insert-execブロックで呼び出されるストアドプロシージャがあります。
insert into @t
exec('test')
ストアドプロシージャで生成された例外を処理し、処理を続行するにはどうすればよいですか?
次のコードは問題を示しています。私がやりたいことは、内部exec()
呼び出しの成功または失敗に応じて0または-1を返すことです。
alter procedure test -- or create
as
begin try
declare @retval int;
-- This code assumes that PrintMax exists already so this generates an error
exec('create procedure PrintMax as begin print ''hello world'' end;')
set @retval = 0;
select @retval;
return(@retval);
end try
begin catch
-- if @@TRANCOUNT > 0 commit;
print ERROR_MESSAGE();
set @retval = -1;
select @retval;
return(@retval);
end catch;
go
declare @t table (i int);
insert into @t
exec('test');
select *
from @t;
私の問題はreturn(-1)
です。成功の道は素晴らしいです。
ストアドプロシージャのtry / catchブロックを省略すると、エラーが発生し、挿入が失敗します。ただし、私がやりたいことは、エラーを処理して適切な値を返すことです。
コードはそのままメッセージを返します。
Msg 3930, Level 16, State 1, Line 6
The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction.
これはおそらく、私が遭遇した中で最悪のエラーメッセージです。「ネストされたトランザクションでエラーを処理しなかった」という意味です。
に入れるとif @@TRANCOUNT > 0
、次のメッセージが表示されます。
Msg 3916, Level 16, State 0, Procedure gordontest, Line 7
Cannot use the COMMIT statement within an INSERT-EXEC statement unless BEGIN TRANSACTION is used first.
begin / commitトランザクションステートメントをいじってみましたが、何も機能しないようです。
では、トランザクション全体を中止せずにストアドプロシージャでエラーを処理するにはどうすればよいですか?
マーティンに応じて編集します。
実際の呼び出しコードは次のとおりです。
declare @RetvalTable table (retval int);
set @retval = -1;
insert into @RetvalTable
exec('
@retval intを宣言します。exec @retval = '+ @ query +'; select @retval ');
select @retval = retval from @RetvalTable;
@query
ストアドプロシージャコールはどこにありますか。目的は、ストアドプロシージャから戻り値を取得することです。これがinsert
(トランザクションを開始せずに)なくても可能であれば、それは素晴らしいことです。
値が多すぎるため、一般にストアドプロシージャを変更して値をテーブルに格納できません。 そのうちの1つが失敗していて、私はそれを修正できます。私の現在の最善の解決策は次のようなものです:
if (@StoredProcedure = 'sp_rep__post') -- causing me a problem
begin
exec @retval = sp_rep__post;
end;
else
begin
-- the code I'm using now
end;
select @retval; return @retval
、最後の方に似 ています。動的なストアドプロシージャの呼び出しから戻り値を取得する別の方法を知っている場合は、知りたいと思います。
DECLARE @RC INT;EXEC sp_executesql N'EXEC @RC = test', N'@RC INT OUTPUT', @RC = @RC OUTPUT;insert into @t VALUES (@RC)
declare @t table (i int);declare @RC int;exec @RC = test;insert into @t values (@RC);select * from @t;
正常に動作します。