存储过程 游标 while(@@FETCH_STATUS=0)死循环

本文探讨了使用游标时遇到的死循环问题,解释了直接使用while(@@FETCH_STATUS=0)导致死循环的原因,并提供了正确的解决方案,即在循环体内部指定获取下一行数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用游标的时候用到while(@@FETCH_STATUS=0),因为第一次是直接从网上复制的,也没记清楚,后面再用的时候就发现这样写会死循环;
在这里插入图片描述在这里插入图片描述

刚开始还以为是偶然,随便加了一个判断就糊弄过去了,后来再用,实在避不开这个问题,就查了一下,嗯发现要在循环体里面再指定获取下一行,这样才不会死循环
在这里插入图片描述

--新建视图 v_desk create view v_desk as select a.*, b.usingType_code, b.sOrderNo from t_desk a left join t_using_desk b on a.id = b.desk_id go --新建台号时向 t_using_desk 插入记录 --台号显示的时候查 v_desk --去掉表 t_dish_orderedNumber --t_order有些字段改为float --t_order_temp增加 price float字段 --t_using_desk增加 sOrderNo nvarchar(20) 字段 --t_dishes 修改 ordered_number float ----------------------------- --发送过程:先选台号,若该台号处于正在使用状态(在表 t_using_desk 中 usingType_code = '02'), --则表明是加菜,从 t_using_desk 中获取该台号对应的 sOrderNo,传入存储过程 sp_orderDishes;(在 sp_orderDishes 中将有菜品的台号的 singType_code 置为‘02’,在结账时重新置为 ‘01’) --若该台号处于空闲状态(在表 t_using_desk 中 usingType_code = '01'),则表明该台号即将被使用,需生成 sOrderNo, 向 t_order 表中增加该订单的信息,然后执行存储过程 sp_orderDishes ------------------------- --创建存储过程 sp_orderDishes --1、将临时表 t_order_temp 中的数据插入到 t_order_dishes --2、将表 t_using_desk 中对应的 desk_id 的 usingType_code 置为 '02'(使用中) --3、更新 t_dishes 的 ordered_number --4、删除临时表 t_order_temp 中该 userId 对应的数据 --drop procedure sp_orderDishes create procedure sp_orderDishes @orderNo nvarchar(20), @userId uniqueidentifier, @deskId uniqueidentifier as begin transaction insert into t_order_dishes(sOrderNo, dish_id, price, order_num, subtotal, taste_id1, taste_id2, remark, waiter) select @orderNo, dish_id, price, order_num, price*order_num, taste_id1, taste_id2, remark, userId from t_order_temp where userId = @userId IF @@ROWCOUNT > 0 update t_using_desk set usingType_code = '02', sOrderNo = @orderNo where desk_id = @deskId if @@error 0 begin rollback transaction--发生错误则回滚事务,无条件退出l return end DECLARE @DishId uniqueidentifier declare @OrderNum float DECLARE My_Cursor CURSOR--定义游标 FOR (SELECT dish_id, order_num FROM t_order_temp where userId = @userId) --查出需要的集合放到游标中 OPEN My_Cursor; --打开游标 FETCH NEXT FROM My_Cursor INTO @DishId, @OrderNum; --读取第一行数据(将 t_order_temp 表中的 dish_id 放到 @DishId 变量中) WHILE @@FETCH_STATUS=0 BEGIN UPDATE t_dishes SET ordered_number = ordered_number + @OrderNum WH
優化以下OPEN MY_CURSOR FETCH NEXT FROM MY_CURSOR INTO @Prenum,@Empid,@Unitid,@PresentId,@FromTime,@ToTime,@PreReason WHILE @@FETCH_STATUS=0 BEGIN Set @P_SERNO = @Prenum Set @P_ID_NO_SZ = @Empid Set @P_DEPT = @Unitid Set @P_REASON = @PresentId Set @P_DATETIME_B = @FromTime Set @P_DATETIME_E = @ToTime Set @P_FAMILY_TYPE = null IF @PresentId = 'L26' BEGIN Set @P_FAMILY_TYPE = 'L26-13A' IF OBJECT_ID('tempdb..#a') IS NOT NULL BEGIN DROP TABLE #a END IF OBJECT_ID('tempdb..#b') IS NOT NULL BEGIN DROP TABLE #b END IF OBJECT_ID('tempdb..#k') IS NOT NULL BEGIN DROP TABLE #k END select * into #a from openquery(SAL_HCPPROD,'select * from hcp.HR_FUNERAL ') select * into #b from openquery(SAL_HCPPROD,'select * from hcp.HR_FAMILY_TYPE ') select * into #k from openquery(SAL_HCPPROD,'select * from hcp.hr_personnel_base ') DECLARE @P_DEATH_DATE1 VARCHAR(30) ='' select @P_DEATH_DATE1 = a.DEATH_DATE from #a a where a.family_type_id = (select b.family_type_id from #b b where family_type = @P_FAMILY_TYPE ) and a.psn_id =(select k.id from #k k where k.id_no_sz = @P_ID_NO_SZ) SET @P_DEATH_DATE = @P_DEATH_DATE1 END ------------ 向HCP資料庫中INSERT資料 Print '@P_SERNO:' + @P_SERNO Print '@P_ID_NO_SZ:' +@P_ID_NO_SZ Print '@P_DEPT:' + @P_DEPT Print '@P_REASON:' +@P_REASON Print '@P_DATETIME_B:' + @P_DATETIME_B Print '@P_DATETIME_E:' + @P_DATETIME_E Print '@P_FAMILY_TYPE:' + @P_FAMILY_TYPE Print '@P_DEATH_DATE:' Print @P_DEATH_DATE Print '@P_SEGMENT_NO:' + @P_SEGMENT_NO Print '@P_REMARK:' + @P_REMARK Print '@P_CONFIRM:' + @P_CONFIRM Print '@P_PERIOD_MASTER:' + @P_PERIOD_MASTER Print '@P_PERIOD_DETAIL:' + @P_PERIOD_DETAIL Print '@P_ERROR_TYPE:' + @P_ERROR_TYPE Print '@P_CREATE_BY:' + @P_CREATE_BY Print '@P_FAMILY_NAME:' + @P_FAMILY_NAME EXECUTE ('BEGIN hcp.P_ABSENCE_INSERT_FLOW_TW(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?); END;', @P_SERNO, @P_ID_NO_SZ, @P_DEPT, @P_REASON, @P_DATETIME_B, @P_DATETIME_E, @P_FAMILY_TYPE, @P_DEATH_DATE, @P_HOURS output, @P_DAYS output, @P_SEGMENT_NO, @P_REMARK, @P_ERROR output, @P_CONFIRM, @P_PERIOD_MASTER, @P_PERIOD_DETAIL, @P_ERROR_TYPE, @P_CREATE_BY, @P_FAMILY_NAME) AT SAL_HCPPROD Print '@P_ERROR:' Print @P_ERROR IF @P_ERROR = 'OK' BEGIN SET @Result = 'Y' SET @OK=@OK+1 END ELSE BEGIN SET @Result = 'N' SET @NG=@NG+1 --記錄本次拋轉異常數據 INSERT INTO #PresentToHCP_Log SELECT @P_SERNO, @P_ID_NO_SZ, @P_DEPT, @P_REASON, @P_DATETIME_B, @P_DATETIME_E, @P_ERROR, @Result, GETDATE() END --將拋轉數據存入拋轉記錄表 INSERT INTO PresentToHCP_Log SELECT @P_SERNO, @P_ID_NO_SZ, @P_DEPT, @P_REASON, @P_DATETIME_B, @P_DATETIME_E, @P_ERROR, @Result, GETDATE() FETCH NEXT FROM MY_CURSOR INTO @Prenum,@Empid,@Unitid,@PresentId,@FromTime,@ToTime,@PreReason END CLOSE MY_CURSOR DEALLOCATE MY_CURSOR
最新发布
03-22
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值