2017-02-19 58 views
0

我正在实现而不是更新SQL-server中的触发器,想要更新所有字段而不需要缓存INSERTED表中的值,然后设置它到UPDATE查询中的字段..我该如何做到这一点?!如何动态更新所有字段而不是更新触发器SQL Server

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

你到底在做什么? “INSTEAD OF UPDATE”触发器通常只用于完全绕过正常更新逻辑并完全自定义的情况。看起来你实际上需要正常的更新逻辑。 – mroach

+0

旁注:严重程度为16的'raiserror'不会阻止更新。如果您希望更新实际取消,则需要添加'回滚事务'。 – mroach

+0

@ mroach我想拒绝ID的更新并接受任何其他更新..我知道这些代码没有显示,我只是试图访问正常的更新值,然后将我的代码写入。 对不起,如果它以某种方式模糊 –

回答

1

您不需要使用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退出触发代码。可能不需要继续进一步处理。

如果你想更新基表,这里是你如何做到这一点:

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列,那么无法更新它,这样就不需要这样的触发器。

+2

'UPDATE()'不检查值是否已经改变。更好地比较插入表和删除表之间的值。 –