4

我想设置SET XACT_ABORT ON与交易一个SQL Server 2008 R2的存储过程,因此,无论是在创作剧本:如何在SQL Server事务中设置“SET XACT_ABORT ON”?

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
SET XACT_ABORT ON 
GO 

CREATE PROCEDURE MyProc 
AS 
BEGIN TRAN 
    ... 
IF @@ERROR <> 0 
BEGIN 
    GOTO Done 
END 
    ... 
IF @@ERROR <> 0 
BEGIN 
    GOTO Done 
END 
COMMIT TRAN  
Done: 
IF @@ERROR <> 0 
BEGIN 
    ROLLBACK TRAN 
END 
GO 

成功创建后,我通过点击检查交易“修改”存储过程选项在生成的脚本ALTER PROCEDURE我没有看到SET XACT_ABORT ON行:

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

ALTER PROCEDURE MyProc 
AS 
BEGIN TRAN 
... 

我在哪里错了或者有什么诀窍?如何正确定义SET XACT_ABORT ON

+0

您没有在过程定义中包含'SET'语句。当你在2008年时,你应该看看'TRY ... CATCH'。 –

+0

@马丁·史密斯:你的意思是不包括'SET XACT_ABORT ON'所有,而是由赶上'TRY..CATCH'错误,并明确'ROLLBACK'事务? – rem

+0

参见[这个答案](http://stackoverflow.com/questions/1150032/what-is-the-benefit-of-using-set-xact-abort-on-in-a-stored-procedure/1150350#1150350 )和下面的评论来讨论这个问题。我绝对不会因为你的代码在TRY ... CATCH可用时测试SQL Server 2008上的'@@ ERROR'而烦恼。只要提到'XACT_ABORT'在'TRY'块中有不同的效果。 –

回答

6

你通常设置xact_abort作为存储过程的身体的一部分:

CREATE PROCEDURE MyProc 
AS 
SET XACT_ABORT ON 
BEGIN TRAN 
.... 

但是也有一些从创建程序会话记住两个“特殊”的设置。 Explanation from MSDN:

存储过程执行与执行 时间除了SET ANSI_NULLS和SET QUOTED_IDENTIFIER指定的SET设置。存储 程序指定SET ANSI_NULLS或SET QUOTED_IDENTIFIER使用在存储过程创建时指定的 设置。如果在 存储过程中使用,则会忽略任何SET设置。

因此,当您创建存储过程时,SQL Server会将QUOTED_IDENTIFIER选项从连接复制到过程定义。目标是具有不同QUOTED_IDENTIFIER设置的其他人仍然获得该过程的作者所期望的行为。

同样不是真正XACT_ABORT

+0

为什么你的sql示例使用'SET XACT_ABORT ON'并且还使用事务?是不是将'XACT_ABORT'设置为'ON'以使整个过程成为原子的目的?你为什么还需要交易? –

+0

好的,我看到作者已经在他的代码示例中有过。不过,我以前的陈述是否准确? –

0

你没有提到你是否正在使用SQL Management Studio中,但如果你是,点击现有的存储过程“修改”(这我假设是你做了什么),那么MS只是产生一个样板脚本基于现有存储过程的内容。

你可能会考虑定义在执行和修改的程序,以及其他任何你想要的存储过程之外的选项(如SET XACT_ABORT ON)一个单独的脚本文件的存储过程。这样你有更多的控制权,可以执行脚本来更新存储过程。