У меня возникли проблемы, которые выглядят как LOT, как транзакция в хранимой процедуре, откат, хотя я уверен, что он был зафиксирован, поскольку выходная переменная не установлена до тех пор, пока не будет выполнена фиксация, и пользователь получает значение выходной переменной (я знаю, потому что они распечатывают ее, и я также настроил таблицу журналов, в которой я вводил значение выходной переменной). Теоретически кто-то МОЖЕТ вручную удалить и обновить данные таким образом, чтобы они выглядели как откат, но это крайне маловероятно.Сделка отменяется после фиксации?
Итак, я надеюсь, кто-то может обнаружить какую-то структурную ошибку в моей хранимой процедуре. Знакомства ЛПП:
CREATE procedure [dbo].[BOB] (@output_id int OUTPUT, @output_msg varchar(255) OUTPUT)
as
BEGIN
SET NOCOUNT ON
DECLARE @id int
DECLARE @record_id int
SET @output_id = 1
-- some preliminary if-statements that doesn't alter any data, but might do a RETURN
SET XACT_ABORT ON
BEGIN TRANSACTION
BEGIN TRY
--insert into table A
SET @id = SCOPE_IDENTITY()
--update table B
DECLARE csr cursor local FOR
SELECT [some stuff] and record_id
FROM temp_table_that_is_not_actually_a_temporary_table
open csr
fetch next from csr into [some variables], @record_id
while @@fetch_status=0
begin
--check type of item + if valid
IF (something)
BEGIN
SET SOME VARIABLE
END
ELSE
BEGIN
ROLLBACK TRANSACTION
SET @output_msg = 'item does not exist'
SET @output_id = 0
RETURN
END
--update table C
--update table D
--insert into table E
--execute some other stored procedure (without transactions)
if (something)
begin
--insert into table F
--update table C again
end
DELETE FROM temp_table_that_is_not_actually_a_temporary_table WHERE [email protected]_id
fetch next from csr into [some variables], @record_id
end
close csr
deallocate csr
COMMIT TRANSACTION
SET @output_msg = 'ok'
SET @output_id = @id
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
SET @output_msg = 'transaction failed !'
SET @output_id = 0
INSERT INTO errors (record_time, sp_name, sp_msg, error_msg)
VALUES (getdate(), 'BOB', @output_msg, error_message())
END CATCH
RETURN
END
Я знаю, мой пользователь получает @output_id, который в SCOPE_IDENTITY(), и он также получает @output_msg, который говорит «ОК». Есть ли способ получить эти результаты без транзакции?
спасибо.
Я не вижу ничего в процедуре, что вызвало бы поведение вы говорите, что происходит. Однако я бы предположил, что использование такого курсора не является наиболее эффективным способом выполнения этого типа вещей. Было бы лучше с нескольких точек зрения изменить это на подход, основанный на наборах, вместо RBAR. –
Спасибо за ответ. Но я не думаю, что на самом деле существует подход, основанный на наборе, который будет работать в этом случае. Во всяком случае, большую часть времени таблица «temp» содержит менее пяти строк, поэтому это не имеет большого значения. –
Я бы по крайней мере предложил использовать фактическую таблицу темпа вместо постоянной таблицы, действующей как временная таблица. Это проблематично, когда параллелизм вступает в игру. –