如何使用sql server进行BEFORE UPDATED触发器?

时间:2009-03-13 13:54:05

标签: sql sql-server database triggers sql-server-express

我正在使用Sqlserver express而我无法执行before updated触发器。还有另外一种方法吗?

9 个答案:

答案 0 :(得分:35)

MSSQL不支持BEFORE个触发器。您最接近的是INSTEAD OF触发器,但它们的行为与MySQL中的BEFORE触发器的行为不同。

您可以了解有关它们的更多信息here,并注意INSTEAD OF触发器“指定执行触发器而不是触发SQL语句,从而覆盖触发语句的操作。”因此,如果没有正确地写入/处理触发器,则可能不会发生对更新的动作。级联行动也会受到影响。

您可能希望使用不同的方法来实现您想要实现的目标。

答案 1 :(得分:32)

MSSQL中确实没有“before triggers”。但是,您仍然可以通过一起使用“inserted”和“deleted”表来跟踪对表进行的更改。当更新导致触发器触发时,“inserted”表存储新值,“deleted”表存储旧值。获得此信息后,您可以相对轻松地模拟“触发前”行为。

答案 2 :(得分:8)

T-SQL仅支持AFTER和INSTEAD OF触发器,它没有BEFORE触发器,如其他一些RDBMS中所示。

我相信你会想要使用INSTEAD OF触发器。

答案 3 :(得分:8)

无法确定这是否适用于SQL Server Express ,但即使您的触发器在更新后发生,您仍然可以访问“之前”数据。您需要从更改表格时动态创建的已删除已插入表中读取数据。这基本上就是@Stamen所说的,但我还需要进一步探索,以了解(有用!)答案。

  

已删除表在DELETE和期间存储受影响行的副本   UPDATE语句。在执行DELETE或UPDATE期间   语句,行从触发器表中删除并传输到   删除的表......

     

插入表在INSERT期间存储受影响行的副本   和UPDATE语句。在插入或更新事务期间,新的   行被添加到插入的表和触发器表...

     

https://msdn.microsoft.com/en-us/library/ms191300.aspx

因此,您可以创建触发器以从其中一个表中读取数据,例如

CREATE TRIGGER <TriggerName> ON <TableName>
AFTER UPDATE
AS
  BEGIN
    INSERT INTO <HistoryTable> ( <columns...>, DateChanged )
    SELECT <columns...>, getdate()
    FROM deleted;
  END;

我的例子基于这里的一个:

http://www.seemoredata.com/en/showthread.php?134-Example-of-BEFORE-UPDATE-trigger-in-Sql-Server-good-for-Type-2-dimension-table-updates

答案 4 :(得分:3)

SQL Server中的所有“正常”触发器都是“AFTER ...”触发器。没有“BEFORE ......”触发器。

要在更新前执行某些操作,请查看INSTEAD OF UPDATE Triggers

答案 5 :(得分:2)

请记住,当您使用替代触发器时,除非您在触发器中明确告知它,否则它不会提交插入。而不是真正意味着这样做而不是你通常做的事情,所以没有任何正常的插入动作会发生。

答案 6 :(得分:2)

要在SQL Server中执行BEFORE UPDATE我使用技巧。我对记录(UPDATE Table SET Field = Field)进行了错误的更新,这样我得到了记录的上一张图像。

答案 7 :(得分:0)

完整示例:

CREATE TRIGGER [dbo].[trig_020_Original_010_010_Gamechanger]
   ON  [dbo].[T_Original]
   AFTER UPDATE
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;
    DECLARE @Old_Gamechanger int;
    DECLARE @New_Gamechanger int;

    -- Insert statements for trigger here
    SELECT @Old_Gamechanger = Gamechanger from DELETED;
    SELECT @New_Gamechanger = Gamechanger from INSERTED;

    IF @Old_Gamechanger != @New_Gamechanger

        BEGIN

            INSERT INTO [dbo].T_History(ChangeDate, Reason, Callcenter_ID, Old_Gamechanger, New_Gamechanger)
            SELECT GETDATE(), 'Time for a change', Callcenter_ID, @Old_Gamechanger, @New_Gamechanger
                FROM deleted
            ;

        END

END

答案 8 :(得分:0)

更新或删除的值存储在 DELETED 中。我们可以通过触发器中的以下方法获取它

完整示例,

CREATE TRIGGER PRODUCT_UPDATE ON PRODUCTS
FOR UPDATE 
AS
BEGIN
DECLARE @PRODUCT_NAME_OLD VARCHAR(100)
DECLARE @PRODUCT_NAME_NEW VARCHAR(100)

SELECT @PRODUCT_NAME_OLD = product_name from DELETED
SELECT @PRODUCT_NAME_NEW = product_name from INSERTED

END