更新触发器使多个记录更新无法进行

时间:2011-11-28 18:27:43

标签: sql sql-server-2005 triggers

我有一个更新触发器,其中一部分位于导致问题的位置。

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触发器中的子句获取多个记录并且无法执行。但是如果我这样做

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

它有效,因为ID是唯一的,只能获取一条记录。

是否有人为此提供补救措施以及更好地重写触发器的方法?

我在触发器中正在做的是,如果记录[Active]中的某个特定字段被更改(例如:记录处于活动状态或非活动状态),我正在记录该日期并将其放入字段[active_changed]之一。这仅用于审计目的。

道歉,我之前解释过有点不对,现在已经修好了。

任何建议

2 个答案:

答案 0 :(得分:2)

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 :(得分:1)

根据要求“我想注册更改日期。帐户可以是'有效'或'不主动'。”我想你想要这个:

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

这假设记录“永远不会”在ID字段上更新。如果您还想了解UPDATE可以执行的情况,您希望这样的操作也设置active_changed字段,您需要以下内容:

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
  LEFT OUTER JOIN deleted d -- match by ID with old version (might not have existed yet
               ON d.ID = upd.ID
 WHERE i.Account <> d.Account -- when changed
    OR d.ID IS NULL -- or when coming from different ID

希望这有帮助。

PS:为什么将active_changed存储为varchar而不是datetime?