2009-12-09 178 views
2

我想从另一个SP调用SP。我知道我可以轻松地称呼它。但问题是,如果在SP2中发生错误,那么我想ROLLBACK SP1。从另一个存储过程调用存储过程

SP1
的begin tran
[一些代码]
呼叫到SP2
[一些代码]

SP2
BEGIN TRAN
[一些代码]
[错误出现]
ROLLBACK TRAN

这将仅在sp2中回滚Tran。如果在sp2中发生错误,我也想回滚SP1。

任何帮助,将不胜感激。

+2

@vaibhav:我已经更新了标签'sqlserver2005'到'sql-server-2005'。你会考虑使用现有的标签吗?谢谢。 – Sung 2009-12-09 22:36:38

+0

对于你想知道的关于错误处理的一切,但不敢问,Erland Sommarskog在这里有一篇很好的(虽然未完成)的文章:http://sommarskog.se/error_handling_2005.html ...它也链接到他的两个SQL Server 2000的文章,但其中一些概念仍然适用于更新的版本。 – 2009-12-10 04:16:40

回答

2

似人与其他信息网站问题...

它的要点是父过程将尝试执行回滚的时候通过异常孩子已经拥有。解决这个问题的方法是让父级在提交之前检查@trancount。

http://forums.asp.net/t/1259708.aspx

Create procedure [dbo].[parent] as Begin Transaction Begin Try 
    Exec Child End Try Begin Catch 
    If @@Trancount > 0 
     RollBack End Catch Commit 


Create procedure [dbo].[Child] as Begin Transaction Begin Try 
    --Do inserts here End Try Begin Catch 
    If @@Trancount > 0 
     RollBack 
    RAISERROR('Error Occured',16,1) End Catch Commit 
+1

你不应该从这里链接到这个网站。;-) – Tomalak 2009-12-09 21:56:15

+0

在您的链接中看不到任何内容。 – 2009-12-09 21:59:02

+0

谢谢,我可以使用@@错误来检查“引发的错误” – 2009-12-09 22:19:09

1

一种可能性是使用@ErrorCode INT OUTPUT参数创建SP2,该参数指示调用者是否需要回滚或提交。

+0

或使用返回值。 – erikkallen 2009-12-09 22:13:27

4

在SP2中尝试RAISERROR

+0

您能否详细说明一下。 – 2009-12-09 22:00:07

+0

在SP2内引发错误也会导致SP1回滚其事务。你做手动回卷还是自动回卷? – Tomalak 2009-12-09 22:03:37

+0

它的自动,使用“回滚Tran” – 2009-12-09 22:06:28

0

在你的第二个SP中创建一个输出参数,它是类型位,指示是否发生了错误。在此基础上,你可以回滚SP 1

1

你可以使用这样的错误代码(我不是写代码只是我该怎么做,如果我是你)

SP1 
DECLARE ReturnVal 
BEGIN TRAN 
CODE 
CALL SP1 ReturnVal output 
IF ReturnVal=errorvalue 
ROLLBACK TRAN 

SP2 
DECLARE ReturnVal output 
BEGIN TRAN 
CODE 
ERROR 
SET ReturnVal=errorVal 
ROLLBACK 
RETURN ReturnVal 
1

它不喜欢你的声音需要嵌套事务。试着用try块(伪码)控制提交/回滚:

begin try 
    begin trans 
    do stuff 
    call other sp 
    do more stuff 
    commit trans 
end try 
begin catch 
    rollback trans 
    do something here to report failure to app 
end catch 

如果try块内的任何地方发生错误,包括withing其他SP,控制将传递到catch块和回滚事务。

+0

我认为这值得考虑。但是不应该像其他人所说的那样使用输出参数。 – 2009-12-09 22:21:10

+0

@valbhav:考虑同时使用'RAISERROR'和'TRY ... CATCH' ... – Sung 2009-12-09 22:35:22

+0

我的方案会捕获由您或服务器“引发”的错误。如果您需要报告第二个sp中的一些业务错误信息,则可以像其他人所建议的那样调用raiserror,这是我的try-catch事件可以捕获的。或者你可以使用输出参数来报告错误。在这种情况下,try-catch不会对你有所帮助,你需要做一个'if'语句或者测试返回值。即使如此,trh try-catch仍然很好,可以捕捉到意想不到的错误。 – Ray 2009-12-09 22:58:47

相关问题