qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

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

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

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

          CREATE OR REPLACE PROCEDURE sp_EditInlayOut(
                           FID     NUMBER,                    --修改記錄的ID T_INLAYOUT表的主鍵
                           InlayBoxIDs varchar2,          --修改的記錄
                           BoxCount number,              --裝箱數量
                           ApplyUserID varchar2,        --申請人編號
                           StoreUserID varchar2,         --庫管編號
                           ConfirmStatechar,              --確認狀態
                           ExistStatechar,                    --存在狀態
                           strErr OUT varchar2             --存儲過程執行結果。成功返回空,失敗返回錯誤原因
          )
          AS
             --定義變量
             v_Now DATE;                                     
             v_Now2 date;                                        
             v_LogID number;
             v_ChipID number;
             v_sql varchar2(2000);
          BEGIN
            
                --記錄日志
                INSERT INTO T_InlayOut_Log(F_InlayBoxIDs,f_Boxcount,f_Applyuserid,f_Storeuserid,f_Addtime,f_Confirmstate
                   ,f_Existstate, f_modifyid, f_modifytime, f_modifyuserid )
                                  ((SELECT F_InlayBoxIDs,f_Boxcount,f_Applyuserid,f_Storeuserid,f_Addtime,f_Confirmstate,f_Existstate
                                   ,FID,SYSDATE,StoreUserID FROM T_InlayOut WHERE F_ID=FID));
                --取剛插入記錄的ID
                select seq_t_inlayout_log.currval into v_LogID from dual;
                --定義游標
                 DECLARE CURSOR myCusor IS SELECT F_ID FROM T_CHIP WHERE F_InlayBoxID IN (SELECT f_ID FROM 
                 T_InlayBox where F_InlayOutID = FID);
                --開始使用游標取數據
                 BEGIN
                      OPEN myCusor;
            
                      LOOP
                          FETCH myCusor INTO v_ChipID;
                          --游標取不到數據則退出
                          EXIT WHEN myCusor%NOTFOUND;    
            
                                SELECT MIN(F_CurrentTime) INTO v_Now FROM t_Chipstatehistory WHERE
                 (F_HistoryState ='Confirm_InlayIn') AND F_ChipID = v_ChipID;
                                --改變芯片表的狀態
                                UPDATEt_chip SET f_State ='Confirm_InlayIn',F_CompareTime = v_Now  WHERE F_ID = v_ChipID;
                                --保存芯片狀態歷史記錄
                                INSERT INTO T_CHIPSTATEHISTORY(f_chipid, f_Historystate,F_TABLEID,f_Currenttime,F_TABLENAME) 
                               VALUES
                                (v_ChipID,'Confirm_InlayIn',v_LogID,SYSDATE,'T_InlayOut_Log');
            
                      END LOOP;
                      CLOSE myCusor;
                 END;
            
                --選擇最近芯片狀態變更時間
                --SELECT MIN(F_CURRENTTIME) INTO v_NOW  FROM T_CHIPSTATEHISTORY WHERE F_HISTORYSTATE = 20 
                AND F_CHIPID IN (SELECT F_ID FROM T_CHIP WHERE F_InlayBoxID=(SELECT F_ID FROM T_InlayBox 
                  WHERE F_InlayOutID=FID));
            
                --將芯片表中芯片狀態更新到以前狀態
                --UPDATE T_CHIP SET F_State=20,F_CompareTime=v_NOW WHERE F_InlayBoxID IN (SELECT F_ID FROM 
                 T_InlayBox WHERE F_InlayOutID =FID);
                --記錄芯片狀態變更日志
                --INSERT INTO  T_ChipStateHistory (F_ChipID,f_Historystate,f_Tableid,f_Currenttime,f_Tablename)VALUES
                --((SELECT F_ID FROM T_CHIP WHERE F_InlayBoxID=(SELECT F_ID FROM T_InlayBox WHERE F_InlayOutID=FID)),
                    20,v_LogID,SYSDATE,'T_InlayOut_Log');
            
            
                --將Inlay出庫箱表中以前的數據更新到以前狀態
                UPDATE T_InlayBox SET F_State=2,F_InlayOutID=nullWHERE F_InlayOutID =FID;
            
                --編輯時將新的INLAY出庫信息更新
                UPDATE T_InlayOut SET F_InlayBoxIDs=InlayBoxIDs,f_Boxcount=BoxCount,f_Applyuserid=ApplyUserID,
                f_Storeuserid=StoreUserID,f_Confirmstate=ConfirmState,F_ExistState=ExistState,F_ConfirmTime=null 
                WHERE F_ID=FID;
            
                --更新T_InlayBox 新的狀態
                --UPDATE T_InlayBox SET F_State=3,F_InlayOutID=FID WHERE F_IDin(InlayBoxIDs);
                v_sql :='UPDATE T_InlayBox SET F_State=3,F_InlayOutID='||FID||' WHERE F_ID in ('||InlayBoxIDs||')';
                 --立即執行v_sql
                EXECUTE IMMEDIATE  v_sql;
            
                SELECT SYSDATE INTO  v_Now2 FROM DUAL;
                --更新芯片表狀態
                UPDATE T_Chip SET F_State='No_Confirm_InlayOut',F_CompareTime=v_Now2  WHERE F_InlayBoxID IN
                 (SELECT F_ID FROM T_InlayBox WHERE F_InlayOutID=FID);
                --記錄當前操作日志
                INSERT INTO  T_ChipStateHistory (F_ChipID,f_Historystate,f_Tableid,f_Currenttime,f_Tablename) 
               SELECT F_ID,'No_Confirm_InlayOut',v_LogID,v_Now2,'T_InlayOut_Log'FROM T_CHIP WHERE F_InlayBoxID IN
               (SELECT F_ID FROM T_InlayBox WHERE F_InlayOutID=FID);
                 --提交
                 COMMIT;
               --發生異常時返回錯誤碼
               EXCEPTION
                  WHEN OTHERS THEN
                  strErr := substr(sqlerrm,1,100);
                  ROLLBACK;
          END sp_EditInlayOut;

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

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

          posted on 2012-04-25 13:49 順其自然EVO 閱讀(1383) 評論(0)  編輯  收藏 所屬分類: 數據庫

          <2012年4月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 宁河县| 波密县| 杨浦区| 新野县| 屯留县| 若尔盖县| 卫辉市| 察隅县| 沂源县| 旺苍县| 毕节市| 镇康县| 六盘水市| 洛南县| 广安市| 旺苍县| 佛冈县| 安陆市| 屏南县| 东阳市| 涿鹿县| 峨山| 中宁县| 灌阳县| 满洲里市| 宁城县| 印江| 鄂州市| 河池市| 吴桥县| 平武县| 徐水县| 新丰县| 昌图县| 文昌市| 云南省| 宜兰市| 当雄县| 乐至县| 五华县| 柳江县|