Как получить хранимую процедуру с транзакцией для выполнения, если еще блок кода? - PullRequest
0 голосов
/ 30 сентября 2019

У меня есть хранимая процедура, которая принимает несколько параметров. На основе значений параметров будет выполнен процесс вставки или редактирования. В каждом процессе есть несколько операторов Update / Insert (более одной таблицы обновляется или вставляется). Вот пример, который у меня есть:

CREATE PROCEDURE dbo.stpAddStatus (
    @record_id  NUMERIC(8),
    @new_type_id NUMERIC(2),
    @current_type_id NUMERIC(2),
    @renew SMALLINT,
    @start_date DATETIME,
    @end_date DATETIME
)
AS
BEGIN
    DECLARE @new_end_dt DATETIME
    DECLARE @approve_end_date DATETIME

    IF @current_type_id != 2 AND @current_type_id != 6 
        SET @new_end_dt = @end_date
    ELSE
        SET @new_end_dt = NULL

    SET @approve_end_date = CONVERT(CHAR(10), DATEADD(dd, -1, @start_date), 101)    

    CREATE TABLE #tmpTbl (
        rec_id NUMERIC(8,0) NULL,
        type_id NUMERIC(3,0) NULL,
        active_status NUMERIC(10,0) NULL
    )

    INSERT INTO #tmpTbl (
        rec_id, 
        type_id, 
        status_id
    )
    SELECT 
        a.rec_id, 
        a.type_id, 
        a.active_status 
    FROM profile a 
    WHERE a.related = @record_id  
        AND type_id IN (10,12,13)

    BEGIN TRANSACTION
        IF (@new_type_id = @current_type_id) AND @renew = 0
            SELECT 'New Type ID is the same as Current Type ID and Renew is 0' AS Message
            /* In this block few different tables should be updated. */
        ELSE
            /* In this block record should be inserted in few different tables. */
            SELECT 'New Type ID is not the same as Current Type ID and Renew is 1' AS Message
        IF @@error !=0
        BEGIN 
            SELECT 1 AS Status, 'Error!' AS Message     
            ROLLBACK TRANSACTION
            RETURN 1
        END
    COMMIT TRANSACTION

    DROP TABLE #tmpTbl 
END

Приведенный выше код выполнит код в операторе If и Else. Я не уверен, почему, даже параметры, передаваемые в SP, таковы:

EXECUTE stpAddStatus 45645, 4, 4, 0, '04/23/2018', '06/22/2019'

Я не уверен, что мой оператор блока if / else правильный или есть что-то еще, что я пропустил. Пожалуйста, дайте мне знать, если вы поймете, почему код не работает и выполняет оба оператора независимо от того, какие параметры передаются в SP.

1 Ответ

2 голосов
/ 30 сентября 2019

Если вы планируете выполнить несколько команд для блока if и / или else, вы должны обернуть этот набор команд в пару BEGIN/END, например:

if .... 
begin
    ... 'if' command #1
    ... 'if' command #2
    ...
    ... 'if' command #n
end
else
begin
    ... 'then' command #1
    ... 'then' command #2
    ...
    ... 'then' command #n
end

The BEGIN/END являются необязательными, если в блоке if и / или else имеется только одна команда;если сомневаетесь, включите оболочку BEGIN/END.

Кроме того, переменная @@error устанавливается (пере) после каждой команды;Я предполагаю, что вы хотите откатить транзакцию, если какая-либо из команд выдает ошибку, что означает, что вам нужно добавить еще немного логики для проверки @@error после каждой команды;выполняете ли вы прерывание после первой ошибки или в конце блока if/then ваш вызов.

Еще один элемент, если ваш процесс вызывается в транзакции более высокого уровня (например, вы выполняете врежим цепочки), тогда ваш rollback transaction фактически откатит все транзакции. [Управление вложенными транзакциями - это целая другая тема.]

...