【sql】-儲存過程實現迴圈遍歷一列資料
阿新 • • 發佈:2019-01-25
前言 |
專案中要實現前端頁面動態配置行為,每個行為呼叫不同的儲存過程的功能,於是乎小編一頭扎進了儲存過程的海洋中,愈發覺得之前寫的儲存過程算是基礎了。遇到一個問題:查詢到表中一列資料,需要取出每一行資料來執行下一個儲存過程。這可怎麼鬧?別急,小編來給你支招。
正文 |
邏輯:第一次取第一行記錄,第二次取第二行記錄,第三次取第三行記錄……
方法一 :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 [email protected]
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-- 釋放遊標
遊標在使用的時候會吃掉很多記憶體,增加程式碼量,程式執行速度變慢,這個邪惡的小遊標 ! 當資料量不大的時候,可以使用遊標。
遊標小課堂
什麼是遊標?
遊標可以被看作指向結果集中一行的指標。遊標每個時間點只能指向一行,但是可以根據需要指向結果集中的其他行。
遊標的作用?
- 指定結果集中特定行的位置;
- 基於當前結果檢索一行或連續的幾行;
- 在結果集的當前位置修改行中的資料;
遊標什麼時候用?
從一個結果集中迴圈遍歷資料進行相同或者不同的操作,而不是一次對整個結果集進行同一種操作;
總結 |
儲存過程中迴圈遍歷一列資料的實現先講到這裡了,小編覺得遊標的使用還需要跟老大再商量,而且業務人員也不止一次的告訴我,一定會改的!親愛的朋友們,你們有沒有其他的思路呢?交流一下。