esj*_*sjr 0 sql-server stored-procedures
为一个存储过程调用多个存储过程时,这是在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
Run Code Online (Sandbox Code Playgroud)
我强烈建议使用TRY/CATCH块和RAISERROR而不是@@ ERROR/@结果检查.我有一个博客条目,显示如何正确使用事务和TRY/CATCH块,包括嵌套事务只恢复失败的过程调用工作,以便calee可以恢复不同的路径并继续事务,如果感觉如下:异常处理和嵌套交易.
<更新>
您在程序返回模式方面不一致.UpdateTHIS和UpdateTHAT返回0/1作为返回值,而包装器DoStuff作为结果集(SELECT)返回.这意味着您无法编写调用DoStuff的DoMoreStuff,因为它必须使用INSERT ... EXEC来捕获结果,并且您很快就会发现INSERT ... EXEC无法嵌套.为了保持一致性,我建议使用RETURN @result.
</更新>
我也有一个不相关的推荐,这只是风格的一个元素:我发现很长的IF ...如果......如果......如果......如果...块很难阅读和遵循.我总是发现表达与DO一样...... BREAK ...... BREAK ...... BREAK ...... WHILE(FALSE)更容易阅读.T-SQL没有DO ... WHILE构造,因此必须使用WHILE ...:
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
Run Code Online (Sandbox Code Playgroud)
同样,这并不重要,因为它只是一种代码格式化风格,但如果您同意它会导致代码更容易阅读,那么这是一个建议.
| 归档时间: |
|
| 查看次数: |
6128 次 |
| 最近记录: |