触发更新所有行,而不仅仅是插入

时间:2012-02-11 19:49:38

标签: sql-server-2008 spatial

我知道我在这里遗漏了一些明显的东西。这个触发器正在更新表中的所有行(查看性能),当我想要它做的是在新插入的行上执行更新时。

CREATE TRIGGER [dbo].[update_location_topo_name]
--fires at each row insert, queries topo map layer (must be present!) and inserts name of topo into new location record
on [dbo].[TBL_LOCATIONS] 
after insert
AS 
BEGIN 
update TBL_LOCATIONS
set TOPO_NAME = dbo.QD24K_GRSM.NAME
FROM dbo.tbl_locations
inner join dbo.QD24K_GRSM 
on TBL_LOCATIONS.Location_ID = TBL_LOCATIONS.Location_ID
WHERE  (QD24K_GRSM.Shape.STContains(TBL_LOCATIONS.SHAPE) = 1)  
END

2 个答案:

答案 0 :(得分:1)

您需要引用INSERTED伪表以仅获取插入的行。

此外,TBL_LOCATIONS.Location_ID = TBL_LOCATIONS.Location_ID的加入条件毫无意义。

可能更好地将此作为INSTEAD OF触发器在插入之前而不是在插入之后修改行。

CREATE TRIGGER [dbo].[update_location_topo_name] 
ON [dbo].[TBL_LOCATIONS] 
INSTEAD OF INSERT 
AS 
  BEGIN 
      INSERT INTO TBL_LOCATIONS 
                  (foo, 
                   bar, 
                   TOPO_NAME) 
      SELECT foo, 
             bar, 
             dbo.QD24K_GRSM.NAME 
      FROM   INSERTED I 
             LEFT JOIN dbo.QD24K_GRSM 
               ON QD24K_GRSM.Shape.STContains(I.SHAPE) = 1/* Will insert additional 
                                                    rows if more than one match*/
  END 

答案 1 :(得分:0)

我建议创建触发器“而不是插入”而不是“插入后”。 这样,您可以在实际将其插入目标表之前根据需要修改新插入的行。 并且绝对不需要将“插入”表与目标表连接。

这样的事情(语法可能是错误的,因为实际上没有运行该代码):

CREATE TRIGGER [dbo].[update_location_topo_name]
on [dbo].[TBL_LOCATIONS] 
Instead Of insert
AS 
BEGIN 
    Insert Into TBL_LOCATIONS (...., TOPO_NAME)
    Select ..., CrTable.NAME as TOPO_NAME
        From Inserted Cross Apply 
        (
                Select top 1 QD24K_GRSM.NAME from QD24K_GRSM where 
                QD24K_GRSM.Shape.STContains(Inserted.SHAPE) = 1
        ) as CrTable
END