程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle數據庫基礎 >> Oracle數據庫游標在存儲過程中的使用

Oracle數據庫游標在存儲過程中的使用

編輯:Oracle數據庫基礎

作為關系型數據庫市場的老大,Oracla占有舉足輕重的地位。雖然在操作上不如SQLSERVER那樣方便,但是他的強大的功能<br>還是吸引來大批大批的追隨著。本人作為ORACLE菜鳥,在工作當中也偶爾使用Oracle。以下記錄的上由於工作需要寫的Oracle的<br>使用游標的儲存過程,個人覺得比較有代表性。希望給初學者一定的幫助,也給自己加深一下印象。

在ORACLE中,他以一個語句塊為一個默認的事務。也就是說,如果你就單單只執行一段Oracle的語句塊,他默認是以事務的形式執行的。

01 CREATE OR REPLACE PROCEDURE sp_EditInlayOut( 02                  FID     NUMBER,                    --修改記錄的ID T_INLAYOUT表的主鍵 03                  InlayBoxIDs varchar2,          --修改的記錄 04                  BoxCount number,              --裝箱數量 05                  ApplyUserID varchar2,        --申請人編號 06                  StoreUserID varchar2,         --庫管編號 07                  ConfirmState char,              --確認狀態 08                  ExistState char,                    --存在狀態 09                  strErr OUT varchar2             --存儲過程執行結果。成功返回空,失敗返回錯誤原因 10 ) 11 AS 12    --定義變量 13    v_Now DATE;                                      14    v_Now2 date;                                         15    v_LogID number; 16    v_ChipID number; 17    v_sql varchar2(2000); 18 BEGIN 19    20       --記錄日志 21       INSERT INTO T_InlayOut_Log(F_InlayBoxIDs,f_Boxcount,f_Applyuserid,f_Storeuserid,f_Addtime,f_Confirmstate 22          ,f_Existstate, f_modifyid, f_modifytime, f_modifyuserid ) 23                         ((SELECT F_InlayBoxIDs,f_Boxcount,f_Applyuserid,f_Storeuserid,f_Addtime,f_Confirmstate,f_Existstate 24                          ,FID,SYSDATE,StoreUserID FROM T_InlayOut WHERE F_ID=FID)); 25       --取剛插入記錄的ID 26       select seq_t_inlayout_log.currval into v_LogID from dual; 27       --定義游標 28        DECLARE CURSOR myCusor IS SELECT F_ID FROM T_CHIP WHERE F_InlayBoxID IN (SELECT f_ID FROM  29        T_InlayBox where F_InlayOutID = FID); 30       --開始使用游標取數據 31        BEGIN 32             OPEN myCusor; 33    34             LOOP 35                 FETCH myCusor INTO v_ChipID; 36                 --游標取不到數據則退出 37                 EXIT WHEN myCusor%NOTFOUND;     38    39                       SELECT MIN(F_CurrentTime) INTO v_Now FROM t_Chipstatehistory WHERE 40        (F_HistoryState = 'Confirm_InlayIn') AND F_ChipID = v_ChipID; 41                       --改變芯片表的狀態 42                       UPDATEt_chip SET f_State = 'Confirm_InlayIn',F_CompareTime = v_Now  WHERE F_ID = v_ChipID; 43                       --保存芯片狀態歷史記錄 44                       INSERT INTO T_CHIPSTATEHISTORY(f_chipid, f_Historystate,F_TABLEID,f_Currenttime,F_TABLENAME)  45                      VALUES 46                       (v_ChipID,'Confirm_InlayIn',v_LogID,SYSDATE,'T_InlayOut_Log'); 47    48             END LOOP; 49             CLOSE myCusor; 50        END; 51    52       --選擇最近芯片狀態變更時間 53       --SELECT MIN(F_CURRENTTIME) INTO v_NOW  FROM T_CHIPSTATEHISTORY WHERE F_HISTORYSTATE = 20  54       AND F_CHIPID IN (SELECT F_ID FROM T_CHIP WHERE F_InlayBoxID=(SELECT F_ID FROM T_InlayBox  55         WHERE F_InlayOutID=FID)); 56    57       --將芯片表中芯片狀態更新到以前狀態 58       --UPDATE T_CHIP SET F_State=20,F_CompareTime=v_NOW WHERE F_InlayBoxID IN (SELECT F_ID FROM  59        T_InlayBox WHERE F_InlayOutID =FID); 60       --記錄芯片狀態變更日志 61       --INSERT INTO  T_ChipStateHistory (F_ChipID,f_Historystate,f_Tableid,f_Currenttime,f_Tablename)VALUES 62       --((SELECT F_ID FROM T_CHIP WHERE F_InlayBoxID=(SELECT F_ID FROM T_InlayBox WHERE F_InlayOutID=FID)), 63           20,v_LogID,SYSDATE,'T_InlayOut_Log'); 64    65    66       --將Inlay出庫箱表中以前的數據更新到以前狀態 67       UPDATE T_InlayBox SET F_State=2,F_InlayOutID=null WHERE F_InlayOutID =FID; 68    69       --編輯時將新的INLAY出庫信息更新 70       UPDATE T_InlayOut SET F_InlayBoxIDs=InlayBoxIDs,f_Boxcount=BoxCount,f_Applyuserid=ApplyUserID, 71       f_Storeuserid=StoreUserID,f_Confirmstate=ConfirmState,F_ExistState=ExistState,F_ConfirmTime=null  72       WHERE F_ID=FID; 73    74       --更新T_InlayBox 新的狀態 75       --UPDATE T_InlayBox SET F_State=3,F_InlayOutID=FID WHERE F_ID in (InlayBoxIDs); 76       v_sql := 'UPDATE T_InlayBox SET F_State=3,F_InlayOutID='||FID||' WHERE F_ID in ('||InlayBoxIDs||')'; 77        --立即執行v_sql 78       EXECUTE IMMEDIATE  v_sql; 79    80       SELECT SYSDATE INTO  v_Now2 FROM DUAL; 81       --更新芯片表狀態 82       UPDATE T_Chip SET F_State='No_Confirm_InlayOut',F_CompareTime=v_Now2  WHERE F_InlayBoxID IN 83        (SELECT F_ID FROM T_InlayBox WHERE F_InlayOutID=FID); 84       --記錄當前操作日志 85       INSERT INTO  T_ChipStateHistory (F_ChipID,f_Historystate,f_Tableid,f_Currenttime,f_Tablename)  86      SELECT F_ID,'No_Confirm_InlayOut',v_LogID,v_Now2,'T_InlayOut_Log' FROM T_CHIP WHERE F_InlayBoxID IN 87      (SELECT F_ID FROM T_InlayBox WHERE F_InlayOutID=FID); 88        --提交 89        COMMIT; 90      --發生異常時返回錯誤碼 91      EXCEPTION 92         WHEN OTHERS THEN 93         strErr := substr(sqlerrm,1,100); 94         ROLLBACK; 95 END sp_EditInlayOut;

 

 

   但是在SQLSERVER中,除非你將所有的T-SQL語句塊以顯示的方式【BEGIN TRANSACTION ....END TRANSACTION】申明在事務中,否則SQLSERVER會將語句塊中的每一句作為一個單獨的默認事務執行。

  此外,游標是一種比較占I/O資源的操作,使用完後應該及時關閉,以釋放系統資源。  

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved