ここで問題が発生していますが、なぜこのように動作するのかわかりません。
TSQL (SQL Server 2008R2) に次の 2 つの (簡略化された) ストアド プロシージャがあるとします。
create procedure [datetransaction1]
as
begin
begin try
begin transaction
declare @a datetime
exec datetransaction2 '2013-02-02 22:21', @a output
select @a
exec datetransaction2 '2013-020222:22', @a output
select @a
exec datetransaction2 '2013-02-02 22:23', @a output
select @a
commit transaction
end try
begin catch
print 'Catch'
end catch
end
と
create procedure [dbo].[datetransaction2] @text nvarchar(100), @res datetime OUTPUT
AS
BEGIN
BEGIN TRY
if (LEN(@text) = 16) SET @text = replace(@text, ' ', 'T') + ':00.000'
else if (LEN(@text) = 19) SET @text = replace(@text, ' ', 'T') + '.000'
else SET @text = replace(@text, ' ', 'T')
PRINT 'trydate:' + @text
SELECT @res =convert(datetime, @text, 126)
END TRY
BEGIN CATCH
PRINT ERROR_SEVERITY()
PRINT 'errordate:' + @text
END CATCH
END
次に を実行するexec datetransaction1
と、 への 3 つの呼び出しがすべてdatetransaction2
実行され、最初と最後の (予想どおり) が正しく実行され、2 番目の呼び出しがCATCH
内のブロックに入ることがわかりますdatetransaction2
。
ここまでは順調ですね。
datetransaction1
しかし、その後、トランザクションがコミットできないというメッセージとともにの catch ブロックに到達します。
Msg 266, Level 16, State 2, Procedure datetransaction1, Line 0
Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1.
Msg 3998, Level 16, State 1, Line 1
Uncommittable transaction is detected at the end of the batch. The transaction is rolled back.
これは起こるはずがありません(私は思う)。サブ プロシージャでエラーを検出したのに、トランザクションが突然コミット不能になるのはなぜでしょうか?
誰かが私にそれを説明できますか?
おそらくこれを回避する方法を見つけることができることに注意してください。しかし、私はその背後にあるアイデアにもっと興味をそそられます。ここで、このトランザクションが突然コミット不能になるのはなぜですか?