Обновление триггера MSSQL для столбца - PullRequest
0 голосов
/ 13 марта 2019

У меня есть 2 таблицы, и я хочу, чтобы в таблице 1 был триггер, который вставлял или обновлял таблицу 2, но я не уверен, как это сделать.

Таблица 1:

CREATE TABLE [dbo].[DevicePorts](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [IsInUse] [bit] NOT NULL,
)

Таблица 2:

CREATE TABLE [dbo].[DevicePortActivities](
    [ID] [uniqueidentifier] NOT NULL,
    [StartTime] [datetimeoffset](7) NOT NULL,
    [EndTime] [datetimeoffset](7) NULL,
    [FK_DevicePortID] [int] NOT NULL FOREIGN KEY REFERENCES DevicePorts(ID),
)

Начало моего триггера:

CREATE TRIGGER PortInUse
   ON  DevicePorts
   AFTER UPDATE
AS BEGIN
    SET NOCOUNT ON;
    IF UPDATE (IsInUse) 
    BEGIN
        IF IsInUse = 1
        THEN
            INSERT INTO [dbo].[DevicePortActivities]
            (
                [ID]
                ,[StartTime]
                ,[EndTime]
                ,[FK_DevicePortID]
            )
            VALUES
            (
                NEWID(),
                SYSDATETIMEOFFSET(),
                null,
                <DevicePortID>
            )
        ELSE 
            UPDATE [dbo].[DevicePortActivities]
            SET EndTime = SYSDATETIMEOFFSET()
            WHERE FK_DevicePortID = <DevicePortID> AND EndTime is null
        END
    END 
END
GO

То, что я пытаюсь сделать, это то, что когда IsInUse модифицируется, он должен вставить строку в DevicePortActivities или обновить.

Условия таковы: если IsInUse имеет значение true, тогда он должен вставить запись, если он ложный, он должен обновить последнюю запись, где EndTime равен нулю.

Ответы [ 2 ]

0 голосов
/ 13 марта 2019

Вам нужно обработать inserted как таблицу .Я бы посоветовал посмотреть на MERGE (потому что разные строки могли иметь разные изменения, примененные одним UPDATE).

Что-то вроде:

CREATE TRIGGER PortInUse
   ON  DevicePorts
   AFTER UPDATE
AS
BEGIN
    SET NOCOUNT ON;
    MERGE INTO [dbo].[DevicePortActivities] t
    USING (select i.ID,i.IsInUse as NewUse,d.IsInUse as OldUse
        from inserted i inner join deleted d on i.ID = d.ID) s
    ON
        t.FK_DevicePortID = s.ID
    WHEN MATCHED AND t.EndTime is null AND NewUse = 0 and OldUse = 1
    THEN UPDATE SET EndTime = SYSDATETIMEOFFSET()
    WHEN NOT MATCHED AND NewUse = 1 and OldUse = 0
    THEN INSERT ([ID]
                ,[StartTime]
                ,[EndTime]
                ,[FK_DevicePortID])
         VALUES (NEWID(),
                SYSDATETIMEOFFSET(),
                null,
                s.ID);
END
0 голосов
/ 13 марта 2019

Я нашел решение для моего вопроса

CREATE TRIGGER [dbo].[PortInUse]
   ON  [dbo].[DevicePorts]
   AFTER UPDATE
AS BEGIN
    SET NOCOUNT ON;
    IF UPDATE (IsInUse) 
    BEGIN
        DECLARE @IsInUse bit;
        DECLARE @PortID int;
        SELECT @IsInUse = i.IsInUse FROM inserted i; 
        SELECT @PortID = i.ID FROM inserted i; 
        IF (@IsInUse = 1)
            INSERT INTO [dbo].[DevicePortActivities]
            (
                [ID]
                ,[StartTime]
                ,[EndTime]
                ,[FK_DevicePortID]
            )
            VALUES
            (
                NEWID(),
                SYSDATETIMEOFFSET(),
                null,
                @PortID
            );
        ELSE 
            UPDATE [dbo].[DevicePortActivities]
            SET EndTime = SYSDATETIMEOFFSET()
            WHERE FK_DevicePortID = @PortID AND EndTime is null;
    END 
END

Я не уверен, что есть лучший способ сделать это, но он работает.

...