SQL Server:如何修改触发器以避免插入时崩溃?

时间:2016-02-15 11:18:24

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

我在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值? 什么是最好的写作方式(高效,安全)?

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分:2)

由于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
相关问题