1. 程式人生 > >【sql】-儲存過程實現迴圈遍歷一列資料

【sql】-儲存過程實現迴圈遍歷一列資料

前言

     專案中要實現前端頁面動態配置行為,每個行為呼叫不同的儲存過程的功能,於是乎小編一頭扎進了儲存過程的海洋中,愈發覺得之前寫的儲存過程算是基礎了。遇到一個問題:查詢到表中一列資料,需要取出每一行資料來執行下一個儲存過程。這可怎麼鬧?別急,小編來給你支招。

正文

     邏輯:第一次取第一行記錄,第二次取第二行記錄,第三次取第三行記錄……

方法一 :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-- 釋放遊標

遊標在使用的時候會吃掉很多記憶體,增加程式碼量,程式執行速度變慢,這個邪惡的小遊標 ! 當資料量不大的時候,可以使用遊標。

遊標小課堂

什麼是遊標?

遊標可以被看作指向結果集中一行的指標。遊標每個時間點只能指向一行,但是可以根據需要指向結果集中的其他行。

遊標的作用?

  1. 指定結果集中特定行的位置;
  2. 基於當前結果檢索一行或連續的幾行;
  3. 在結果集的當前位置修改行中的資料;

遊標什麼時候用?

從一個結果集中迴圈遍歷資料進行相同或者不同的操作,而不是一次對整個結果集進行同一種操作;

總結

    儲存過程中迴圈遍歷一列資料的實現先講到這裡了,小編覺得遊標的使用還需要跟老大再商量,而且業務人員也不止一次的告訴我,一定會改的!親愛的朋友們,你們有沒有其他的思路呢?交流一下。

相關推薦

no