Обновление триггера делает невозможным обновление нескольких записей - PullRequest
1 голос
/ 28 ноября 2011

У меня есть триггер обновления, часть которого ниже, вызывает проблему.

if ( (select [Account] from inserted) != (select [Account] from deleted))
    begin
    UPDATE Customers SET active_changed = CONVERT(varchar(10),GetDate(),102)
    FROM Customers ,INSERTED
    WHERE Customers .ID = INSERTED.ID
    end

Если я сделаю такой запрос

UPDATE Customers SET RepID= '111'  where repID = '222'

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

UPDATE Customers SET RepID = '111' where ID = '12345'    

Это работает, потому что ID уникален и выбирает только одну запись.

Есть ли у кого-нибудь средство от этого и лучший способ переписать мой триггер?

Что я делаю в триггере, так это то, что если конкретное поле в записи [Active] изменяется (пример: запись сделана активной или неактивной), я записываю эту дату и помещаю ее в одно из полей [active_changed] , Это только для целей аудита.

Извинения, раньше я объяснил немного неправильно, теперь исправлено.

Любой совет

Ответы [ 2 ]

2 голосов
/ 29 ноября 2011
UPDATE A 
    SET A.active_changed = CONVERT(varchar(10),GetDate(),102)
FROM
    Customers A 
    INNER JOIN INSERTED B ON A.ID=B.ID
    INNER JOIN DELETED C ON A.ID=C.ID
WHERE
    B.Account <> C.Account
    -- below to cover nulls as above will evaluate to false if any of two fields is null
    OR
    B.Account IS NULL AND C.Account IS NOT NULL
    OR
    B.Account IS NOT NULL AND C.Account IS NULL

Это работает без необходимости использования условия IF, но для того, чтобы вообще не задействовать таблицу Customers, когда ни на какие записи не повлияет, используйте условие ниже:

IF EXISTS(SELECT NULL 
    FROM INSERTED B INNER JOIN DELETED C ON B.ID=C.ID 
    WHERE B.Account <> C.Account 
        OR B.Account IS NULL AND C.Account IS NOT NULL 
        OR B.Account IS NOT NULL AND C.Account IS NULL)
BEGIN
    -- insert first sql
END
1 голос
/ 11 декабря 2011

На основании требования «Я хотел бы зарегистрировать дату, в которую оно было изменено. Аккаунт может быть« активным »или« неактивным ».»Я думаю, что вы хотите это:

UPDATE Customers 
   SET active_changed = CONVERT(varchar(10),GetDate(),102)
  FROM Customers upd
  JOIN inserted i -- match by ID with new version
    ON i.ID = upd.ID
  JOIN deleted d -- match by ID with old version 
    ON d.ID = upd.ID
 WHERE i.Account <> d.Account -- when changed

Это предполагает, что записи никогда не обновляются в поле идентификатора.Если вы также хотите поймать ситуацию, когда UPDATE может сделать это и , вы хотите, чтобы такая операция также устанавливала поле active_changed, вам потребуется нечто вроде следующего:Надеюсь, это поможет.

PS: Зачем хранить active_changed как varchar вместо datetime?

...