触发器更新所有行,不只是插入

触发器更新所有行,不只是插入

问题描述:

我知道我在这里错过了一些明显的东西。这个触发器正在更新表中的所有行(当性能被破坏时),当我想要做的是在新插入的行上执行更新。触发器更新所有行,不只是插入

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 
+0

请提供您的表结构为'QD24K_GRSM'和'tbl_locations'包括主键和外键。 – 2012-02-11 20:07:17

+0

[link] http://stackoverflow.com/questions/9046436/can-stwithin-or-stcontains-be-used-to-update-columns-based-on-point-within-polyg [/ link] – tpcolson 2012-02-11 20:11:31

+0

objectid is PK都在。 – tpcolson 2012-02-11 20:15:07

您需要引用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 
+0

不幸的是,这两个表之间绝对没有列通用性,唯一可能的关系是空间的,因此QD24K_GRSM.Shape.STContains(I.SHAPE)= 1语句。所以我不清楚如何加入插入到QD24K? – tpcolson 2012-02-11 20:10:24

+0

并保证有一个确切的'1:1'匹配记录的条件?如果不是,如果0匹配或多于一个匹配会发生什么? – 2012-02-11 20:12:13

+0

是的,考虑到业务需求,在空间表(140)内存在有限数量的多边形,并且位置只能出现在其中一个边界内。用户无法输入不在多边形边界框内的位置。 – tpcolson 2012-02-11 20:13:58

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

像这样的东西(不实际运行代码语法可能是错误的):

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