关于用游标批量更新数据问题.

jyh070207 2016-12-27 04:26:23
关于用游标批量更新数据问题.

在游标处理数据,遇到错误时,标识出有错误的行,不停止处理。

比如用一个基本表A中的数据,逐条读取处理,处理表B中的数据,
但会根据表A中不同栏位的值,需要参考其它C/D/E/F等表的内容,
现在的情况是,由于存在各种约束及条件限制,表A中不是每一条都可以更新表B成功,
用游标处理时,当遇到更新不成功的行时,直接结束了,而不是转到下一行继续处理。

期望的结果,比如A有100条记录,有90条可以成功更新到表B,有10条失败。
用游标可以一次处理完,标识出失败的10条记录,同是处理完90条没有问题的记录,
而不是遇到失败的记录就不处理。
...全文
431 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaoxiangqing 2016-12-28
  • 打赏
  • 举报
回复
用try catch包含起来
卖水果的net 版主 2016-12-27
  • 打赏
  • 举报
回复
引用 5 楼 jyh070207的回复:
[quote=引用 4 楼 wmxcn2000 的回复:] [quote=引用 3 楼 jyh070207 的回复:] declare @row_id int declare cursor_aaaa cursor local for select row_id from a open cursor_aaaa fetch next from cursor_aaaa into @row_id while @@fetch_status = 0 begin --这中间一段复杂的处理及更新,但不一定会成功 --实际可能是一个存储过程,用A表的数据更新B表 --也就是这一段,遇到错误会结束 fetch next from cursor_aaaa into @row_id end close cursor_aaaa deallocate cursor_aaaa
那就好办了,成功了,打上一个标记,最后再统计一下没有打标记的有多少;[/quote] 用游标处理时,当遇到更新不成功的行时,直接结束了,而不是转到下一行继续处理. 因为实际的逻辑比较复杂,可能在更新数据时引起触发器或约束的限制,而更新失败, 现在的问题是,遇到失败的行,这个游标就结束了,不行处理下一行。[/quote] 按照1#,把try catch 放在循环中。
中国风 2016-12-27
  • 打赏
  • 举报
回复
给你测个例子: e.g.
SELECT TOP 10 ID=IDENTITY(INT,1,1),1 AS Num,name INTO CurTab FROM sys.tables 

ALTER TABLE CurTab ADD CONSTRAINT CHK_CurTab_Num CHECK(Num/10%2=0)

GO
DECLARE @ErrorRows INT=0;
DECLARE Cur1 CURSOR LOCAL FOR
SELECT ID FROM CurTab
DECLARE @ID INT
OPEN Cur1
FETCH NEXT FROM Cur1 INTO @ID
WHILE @@FETCH_STATUS=0
BEGIN
	BEGIN TRY 
		UPDATE CurTab SET Num=Num+ID*10 WHERE CURRENT OF Cur1;
	END TRY
	BEGIN CATCH
		SET @ErrorRows=@ErrorRows+1
	END CATCH
	FETCH NEXT FROM Cur1 INTO @ID
END
CLOSE Cur1
DEALLOCATE Cur1
SELECT @ErrorRows AS 出错记录数
/*
出错记录数
5
*/
GO
SELECT ID,Num FROM  CurTab

/*
ID	Num
1	1
2	21
3	1
4	41
5	1
6	61
7	1
8	81
9	1
10	101
*/
DROP TABLE CurTab
jyh070207 2016-12-27
  • 打赏
  • 举报
回复
引用 4 楼 wmxcn2000 的回复:
[quote=引用 3 楼 jyh070207 的回复:] declare @row_id int declare cursor_aaaa cursor local for select row_id from a open cursor_aaaa fetch next from cursor_aaaa into @row_id while @@fetch_status = 0 begin --这中间一段复杂的处理及更新,但不一定会成功 --实际可能是一个存储过程,用A表的数据更新B表 --也就是这一段,遇到错误会结束 fetch next from cursor_aaaa into @row_id end close cursor_aaaa deallocate cursor_aaaa
那就好办了,成功了,打上一个标记,最后再统计一下没有打标记的有多少;[/quote] 用游标处理时,当遇到更新不成功的行时,直接结束了,而不是转到下一行继续处理. 因为实际的逻辑比较复杂,可能在更新数据时引起触发器或约束的限制,而更新失败, 现在的问题是,遇到失败的行,这个游标就结束了,不行处理下一行。
卖水果的net 版主 2016-12-27
  • 打赏
  • 举报
回复
引用 3 楼 jyh070207 的回复:
declare @row_id int declare cursor_aaaa cursor local for select row_id from a open cursor_aaaa fetch next from cursor_aaaa into @row_id while @@fetch_status = 0 begin --这中间一段复杂的处理及更新,但不一定会成功 --实际可能是一个存储过程,用A表的数据更新B表 --也就是这一段,遇到错误会结束 fetch next from cursor_aaaa into @row_id end close cursor_aaaa deallocate cursor_aaaa
那就好办了,成功了,打上一个标记,最后再统计一下没有打标记的有多少;
jyh070207 2016-12-27
  • 打赏
  • 举报
回复
declare @row_id int declare cursor_aaaa cursor local for select row_id from a open cursor_aaaa fetch next from cursor_aaaa into @row_id while @@fetch_status = 0 begin --这中间一段复杂的处理及更新,但不一定会成功 --实际可能是一个存储过程,用A表的数据更新B表 --也就是这一段,遇到错误会结束 fetch next from cursor_aaaa into @row_id end close cursor_aaaa deallocate cursor_aaaa
  • 打赏
  • 举报
回复
mark一下 学习 ,学习
卖水果的net 版主 2016-12-27
  • 打赏
  • 举报
回复


fetch from ss into @a 
while @@FETCH_STATUS = 0 
begin
    -- 把 try catch 写到 循环中
    begin try
        update test set ....  / -- 成功的处理
    end try
    begin catch
	    update  ....  -- 失败的处理
    end catch
    -- 下一个
    fetch from ss into @a 
end

34,838

社区成员

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

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