栏上的MSSQL触发器更新

时间:2019-03-13 09:30:54

标签: sql-server triggers sql-update

我有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,则应插入一条记录;如果为false,则应更新'EndTime'为null的最后一条记录。

2 个答案:

答案 0 :(得分:0)

我找到了解决问题的方法

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

我不确定是否有更好的方法可以做到这一点,但是它可以正常工作。

答案 1 :(得分:0)

您需要将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