【问题标题】:SQL Server: how to modify trigger in order to avoid crashing when insert?SQL Server:如何修改触发器以避免插入时崩溃?
【发布时间】:2016-02-15 11:18:24
【问题描述】:

我在 Windows 7 上使用 SQL Server 2012。

我是 SQL 初学者;我目前在表DeviceStatus 上有这个触发器:

ALTER TRIGGER [dbo].[trigger_insertInStatus] 
ON [dbo].[DeviceStatus] 
AFTER INSERT 
AS 
BEGIN
   -- Insert statements for trigger here:
   INSERT INTO GeneralStatus (DeviceIP, ServiceStatus)
   VALUES
   ( (SELECT DeviceIP FROM INSERTED), (SELECT ServiceStatus FROM INSERTED) );

END

其中DeviceIP 是唯一键。

问题是,很明显,当尝试插入具有DeviceIP 值的记录/行时,它会崩溃 - 意外 - 已经存在于名为 GeneralStatus 的第二个表中...

我应该如何修改/调整上述 SQL 查询以保留现有功能(INSERT INTO...),但还可以在此类中添加ServiceStatus更新 DeviceIP 值已存在于GeneralStatus 表中的情况?
编写此代码的最佳方式是什么(高性能且安全)?

【问题讨论】:

    标签: sql sql-server triggers insert sql-update


    【解决方案1】:

    由于 Inserted 有多行,每行都可以是对GeneralStatus 的插入或更新,因此您可以加入插入并根据行是否存在这样的检查。

    ALTER TRIGGER [dbo].[trigger_insertInStatus] 
       ON  [dbo].[DeviceStatus] 
       AFTER INSERT 
    AS 
    BEGIN
    
       --Update Records where DeviceIP does exist in GeneralStatus
       UPDATE GS 
       SET GS.ServiceStatus = I.ServiceStatus
       FROM GeneralStatus GS INNER JOIN Inserted I ON GS.DeviceIP = I.DeviceIP
    
    
       -- Insert statements for trigger here:
       -- Insert records where DeviceIP does not exist in GeneralStatus 
       INSERT INTO GeneralStatus
       ( DeviceIP,ServiceStatus )
       SELECT DeviceIP , ServiceStatus FROM INSERTED I
       LEFT JOIN GeneralStatus GS ON GS.DeviceIP = I.DeviceIP 
       WHERE GS.DeviceIP IS NULL;
    
    END
    

    【讨论】:

    • @IvanStarostin - 是的,您能否解释一下当我们更新另一个表格时它将如何产生影响GeneralStatus 或者您的意思是别的什么
    • “我修改/调整了上面的 SQL 查询,以便在 GeneralStatus 表中已经存在 DeviceIP 值的情况下更新 ServiceStatus 列”检查该行是否已存在于目标表GeneralStatus 并在这种情况下更新状态并且没有另一个插入目标表
    • 对不起,我没有完全解释自己。是的,当[DeviceStatus] 表中有插入时,触发器将检查GeneralStatus 表中是否存在具有相同DeviceIP 的行。如果是这样,它将更新该行而不是在GeneralStatus 中创建一个新行。如果GeneralStatus 表中不存在插入的行,在这种情况下,它将执行插入
    • 对不起,我好像误解了原来的要求!
    • 所以你是说当GeneralStatus 中已经存在该行时,不要在GeneralStatus 中进行任何插入/更新。在这种情况下,只需使用 TheGameiswar 提供的答案
    【解决方案2】:
    INSERT INTO GeneralStatus
       ( DeviceIP, ServiceStatus )
     SELECT DeviceIP ,ServiceStatus FROM INSERTED I
    where not exists(select 1 from generalstatus g where g.deviceip=i.deviceip)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-09
      • 1970-01-01
      • 2021-10-03
      • 1970-01-01
      相关资源
      最近更新 更多