Сообщение 3902, уровень 16, состояние 1. Запрос ТРАНЗАКЦИИ ФИКСАЦИИ не имеет соответствующей ТРАНЗАКЦИИ BEGIN

#sql #sql-server #sql-server-2005 #sql-server-2008

#sql #sql-сервер #sql-server-2005 #sql-сервер-2008

Вопрос:

 DECLARE @cnt_inv int,
        @cnt_jrn int, 
        @pl_per varchar(2), 
        @pl_yr  varchar(4), 
        @pl_jrn varchar (6), 
        @pl_inv varchar (6)

IF @@ERROR <> 0
BEGIN
BEGIN TRANSACTION JD_Imp


            IF @cnt_inv > 0 
            BEGIN
            BEGIN TRANSACTION JD_Inv



        COMMIT TRANSACTION JD_Inv; 
                    PRINT N'The Invoice Commits DONE.';
        END

            IF @cnt_jrn > 0 
            BEGIN
            BEGIN TRANSACTION JD_Jrn


        COMMIT TRANSACTION JD_Jrn;  
                    PRINT N'The Journals Commits DONE.';
        END
COMMIT TRANSACTION JD_Imp;
END
 

Ответ №1:

Суть вашей проблемы заключается в следующем:

 IF @cnt_jrn > 0 
        BEGIN TRANSACTION JD_Jrn
 

Все, что это сделает, это только запуск новой транзакции, если @cnt_jrn > 0 . Он по-прежнему будет выполнять весь приведенный ниже код независимо от условия. Итак, если @cnt_jrn <= 0 он будет вызываться commit transaction JD_Jrn , даже не запустив его.

Вам нужно заключить тело любого if тела с несколькими операторами begin с помощью и end . Например:

 IF @cnt_jrn > 0 
BEGIN
        BEGIN TRANSACTION JD_Jrn

        ... code ...
END
 

Но вы включаете отдельные insert update операторы и в транзакции, в чем нет необходимости. Операции SQL гарантированно будут атомарными, поэтому транзакция вам нужна только в том случае, если вы охватываете несколько операций.

Комментарии:

1. 1. Я заключил тело тела if в НАЧАЛО и КОНЕЦ. Когда я это делаю, процедура запускается и команды с сообщениями об ошибках успешно завершены. 2. Когда я смотрю на свои таблицы, новых записей нет. Это означает, что я только удалил сообщение об ошибке, но не решил основную проблему. Нет вставок.

2. «Команда (команды) успешно завершены» не является сообщением об ошибке. Если вы не видите вставок, то либо а) у вас есть незафиксированные транзакции в конце пакета, б) ваша логика (либо внутренняя, либо выраженная в коде) неверна, либо в) ваши значения не соответствуют ожидаемым. Невозможно определить, что является вероятной причиной, не увидев ваш (теперь обновленный) код и распечатку значений переменных.

3. Я внес изменения в соответствии с рекомендациями Адама. Я не могу перепечатать измененный сценарий. не хватает места

4. @hcaneshcanes: Отредактируйте свой вопрос, чтобы включить новый код; вы не сможете опубликовать его в комментарии.

5. Спасибо, Адам. Я ввел новый код, используя опцию редактирования. При выполнении процедуры вставки не происходят. Когда я пытаюсь запустить отладку, отладка не перемещается с первой. Когда я перетаскиваю стрелку отладки, чтобы выполнить код, я получаю сообщение «Невозможно использовать следующий оператор для этого местоположения. В этом месте в исходном коде нет исполняемого кода.

Ответ №2:

Проблема решена…..

(a) Наличие Begin …Конечные блоки исправили сообщение об ошибке Msg 3902.. Я заметил, что без блоков BEGIN..END предыдущие запуски процедуры по-прежнему будут зависать незафиксированными

(b) ЕСЛИ @@ERROR <> 0, BEGIN всегда будет иметь значение true, поэтому неудивительно, что блок сценария внутри не выполнялся.

(c) отладчик не прошел мимо оператора IF из-за (b).

Большое спасибо, Адам.

Комментарии:

1. Если мой ответ привел вас к решению, пожалуйста, обязательно примите его, нажав на галочку. Возможно, вы также захотите вернуться к своему вопросу, чтобы исходный код был доступен другим пользователям в будущем.