50

我正在使用 Sqlserver express,但无法before updated触发。还有其他方法可以做到吗?

4

9 回答 9

45

确实,MSSQL 中没有“前触发器”。但是,您仍然可以通过同时使用“插入”和“删除”表来跟踪对表所做的更改。当更新导致触发器触发时,“插入”表存储新值,“删除”表存储旧值。一旦有了这些信息,您就可以相对容易地模拟“触发前”行为。

于 2011-01-07T15:25:54.953 回答
44

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

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

相反,您可能想要使用不同的方法来实现您想要实现的目标。

于 2009-03-13T14:02:48.160 回答
14

无法确定这是否适用于 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

于 2016-01-19T11:57:54.797 回答
9

T-SQL 仅支持 AFTER 和 INSTEAD OF 触发器,它不具有 BEFORE 触发器,这在其他一些 RDBMS 中可以找到。

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

于 2009-03-13T13:57:35.533 回答
4

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

要在更新之前做一些事情,请查看INSTEAD OF UPDATE 触发器

于 2009-03-13T13:58:45.440 回答
2

为了BEFORE UPDATE在 SQL Server 中做一个,我使用了一个技巧。我对记录 ( UPDATE Table SET Field = Field) 进行了错误更新,这样我就得到了记录的先前图像。

于 2012-05-03T14:16:44.663 回答
1

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

于 2009-03-13T14:37:47.920 回答
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
于 2019-03-26T17:17:51.567 回答
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
于 2020-07-13T11:04:52.840 回答