Хранимая процедура SQL Server: дождитесь завершения триггера удаления, прежде чем продолжить процедуру - PullRequest
0 голосов
/ 01 июня 2018

Моя хранимая процедура выполняет оператор удаления, который запускает триггер, который не может записать, кто удалил строку, но записывает пробел для changed_by.

Затем хранимая процедура обновляет changed_by с помощьюимя пользователя, которое ему было дано.

Половина времени, часть 2 нижеприведенной хранимой процедуры находит результаты триггера, другая половина времени, она не находит результатов триггера, поэтому естьобновлять нечего.

Как я могу "сдать" элемент управления и убедиться, что триггер обновления завершается, прежде чем продолжить хранимую процедуру?

(В комментариях вы видите некоторые вещи, которые я пробовал до сих пор)это не сработало)

DROP PROCEDURE IF EXISTS dbo.deleteAndUpdateChangedByInAuditTrail
GO

CREATE PROCEDURE dbo.deleteAndUpdateChangedByInAuditTrail 
     (@tableName VARCHAR(100), 
      @pkIDColName VARCHAR(100), 
      @pkIDValue NUMERIC,
      @delUser VARCHAR(100) )
AS
     BEGIN TRANSACTION;
        -- PART 1: DO THE DELETE:
        DECLARE @JUST_BEFORE_DELETION_TIMESTAMP AS DATETIME2;

        SET @JUST_BEFORE_DELETION_TIMESTAMP = CONVERT(varchar, SYSDATETIME(), 121);

        DECLARE @DELETION_TEMPLATE AS VARCHAR(MAX);
        SET @DELETION_TEMPLATE = 'delete from {THE_TABLE_NAME} WHERE {PK_ID_COL_NAME} = {PK_ID_VALUE}';
        SET @DELETION_TEMPLATE = REPLACE(@DELETION_TEMPLATE, '{THE_TABLE_NAME}', @tableName);
        SET @DELETION_TEMPLATE = REPLACE(@DELETION_TEMPLATE, '{PK_ID_COL_NAME}', @pkIDColName);
        SET @DELETION_TEMPLATE = REPLACE(@DELETION_TEMPLATE, '{PK_ID_VALUE}', @pkIDValue);

        --PRINT @DELETION_TEMPLATE
        EXEC (@DELETION_TEMPLATE);

    COMMIT TRANSACTION;

    BEGIN TRANSACTION;
        -- PART 2: UPDATE THE AUDIT_TRAIL:

        DECLARE @TOTAL_NUM_ROWS_UPDATED_WITH_USERNAME AS NUMERIC;
        SET @TOTAL_NUM_ROWS_UPDATED_WITH_USERNAME = 0;

        --DECLARE @TOTAL_TRIES_SO_FAR AS NUMERIC;
        --SET @TOTAL_TRIES_SO_FAR = 0;

        --WHILE @TOTAL_NUM_ROWS_UPDATED_WITH_USERNAME < 1 AND @TOTAL_TRIES_SO_FAR < 5
        --BEGIN  

            --SET @TOTAL_TRIES_SO_FAR = @TOTAL_TRIES_SO_FAR + 1;

            --WAITFOR DELAY '00:00:01.000' -- SEEN IT FAIL FOR 4 SECONDS :(

            DECLARE @UPDATE_AUDIT_TRAIL_TEMPLATE AS VARCHAR(MAX);

            SET @UPDATE_AUDIT_TRAIL_TEMPLATE = 'update AUDIT_TRAIL set changed_by = ''{CHANGED_BY}'' WHERE upper(table_name) = upper(''{THE_TABLE_NAME}'') and table_pk_value = {PK_ID_VALUE} and CONVERT(varchar, changed_at, 121) >= ''{CHANGED_AT}'' ';

            SET @UPDATE_AUDIT_TRAIL_TEMPLATE = REPLACE(@UPDATE_AUDIT_TRAIL_TEMPLATE, '{CHANGED_BY}', @delUser); 
            SET @UPDATE_AUDIT_TRAIL_TEMPLATE = REPLACE(@UPDATE_AUDIT_TRAIL_TEMPLATE, '{THE_TABLE_NAME}', @tableName); 
            SET @UPDATE_AUDIT_TRAIL_TEMPLATE = REPLACE(@UPDATE_AUDIT_TRAIL_TEMPLATE, '{PK_ID_VALUE}', @pkIDValue); 
            SET @UPDATE_AUDIT_TRAIL_TEMPLATE = REPLACE(@UPDATE_AUDIT_TRAIL_TEMPLATE, '{CHANGED_AT}', @JUST_BEFORE_DELETION_TIMESTAMP); 

            --PRINT @UPDATE_AUDIT_TRAIL_TEMPLATE

            EXEC (@UPDATE_AUDIT_TRAIL_TEMPLATE);

            SELECT @TOTAL_NUM_ROWS_UPDATED_WITH_USERNAME = @@ROWCOUNT;

        --END

    COMMIT TRANSACTION;

    RETURN @TOTAL_NUM_ROWS_UPDATED_WITH_USERNAME;
GO

1 Ответ

0 голосов
/ 01 июня 2018

Триггеры не выполняются асинхронно.Следующий шаг после УДАЛЕНИЯ не произойдет до тех пор, пока триггер не будет завершен.

Если вы видите что-то, что заставляет вас думать иначе, есть другая причина для этого.Это не потому, что триггер "не закончил".

...