如何动态更新所有字段而不是UPDATE触发SQL Server

时间:2017-02-19 08:18:06

标签: sql sql-server tsql

我正在SQL服务器中实现而不是UPDATE触发器,想要更新所有字段而不需要缓存INSERTED表中的值,然后将其设置为UPDATE Query中的字段。我该怎么办?这个?!

CREATE TRIGGER trg_Instead_updTable1 ON dbo.Table1
INSTEAD OF UPDATE
AS
BEGIN
    IF (UPDATE(ID))
           RAISERROR ('It is not allowed to update a Table1.ID', 16, 1)
    ELSE
           BEGIN
                UPDATE dbo.Table1
                SET * = (SELECT * FROM INSERTED JOIN DELETED ON INSERTED.ID = DELETED.ID)
           END
END

1 个答案:

答案 0 :(得分:3)

您不需要使用INSTEAD OF UPDATE触发器。只有当您想要完全绕过所有正常的表更新逻辑并执行完全自定义的操作时,才需要这些。通常,这是在复杂视图上设置触发器时完成的。

你说你想拒绝更新一个值。没问题。你可以这样做:

CREATE TRIGGER dbo.Table1_UPDATE on Table1 FOR UPDATE AS
  IF UPDATE(ID)
  BEGIN
    RAISERROR('You may not update the ID', 16, -1)
    ROLLBACK TRANSACTION
    RETURN
  END
GO
  1. RAISERROR当然会引发错误,提醒用户他们已经做了坏事。有人可能会认为这会暂停执行并回滚更新,但它不会(除非XACT_ABORTON)。

  2. ROLLBACK TRANSACTION将撤消整个更新,将表格恢复到尝试UPDATE之前的状态。

  3. RETURN退出触发器代码。可能无需继续进一步处理。

  4. 如果您确实想要更新基表,请按照以下方式进行操作:

    UPDATE t1 SET
           field1 = i.field1,
           field2 = i.field2,
           -- all additional fields go here
    FROM   Table1 t1
           INNER JOIN inserted i ON i.id = t1.id
    

    inserted是一个虚拟表,包含整个行以及新值。 deleted具有插入之前的行。因此可以使用它们来查看哪些值发生了变化。

    旁注:如果字段是IDENTITY列,则无论如何都无法对其进行更新,从而无需进行此类触发。