gpt4 book ai didi

SQL SERVER 2008R2 带有 RAISERROR 的嵌套事务

转载 作者:行者123 更新时间:2023-12-03 00:23:34 24 4
gpt4 key购买 nike

我们正在经历从 DB2 切换到 SQL Server 2008R2 的过程,我对 TSQL 有点不熟悉。任何有助于更好地了解正在发生的事情的帮助都会很好。我们创建了一个名为 RethrowError 的过程,如下所示:

CREATE PROCEDURE RethrowError 
AS
BEGIN
-- Return if there is no error information to retrieve.
IF ERROR_NUMBER() IS NULL
RETURN;
PRINT 'yo error';

DECLARE
@ErrorMessage NVARCHAR(4000),
@ErrorNumber INT,
@ErrorSeverity INT,
@ErrorState INT,
@ErrorLine INT,
@ErrorProcedure NVARCHAR(200);

-- Assign variables to error-handling functions that
-- capture information for RAISERROR.
SELECT
@ErrorNumber = ERROR_NUMBER(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE(),
@ErrorLine = ERROR_LINE(),
@ErrorProcedure = ISNULL(ERROR_PROCEDURE(), '-');

-- Build the message string that will contain original
-- error information.
SELECT @ErrorMessage = N'Error %d, Level %d, State %d, Procedure %s, Line %d, ' +
'Message: '+ ERROR_MESSAGE();
PRINT 'yo doin something';

-- Raise an error: msg_str parameter of RAISERROR will contain
-- the original error information.
RAISERROR
(
@ErrorMessage,
@ErrorSeverity,
1,
@ErrorNumber, -- parameter: original error number.
@ErrorSeverity, -- parameter: original error severity.
@ErrorState, -- parameter: original error state.
@ErrorProcedure, -- parameter: original error procedure name.
@ErrorLine -- parameter: original error line number.
);
PRINT 'yo end';

RETURN;
END
GO

我们创建该过程的原因纯粹是为了将来扩展错误,而不必触及所有过程。 我添加了一些 PRINT 行用于调试目的

我的主要问题是我们有过程 A,失败时它会执行 RethrowError,我会看到消息

yo error
yo doin something
yo end

正如预期的那样。

CREATE PROCEDURE dbo.A
AS
BEGIN
SET NOCOUNT ON;

DECLARE & SET VARIABLES;
BEGIN TRY
BEGIN TRANSACTION MaintainTarget

DO SOME STUFF
END TRY
BEGIN CATCH
EXEC RethrowError;

IF (XACT_STATE()) = -1
BEGIN
PRINT
N'The transaction is in an uncommittable state. ' +
'Rolling back transaction.'
ROLLBACK TRANSACTION;
END;


IF (XACT_STATE()) = 1
BEGIN

PRINT
N'The transaction is committable. ' +
'Rolling back transaction.'
ROLLBACK TRANSACTION;
END;

RETURN -101;
END CATCH;
RETURN;
END

GO

但是,我们创建了一个执行许多过程的过程,当嵌套过程(即过程 A 被过程 B 调用)失败时,我看到的唯一消息是

yo error
yo doin something

我不太明白为什么最后一条消息不再显示。

程序B与程序A类似,但catch略有不同。

CREATE PROCEDURE dbo.B
AS
BEGIN
SET NOCOUNT ON;

DECLARE & SET VARIABLES;
BEGIN TRY
DO SOME STUFF
END TRY
BEGIN CATCH
COMMIT;

RETURN -101;
END CATCH;
RETURN;
END

任何有助于更好地了解正在发生的事情的帮助将不胜感激。

最佳答案

我允许自己编辑你的代码来模仿行为,但要保持简单(实际上是你的工作;)。

您的 procA 工作正常,因为 RethrowError 过程正在 procA 的 CATCH block 内调用,并且所有内容都会执行。但在第二种情况下,这一切仍然发生在 procB 的 TRY block 内!因此,在调用 RethrowError 中的 RAISERROR 后,procB 的 CATCH 部分会立即触发。

这个简单的示例演示了 TRY-CATCH 的这种行为:

begin try
select 1/0
print 'doesnt show - div error'
end try
begin catch
print 'oops'
select 1/0
print 'this one shows because its in CATCH!'
end catch

这是您的简化代码:

-- "proc B" start
begin try
-- "proc A" start (works fine alone)
begin try
begin tran
select 1/0 --error
end try
begin catch
print 'yo error';
RAISERROR ('RE from RethrowError', 16, 1) --comment this out and see what happens
print 'yo end';

IF (XACT_STATE())=-1 or (XACT_STATE())=1
BEGIN
PRINT N'Rolling back transaction.'
ROLLBACK TRANSACTION;
end
end catch -- "proc A" ends
end try
begin catch
select error_message(), error_severity(), error_state() --
print 'outer catch';
commit;
end catch;

希望这有帮助。

关于SQL SERVER 2008R2 带有 RAISERROR 的嵌套事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16672810/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com