27,579
社区成员
发帖
与我相关
我的任务
分享
实验目的:sqlserver的存储过程中事物的写法,以及对异常的处理
实验步骤:Table1,Table2,都有主键,在一个存储过程中往这个两个表中插数据,两条插入数据的sql分别放在事物中,有意使其异常
结果:我知道,存储过程中的事物(有多个),后面的一个发生异常后,前面执行成功的也不会提交,这里不在给出详细信息
但是关于返回值设置值的问题就不是这么回事了,还有一只没有解决的return到底该怎么用的问题
疑问:对于异常情况的处理的写法以及调试过程中发现@error变量的问题,还有就是网上看到把两个sql放到一个事物中,
BEGIN TRANSACTION sql1 sql2 COMMIT TRANSACTION
个人感觉粒度有点大,其实也是没问题的,但是想更进一步探索下
所以这里疑问就是return的用法问题,能不能这样return,还有就是存储过程中多个sql,卸载一块放在一个事物中还是分别放在一个事物中,异常了用return返回呢?
网上见到的另外一种写法就是也不太合适,因为即便是你if(@@error)成立,还是继续往下走,即便是后面sql出错,前面正常的sql最终不会执行成功,但这样感觉不大合适吧?
--事物开始
sql1
if(@@error>0)
--回滚
--事物提交
--事物开始
sql2
if(@@error>0)
--回滚
--事物提交
create table tb(id int identity(1,1),ic int unique)
insert into tb select 2
go
create proc pro
@i int,
@j int output,
@k int output
AS
BEGIN
begin try
begin tran
insert into tb select @i
set @j = 0
commit
end try
begin catch
rollback
set @j=1
end catch
begin try
begin tran
update tb set ic = 1 where id = @i
set @k = 0
commit
end try
begin catch
rollback
set @k=1
end catch
END
GO
declare @m int,@n int
exec pro 1,@m output,@n output
select * from tb
select @m,@n
drop proc pro
drop table tb
/***********
id ic
----------- -----------
1 2
2 1
(2 行受影响)
----------- -----------
0 1
(1 行受影响)
create table employee (empid int, fname varchar(50),lname varchar(50))
insert into employee (empid, fname, lname) values (2021115, 'jim', 'kennedy')
go
create procedure [dbo].[updatewanjun]
@upret varchar(10),
@returnval int output
as
begin
begin transaction t
begin try
update employee set empid=@upret where fname ='jim';
set @returnval=-1;
commit
end try
begin catch
set @returnval=1;
rollback
end catch
end
go
declare @returnval int ;
exec updatewanjun '123',@returnval output
select @returnval
/*
-1
*/
declare @returnva int ;
exec updatewanjun 'aa',@returnva output
select @returnva
/*
1
*/
drop proc [updatewanjun]
drop table employee