============while循环==============

-Tracy-McGrady- 2016-04-20 02:37:03

create table tb_test(lszh varchar(20),before varchar(2) default 'n',after varchar(2) default 'n')
create proc proc_test1
as
begin
insert into tb_test(lszh) select lszh from tb_lszh --假设一次数插入20条数据
declare @lszh varchar(20)
while exists(select lszh from tb_test where after='n')
begin
select top(1) @lszh=lszh from tb_test where after='n'
update tb_test set before='y'
exec proc_test_2 --执行另一个存储过程
update tb_test set after='y'
end
end

--现遇到个奇葩问题,我前台程序中调用存储过程的时候exec proc_test1 的时候成功插入20条数据在tb_test表中,流水号什么的都是对的
--但是存储过程有时候执行会出现类似下面数据的结构
lszh before after
1 y y
2 y y
3 y y
4 y y
5 y y
6 y n --这里是一个y,一个n
7 n n
8 n n
9 n n
10…………
11…………后面的都是n,n了不写了


就在这个时候,我悄悄在后台数据库中执行了如下语句,exec proc_test1,这些完了,剩下的数据毫无错误的被执行完了


鬼火一怒,我加了个捕获异常的在exec proc_test_2 上面
create table tb_error(lszh varchar(20),err_message varchar(200),err_line int)
所以存储过程就变成这样了
create proc proc_test1
as
begin
insert into tb_test(lszh) select lszh from tb_lszh --假设一次数插入20条数据
declare @lszh varchar(20)
while exists(select lszh from tb_test where after='n')
begin
select top(1) @lszh=lszh from tb_test where after='n'
update tb_test set before='y'
begin try
exec proc_test_2 --执行另一个存储过程
end try
begin catch
insert into tb_error(lszh,err_message,err_line) select @lszh,error_message(),error_line()
end catch
update tb_test set after='y'
end
end

--但是这似乎没有什么卵用,表tb_error中捕获不到任何错误,存储过程执行的时候还是会遇到上面那个奇葩的问题(ps,貌似也不是每次执行都会这样,就观察而已有的时候数据量大的时候会出现这样,但是绝对不是超时,因为我跟踪过执行时间,很短)

就在这个时候,我又悄悄在后台数据库中执行了如下语句,exec proc_test1,这些完了,剩下的数据毫无错误的被执行完了,没报任何错误


于是鬼火一怒,我又改了下存储过程
create proc proc_test1
as
begin
begin try
insert into tb_test(lszh) select lszh from tb_lszh --假设一次数插入20条数据
declare @lszh varchar(20)
while exists(select lszh from tb_test where after='n')
begin
select top(1) @lszh=lszh from tb_test where after='n'
update tb_test set before='y'
exec proc_test_2 --执行另一个存储过程
update tb_test set after='y'
end
end try
begin catch
insert into tb_error(lszh,err_message,err_line) select @lszh,error_message(),error_line()
end catch
end
--但是,还是铺货不到任何错误,执行是还是会发生上面的奇葩现象


---于是,我又鬼火了,在 proc_test_2里面加
alter proc proc_test_2
as
begin
begin try
…………
end try
begin catch
insert into tb_error(lszh,err_message,err_line) select @lszh,error_message(),error_line()
end catch
end
--然而,还是没有捕获到异常,程序大哥心情好了的时候还是给你来一个这样的奇葩
lszh before after
1 y y
2 y y
3 y y
4 y y
5 y y
6 y n --这里是一个y,一个n
7 n n
8 n n
9 n n
10…………
11…………后面的都是n,n了不写了


----各位英雄好汉,来拯救下我吧,谢谢
...全文
167 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
-Tracy-McGrady- 2016-04-20
  • 打赏
  • 举报
回复
引用 11 楼 spiritofdragon 的回复:
[quote=引用 9 楼 spiritofdragon 的回复:] 我怀疑,是不是,你这个执行的时间太长,被“公司dba”或者“某些自动检查死锁排队并能kill的程序” 给kill了。所以没执行完。
因为如果正常报错,就应该写你的err表。 当然,你说你的 proc_test_1 也是放在别的事物里....这样就即使捕获到异常也可能被外层事务回滚。所以,最好是proc_test_1放到最外层,这样才好调试。[/quote] 哪有那么好放的第一层啊,嵌套着呢,郁闷
spiritofdragon 2016-04-20
  • 打赏
  • 举报
回复
引用 9 楼 spiritofdragon 的回复:
我怀疑,是不是,你这个执行的时间太长,被“公司dba”或者“某些自动检查死锁排队并能kill的程序” 给kill了。所以没执行完。
因为如果正常报错,就应该写你的err表。 当然,你说你的 proc_test_1 也是放在别的事物里....这样就即使捕获到异常也可能被外层事务回滚。所以,最好是proc_test_1放到最外层,这样才好调试。
-Tracy-McGrady- 2016-04-20
  • 打赏
  • 举报
回复
引用 9 楼 spiritofdragon 的回复:
我怀疑,是不是,你这个执行的时间太长,被“公司dba”或者“某些自动检查死锁排队并能kill的程序” 给kill了。所以没执行完。
执行时间不长啊,你看看我另外那个帖子里面贴的图片,就一秒不到
spiritofdragon 2016-04-20
  • 打赏
  • 举报
回复
我怀疑,是不是,你这个执行的时间太长,被“公司dba”或者“某些自动检查死锁排队并能kill的程序” 给kill了。所以没执行完。
-Tracy-McGrady- 2016-04-20
  • 打赏
  • 举报
回复
引用 4 楼 wmxcn2000 的回复:
1 。 proc_test_2   的语句,都贴出来 2。 tb_lszh   表结构和数据,都提供一下;
tb_lszh就一个临时用的表,原来是个#表,后来我改了,作用就是把符合要求的流水号查询出来插进去,然后每次取一个流水号循环调用proc_test_2 ,因为proc_test_2 里面只提供了一个流水号,不能全部一起,proc_test_2 是其他人写的,也没什么问题,具体的业务我也不太清楚,但是proc_test_2 在很多程序里面使用的,人都没问题。语句有点多,在内网电脑里面,贴不出来啊 我之前还发过一个帖子http://bbs.csdn.net/topics/391934117
-Tracy-McGrady- 2016-04-20
  • 打赏
  • 举报
回复
引用 5 楼 roy_88 的回复:
开事务,是数据一致性,只要有错误 才会去做回滚 proc_test_2 --存储过程里有没有针对tb_test 表做操作
我的proc_test_1又是在另外一个存储过程里面调用的,当时为了找错误,我把proc_test_1放到前面有个地方的事物里面执行过一个小时,数据全部回滚了,连上一个存储过程都没执行,全回滚。所以我才怀疑是proc_test_2出错了,但是我在数据库里面单独执行proc_test_1,又不报错。我就很郁闷了,tb_test里面有多少数据全部都可以顺着执行成功。 tb_test 其实就是一个临时表,用来存符合要求的流水号的。所以在proc_test_2里面没做任何处理。谢谢
-Tracy-McGrady- 2016-04-20
  • 打赏
  • 举报
回复
引用 1 楼 roy_88 的回复:
开事务 create proc proc_test1 as begin try begin tran insert into tb_test(lszh) select lszh from tb_lszh --假设一次数插入20条数据 declare @lszh varchar(20) while exists(select lszh from tb_test where after='n') begin select top(1) @lszh=lszh from tb_test where after='n' update tb_test set before='y' exec proc_test_2 --执行另一个存储过程 update tb_test set after='y' end commit tran end try begin catch insert into tb_error(lszh,err_message,err_line) select @lszh,error_message(),error_line() rollback tran end catch
如果全部回滚了,那这就没法跟踪了啊?还是?
-Tracy-McGrady- 2016-04-20
  • 打赏
  • 举报
回复
引用 2 楼 spiritofdragon 的回复:
两个问题。 1、@lszh没有用上?你是不是写得省略了?还是@lszh会再后面的update里作为where条件,因为后面update没有where条件很难想像,或者@lszh会作为 proc_test_2 的参数使用? 2、你是想找到正确的写法?还是,想找到catch不到异常的原因。如果是前者,最好再提供下proc_test_2的内容,并提供完全的脚本和数据。如果是想讨论后者,那么我只能怀疑,某些地方被回滚了,比如:某些触发器里,或者proc_test_2里等等。
update tb_test set after='y' where lszh=@lszh,忘记写了,反正我检查过各种语法了,没问题。上面的例子是随手敲的,把这个敲漏了。什么都行啊,把问题解决了就行,谢谢啊大哥
中国风 2016-04-20
  • 打赏
  • 举报
回复
开事务,是数据一致性,只要有错误 才会去做回滚 proc_test_2 --存储过程里有没有针对tb_test 表做操作
卖水果的net 版主 2016-04-20
  • 打赏
  • 举报
回复
1 。 proc_test_2   的语句,都贴出来 2。 tb_lszh   表结构和数据,都提供一下;
spiritofdragon 2016-04-20
  • 打赏
  • 举报
回复
两个问题。 1、@lszh没有用上?你是不是写得省略了?还是@lszh会再后面的update里作为where条件,因为后面update没有where条件很难想像,或者@lszh会作为 proc_test_2 的参数使用? 2、你是想找到正确的写法?还是,想找到catch不到异常的原因。如果是前者,最好再提供下proc_test_2的内容,并提供完全的脚本和数据。如果是想讨论后者,那么我只能怀疑,某些地方被回滚了,比如:某些触发器里,或者proc_test_2里等等。
中国风 2016-04-20
  • 打赏
  • 举报
回复
开事务 create proc proc_test1 as begin try begin tran insert into tb_test(lszh) select lszh from tb_lszh --假设一次数插入20条数据 declare @lszh varchar(20) while exists(select lszh from tb_test where after='n') begin select top(1) @lszh=lszh from tb_test where after='n' update tb_test set before='y' exec proc_test_2 --执行另一个存储过程 update tb_test set after='y' end commit tran end try begin catch insert into tb_error(lszh,err_message,err_line) select @lszh,error_message(),error_line() rollback tran end catch

34,588

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧