前言 |
项目中要实现前端页面动态配置行为,每个行为调用不同的存储过程的功能,于是乎小编一头扎进了存储过程的海洋中,愈发觉得之前写的存储过程算是基础了。遇到一个问题:查询到表中一列数据,需要取出每一行数据来执行下一个存储过程。这可怎么闹?别急,小编来给你支招。
正文 |
逻辑:第一次取第一行记录,第二次取第二行记录,第三次取第三行记录……
方法一 :sql 语句
--第一次尝试
BEGIN TRY declare @i int ---存放循环变量 declare @count int ---存放pcb关联板的数量 declare @pcbID nvarchar(64) --虚拟pcbid set @i = 1;
BEGIN TRAN begin select @pcbID = PcbID from [dbo].[MM_LOTS_PCB] where LotID=@LotID select @count = count(*) from [dbo].[MM_LOTS_PCB] where PcbID = @pcbID while @i < @count begin --第一次,选出第一行数据,第二次,取出前两条数据不在前一条中,以此类推 select top (@i) @LotID = LotID from [dbo].[MM_LOTS_PCB] where PcbID = @pcbID and LotID not in (select top (@i-1) LotID from [dbo].[MM_LOTS_PCB] where PcbID = @pcbID ) set @i = @i + 1 exec [dbo].[CP_PM_WIP] @LotID,'','','','',@stepID,@stationID,'',@userID,'' end end COMMIT TRAN END TRY BEGIN CATCH ROLLBACK TRAN set @ReturnMessage = 'NG '+ ERROR_MESSAGE() RAISERROR(@ReturnMessage,16,1)--抛出异常 END CATCH END
想想也是这么个理,比较笨的办法,实现了还是挺开心的;But,后面的测试中发现了大 Bug , 来来来,大家跟着我的思路走,当数据为3条(1,2,3)时,第一次 ,取值1;第二次,取值2,3 这就坏事了,我来把它调整一下。
--第二次尝试
while @i < @count
begin
-- TOP 1 每次选择一条
select top 1 @LotID = LotID from [dbo].[MM_LOTS_PCB] where PcbID = @pcbID and LotID not in (select top (@i-1) LotID from [dbo].[MM_LOTS_PCB] where PcbID = @pcbID )
set @i = @i + 1
exec [dbo].[CP_PM_WIP] @LotID,'','','','',@stepID,@stationID,'',@userID,''
end
经过一次修改之后才是比较符合的,也是Get了一项新技能!
后来,我让老大给我看看我写的存储过程,他瞥见我这‘绝招’,说这是在干啥? 这种方式真奇怪 ,我忙解释,老大说,其实你还可以这样;
方法二 :游标
declare curTab CURSOR FOR --声明游标
select LotID from [dbo].[MM_LOTS_PCB] where PcbID = @pcbID OPEN curTab --打开游标 FETCH NEXT FROM curTab INTO @LotID 将游标指向的数据放到本地变量中 ,游标指向结果中第一行 --判断游标的状态 --0 fetch语句成功 --1 fetch语句失败或此行不在结果集中 --2 被提取的行不存在 WHILE @@FETCH_STATUS = 0 --语句成功 BEGIN ---过站 exec [dbo].[CP_PM_WIP] @LotID,@orderID,@defID,@stepID,@stationID,'',@userID,null FETCH NEXT FROM curTab INTO @LotID --执行下一行,可以重复,直到完成结果集中所有行 END CLOSE curTab--关闭游标 DEALLOCATE curTab-- 释放游标
游标在使用的时候会吃掉很多内存,增加代码量,程序执行速度变慢,这个邪恶的小游标 ! 当数据量不大的时候,可以使用游标。
游标小课堂
什么是游标?
游标可以被看作指向结果集中一行的指针。游标每个时间点只能指向一行,但是可以根据需要指向结果集中的其他行。
游标的作用?
- 指定结果集中特定行的位置;
- 基于当前结果检索一行或连续的几行;
- 在结果集的当前位置修改行中的数据;
游标什么时候用?
从一个结果集中循环遍历数据进行相同或者不同的操作,而不是一次对整个结果集进行同一种操作;
总结 |
存储过程中循环遍历一列数据的实现先讲到这里了,小编觉得游标的使用还需要跟老大再商量,而且业务人员也不止一次的告诉我,一定会改的!亲爱的朋友们,你们有没有其他的思路呢?交流一下。