当为一个存储过程调用多个存储过程时,在SQL Server 2008上这是正确的还是最好的方法?
CREATE PROCEDURE [dbo].[DoStuff]
AS
BEGIN
SET NOCOUNT ON;
declare @result int
BEGIN TRANSACTION
BEGIN
EXECUTE @result = dbo.UpdateTHIS @ID = 1
IF @result != 0
ROLLBACK
ELSE
EXECUTE @result = dbo.UpdateTHAT @ID = 21
IF @result != 0
ROLLBACK
ELSE
EXECUTE @result = dbo.UpdateANOTEHR @ID = 15
IF @result != 0
ROLLBACK
ELSE
COMMIT
SELECT @result
END
END发布于 2009-11-12 00:12:46
我强烈建议使用TRY/CATCH块和RAISERROR,而不是@@ERROR/@result检查。我有一篇博客文章,展示了如何正确使用事务和TRY/CATCH块,包括嵌套事务,以便仅恢复失败的过程调用工作,以便被调用者可以恢复不同的路径并继续事务,如果感觉像:Exception Handling and Nested Transactions。
您在过程返回模式方面不一致。UpdateTHIS和UpdateTHAT返回0/1作为返回值,而包装器DoStuff作为结果集(SELECT)返回。这意味着您不能编写调用DoStuff的DoMoreStuff,因为它必须使用Insert...EXEC来捕获结果,您很快就会发现插入...EXEC不能嵌套。为了保持一致性,我建议使用RETURN @result。
我还有一个不相关的推荐,这只是风格的一个元素:我发现long IF...否则..。否则..。否则..。难以读取和跟踪的块。我总是发现表达和做是一样的.休息..。休息..。休息..。而(FALSE)更容易读懂。T-SQL没有DO ...虽然构造,所以有一段时间...必须改用:
BEGIN TRANSACTION
WHILE (1=1)
BEGIN
EXECUTE @result = dbo.UpdateTHIS @ID = 1;
IF @result != 0
BEGIN
ROLLBACK;
BREAK;
END
EXECUTE @result = dbo.UpdateTHAT @ID = 21
IF @result != 0
BEGIN
ROLLBACK;
BREAK;
END
...
COMMIT;
BREAK;
END同样,这并不重要,因为这只是一种代码格式化样式,但如果您同意这会产生更容易阅读的代码,则建议您这样做。
发布于 2009-11-12 00:13:33
嵌套if和not/嵌套if是不同的。Rollback将回滚事务,但会继续执行。我使用了一些显式的RETURN命令来保证您希望代码在何时何地退出存储过程。
发布于 2009-11-12 00:07:45
我不认为从一个存储的proc调用其他的存储的proc是一个非常好的主意。如果出现错误,则需要花费大量的工时才能找出错误发生的位置。在某些情况下,另一个开发人员可能会在不通知团队中任何人的情况下更改存储的proc。可能出错的事情太多了。
最好是在一个大的存储过程中编写所有的sql。
编辑:这也取决于你存储的proc有多大。
https://stackoverflow.com/questions/1716152
复制相似问题