запускать обновление всей таблицы даже при обновлении в одну строку - PullRequest
1 голос
/ 04 марта 2012

Следующие триггеры предназначены для автоматизации обновлений при обновлении строки в таблице расположений. Изменения могут происходить по одной строке за раз или от 1 до n строк одновременно. Однако при обновлении одной строки, когда «location_geteditdate» включен, новая отметка времени записывается во все 28K строк в таблице расположений. Я знаю, что упускаю что-то очевидное здесь, спасибо за помощь.

ALTER TRIGGER   [dbo].[locations_geteditdate]
ON  [dbo].[TBL_LOCATIONS]   
instead of update
AS
begin
declare @recs INT
select @recs = COUNT(*)
from dbo.TBL_LOCATIONS a
join inserted i on i.Location_ID = a.Location_ID
if @recs > 0
update dbo.TBL_LOCATIONS
SET EditDate = GETDATE()
end
GO

alter TRIGGER   [dbo].[locations_move_topo]
ON  [dbo].[TBL_LOCATIONS]
for update   
AS   
BEGIN   
  update dbo.TBL_LOCATIONS
  set topo_name = dbo.TLU_TOPO_BOUNDS.name
  FROM  dbo.TBL_LOCATIONS
      inner join dbo.TLU_TOPO_BOUNDS
      on dbo.TBL_LOCATIONS.Location_ID = dbo.TBL_LOCATIONS.Location_ID
      where (TLU_TOPO_BOUNDS.Shape.STContains(TBL_LOCATIONS.SHAPE) = 1) ; 
END

Принятый ответ:

alter TRIGGER   [dbo].[locations_geteditdate]
ON  [dbo].[TBL_LOCATIONS]   
for update 
as
begin
update dbo.TBL_LOCATIONS
SET EditDate = GETDATE()
from dbo.TBL_LOCATIONS locn
inner join inserted i on i.location_id = locn.Location_ID
end
GO

1 Ответ

2 голосов
/ 04 марта 2012

В вашем условии if (в locations_geteditdate) у вас нет условия where;поэтому он включает в себя все записи:

if @recs > 0
update dbo.TBL_LOCATIONS
SET EditDate = GETDATE()
WHERE ???
end

Вы правильно использовали таблицу inserted, чтобы увидеть, что было обновлено, но только для определения количества записей

Итак, читая код, который вывставьте триггер, похоже, что вы пытаетесь просто применить временную метку к таблице, чтобы показать, что когда она была обновлена.

У вас есть по крайней мере следующие параметры для этого:
1. Если вам на самом деле не требуется распознаваемая дата и время, вы можете использовать поле метки времени вместо даты и автоматически обновлять его.
2. Если вы можете контролировать, где выполняются обновления таблицы, вы можете просто установитьEditDate там (то есть в хранимых процедурах)

Однако, предполагая, что вы хотите узнаваемую дату и время и , вы не можете контролировать, где происходят обновления таблицы, поэтому выРеализация триггера вместо того, чтобы просто иметь набор процедур EditDate, вам нужно идти вперед с одним из двух типов триггера:

A) Так что если вы продолжите с«вместо» триггера вы должны понимать, что заменяет обновление, которое произошло бы.Поэтому на вас лежит обязанность выполнять ту работу, которую он собирался выполнить.Вы проверяете столбец за столбцом, что изменилось:
например

IF UPDATE (price)
BEGIN 
     UPDATE t
     SET price = i.price
     FROM TBL_LOCATIONS t join inserted i
          ON i.locn_id = t.locn_id
END

... повторите для каждого столбца (вы можете объединить обновления, если это имеет смысл)

B) В качестве альтернативы выможет измениться на триггер «после», разрешить обновление (чтобы вам не приходилось кодировать столбец за столбцом, чтобы проверить, что было обновлено), НО ВЫ ДОЛЖНЫ затем проверить столбец EditDate и НЕ выполнять обновлениеесли это столбец EditDate, который изменился.Если вы этого не сделаете, вы будете в бесконечном цикле - ваш прок вызывает триггер, который вызывает триггер и т. Д.

, то есть что-то вроде:

IF NOT UPDATE(EditDate)
BEGIN
   UPDATE dbo.TBL_LOCATIONS
   SET EditDate = GETDATE()
   FROM dbo.TBL_LOCATIONS locn
     INNER JOIN inserted i on i.locn_id = locn.locn_id
END
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...