MSSQL中,一个事务(TRANSACTION)中支持多次执行存储过程(PROCEDURE)

先创建一个测试表:

-- 创建测试表格
CREATE TABLE table_test
(
    [id] [int] NOT NULL PRIMARY KEY IDENTITY(1, 1),
    [name] [varchar] (50) NULL,
)
GO

创建存储过程:

-- 测试用的存储过程
CREATE PROCEDURE proc_test
    @name AS VARCHAR(60)
AS
BEGIN
    INSERT INTO dbo.table_test(name) VALUES(@name)
END
GO

测试一个事务中执行多次存储过程:

-- 在一个事务中执行两次存储过程
BEGIN TRANSACTION
--执行存储过程
EXECUTE dbo.proc_test @name='张三';
EXECUTE dbo.proc_test @name='李四';
EXECUTE dbo.proc_test @name='王五';
--提交存储过程
COMMIT TRANSACTION
GO

执行结果:

MSSQL中,一个事务(TRANSACTION)中支持多次执行存储过程(PROCEDURE)MSSQL中,一个事务(TRANSACTION)中支持多次执行存储过程(PROCEDURE)

关于存储过程中执行出错后,会继续执行后续的脚本。测试:

-- 在一个事务中执行两次存储过程
BEGIN TRANSACTION
--执行存储过程
EXECUTE dbo.proc_test @name='张三';
-- 长度超过表格的50,超过存储过程变量的60
EXECUTE dbo.proc_test @name='李四asdfasdfasdfasdfasdfasdfasfasdfasdfasdfasdfasdfasdfasfasdfasdfasdfasdfasdfasdfasf';
EXECUTE dbo.proc_test @name='王五';
--提交存储过程
COMMIT TRANSACTION
GO

执行结果:

MSSQL中,一个事务(TRANSACTION)中支持多次执行存储过程(PROCEDURE)MSSQL中,一个事务(TRANSACTION)中支持多次执行存储过程(PROCEDURE)

 可以看到参数超过存储过程的变量长度,存储过程就报错了。但后续的脚本继续执行完成了。

我们应该优化语句:

-- 在一个事务中执行两次存储过程
BEGIN TRANSACTION
    -- 通过变量来记录错误 【注意】@@ERROR是错误编码而不是错误数
    DECLARE @sumError INT = 0;
    --执行存储过程
    EXECUTE dbo.proc_test @name='张三';
    SET @sumError = @sumError+@@ERROR
    -- 长度超过表格的50,超过存储过程变量的60
    EXECUTE dbo.proc_test @name='李四asdfasdfasdfasdfasdfasdfasfasdfasdfasdfasdfasdfasdfasfasdfasdfasdfasdfasdfasdfasf';
    SET @sumError = @sumError+@@ERROR
    EXECUTE dbo.proc_test @name='王五';
    SET @sumError = @sumError+@@ERROR
IF (@sumError <> 0)
BEGIN
    --提交存储过程
    ROLLBACK TRANSACTION
END
ELSE 
BEGIN
    --提交存储过程
    COMMIT TRANSACTION
END
GO

优化方案二:

--用 TRY CATCH
BEGIN TRY
-- 在一个事务中执行两次存储过程
BEGIN TRANSACTION
    --执行存储过程
    EXECUTE dbo.proc_test @name='张三';
    -- 长度超过表格的50,超过存储过程变量的60
    EXECUTE dbo.proc_test @name='李四asdfasdfasdfasdfasdfasdfasfasdfasdfasdfasdfasdfasdfasfasdfasdfasdfasdfasdfasdfasf';
    EXECUTE dbo.proc_test @name='王五';
    --提交存储过程
    COMMIT TRANSACTION
END TRY
BEGIN CATCH
    --提交存储过程
    ROLLBACK TRANSACTION
END CATCH
GO

 

参考:

Sql Server 中的 @@ERROR

Sql Server 中关于@@ERROR的一个小小误区

 

上一篇:Leetcode——868.二进制间距——题解+代码实现


下一篇:不打无准备之仗,大战2020:最全868道Java面试题及答案整理分享