SQL Server 插入后触发器不执行操作

Dat*_*ger 2 trigger sql-server dml sql-server-2012

我有 2 个插入后触发器和 1 个而不是插入触发器的问题。After Insert 触发器应该执行一些操作,但不会触发这些操作。

当替代触发器触发时,它们的动作 After Triggers 工作正常。

让我解释:

“替代”触发器验证该ID值是否为 Null。如果是,则触发器在表 ( TRADE_APPR) 中执行插入操作,填充IDSQL Server 序列中的值。

当替代触发器执行操作时,插入后触发器也执行它们的操作。

我的而不是插入触发器的代码是这样的:

ALTER TRIGGER [ConfirmMgr].[TG_TRADE_APPR_BER_I] 
ON [ConfirmMgr].TRADE_APPR] 
INSTEAD OF INSERT
AS
   DECLARE
      @user_name            varchar(50),
      @appr_username        varchar(50),
      @appr_id          int,
      @v_id             int,
      @appr_timestamp       datetime
BEGIN 
    SELECT @appr_username = APPR_BY_USERNAME FROM inserted

    IF (@appr_username) IS NULL
    BEGIN
            SELECT @user_name = SUSER_NAME()
            UPDATE tbl SET APPR_BY_USERNAME = UPPER(@user_name)
            FROM ConfirmMgr.TRADE_APPR tbl
            INNER JOIN inserted i ON tbl.ID = i.ID
    END

    SELECT @appr_id = i.ID FROM inserted i

    IF (@appr_id) IS NULL
    BEGIN
        INSERT ConfirmMgr.TRADE_APPR
            SELECT 
                NEXT VALUE FOR ConfirmMgr.SEQ_TRADE_APPR,
                i.TRADE_ID,
                i.APPR_FLAG,
                ISNULL(i.APPR_TIMESTAMP_GMT,GETDATE()),
                ISNULL(i.APPR_BY_USERNAME, UPPER(SUSER_NAME()))
            FROM inserted i         
        END
    RETURN          
END
Run Code Online (Sandbox Code Playgroud)

由于您可以检查我的代码,而不是触发器验证 如果 user_name 或 ID 为空,则执行操作。

当您发送空值时,触发器工作正常,并且 After 触发器也能正常工作。

关键是当您发送包含 ID 的正确值时,插入操作不会保存记录,因为这不会插入记录,并且插入后触发器不会执行它们的操作。

我知道你发送了正确的值,像这样的触发器而不是不应该执行或阻止某些事情。

我做了一个测试,禁用了替代插入触发器,记录被保存,插入后触发器工作正常。

我的问题是:当您发送权限值时,为什么“替代插入”触发器会影响插入操作?

下面是我在插入后触发器之一中的代码

谢谢你的建议

ALTER TRIGGER ConfirmMgr.TG_TRADE_APPR_AER_I
ON ConfirmMgr.TRADE_APPR
AFTER INSERT
AS
/******************************************************************************
*
* AUTHOR:       JAVIER MONTERO - 08/19/2015
* DB:           SQL SERVER 2012 OR HIGHER
* VERSION:      1.0
* DESCRIPTION:  TRIGGER FOR UPDATE THE FIELD FINAL_APPROVAL_FLAG, 
                FINAL_APPROVAL_TIMESTAMP_GMT AND TRANSACTION_SEQ
                IN TABLE TRADE_SUMMARY WHEN A INSERT ACTION IS FIRED IN
                TRADE_APPR TABLE 
* DEPENDECIES:  TABLE TRADE_SUMMARY AND SEQUENCE SEQ_TRADE_SUMMARY_TRANSACTION
*
*******************************************************************************/
DECLARE 
@v_id       int

BEGIN
        /*The process collect the trade_id that is coming in the inserted values*/
        SELECT @v_id = ts.TRADE_ID
        FROM ConfirmMgr.TRADE_SUMMARY ts
        JOIN inserted i
        ON ts.TRADE_ID = i.TRADE_ID
        print cast(@v_id as varchar)
        /*The trade_id saved in the local variable @v_id is validated is different to Null*/
        IF (@v_id) IS NOT NULL 
        BEGIN
            /*Finally we update the fields FINAL_APPROVAL_FLAG, FINAL_APPROVAL_TIMESTAMP_GMT and TRANSACTION_SEQ 
            in the table TRADE_SUMMARY also it use a SQL Sequence to set the TRANSACTION SEQUENCE value in the table */
            UPDATE ts
            SET ts.FINAL_APPROVAL_FLAG = i.APPR_FLAG,
            ts.FINAL_APPROVAL_TIMESTAMP_GMT = i.APPR_TIMESTAMP_GMT,
            ts.TRANSACTION_SEQ = NEXT VALUE FOR ConfirmMgr.SEQ_TRADE_SUMMARY_TRANSACTION
            FROM ConfirmMgr.TRADE_SUMMARY ts
            INNER JOIN inserted i
            ON ts.TRADE_ID = i.TRADE_ID
        END
END
Run Code Online (Sandbox Code Playgroud)

Pau*_*ite 6

一个INSTEAD OF INSERT触发器执行的行动,而不是什么原本INSERT会做的。

在您的代码中,如果@appr_username@appr_id为 NULL,则对基表进行某种更改(插入或更新)。

否则,触发器不会执行任何操作(不影响行),因此AFTER会跳过触发器。毕竟,SQL Server 认为,如果INSTEAD OF触发器什么都不做,触发器也不AFTER能做任何事情,对吧?

请注意,如果服务器配置选项nested triggers(如Allow Triggers to Fire OthersSSMS 高级服务器属性选项卡中所示)设置为 1(默认值),您也会得到一些非常令人困惑的行为。

从该链接:

嵌套触发器选项控制 AFTER 触发器是否可以级联。即,执行启动另一个触发器的操作,启动另一个触发器,依此类推。当嵌套触发器设置为 0 时,AFTER 触发器不能级联。当嵌套触发器设置为 1(默认值)时,AFTER 触发器可以级联到多达 32 个级别。无论此选项的设置如何,INSTEAD OF 触发器都可以嵌套。