2012-02-11 1 views
1

Я знаю, что здесь отсутствует что-то очевидное. Этот триггер обновляет все строки в таблице (убивая производительность), когда все, что я хочу, это выполнить обновление в новой вставленной строке.триггер, обновляющий все строки, а не только вставленный

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', включая первичные и внешние ключи. –

+0

[ссылка] http://stackoverflow.com/questions/9046436/can-stwithin-or-stcontains-be-used-to-update-columns-based-on-point-within-polyg [/ link] – tpcolson

+0

objectid is ПК в обоих. – tpcolson

ответ

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

К сожалению, между этими двумя таблицами нет никакой общности столбцов, единственная возможная связь - пространственная, поэтому оператор QD24K_GRSM.Shape.STContains (I.SHAPE) = 1. Итак, я не понимаю, как присоединиться к вставленному в QD24K? – tpcolson

+0

И гарантируется ли точная запись соответствия «1: 1» для этого условия? Если нет, что должно произойти, если 0 совпадений или более одного совпадения? –

+0

да, учитывая бизнес-требования, в пространственной таблице (140) имеется конечное число полигонов, и местоположение может происходить только внутри границы одного из них. Пользователи не могут вводить местоположения, которые не попадают в ограничительную рамку полигонов. – tpcolson

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