㈠ 請寫出遊標和存儲過程的概念及其在資料庫編程中發揮什麼樣的作用
轉載
以下記錄的上由於工作需要寫的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 al;
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資源的操作,使用完後應該及時關閉,以釋放系統資源。
㈡ 存儲過程為什麼要用游標,什麼情況下使用游標
游標一般用於把通過腳本得到的結果集的內容在用於其它的SQL語句中。但是游標執行會影響腳本執行速度,所以使用時請慎重。 在存儲過程或觸發器中使用 SQL 游標的典型過程為: 聲明SQL 變數包含游標返回的數據。為每個結果集列聲明一個變數。聲明足夠大的變數來保存列返回的值,並聲明變數的類型為可從列數據類型隱式轉換得到的數據類型。
使用 DECLARE CURSOR 語句將 SQL 游標與 SELECT 語句相關聯。另外,DECLARE CURSOR 語句還定義游標的特性,例如游標名稱以及游標是只讀還是只進。
使用 OPEN 語句執行 SELECT 語句並填充游標。
使用 FETCH INTO 語句提取單個行,並將每列中的數據移至指定的變數中。然後,其他 SQL 語句可以引用那些變數來訪問提取的數據值。SQL 游標不支持提取行塊。
使用 CLOSE 語句結束游標的使用。關閉游標可以釋放某些資源,例如游標結果集及其對當前行的鎖定,但如果重新發出一個 OPEN 語句,則該游標結構仍可用於處理。由於游標仍然存在,此時還不能重新使用該游標的名稱。DEALLOCATE 語句則完全釋放分配給游標的資源,包括游標名稱。釋放游標後,必須使用 DECLARE 語句來重新生成游標。
請採納。
㈢ 游標屬於存儲過程嗎
存儲過程就是可以傳入參數進行一定的內部運算,然後再傳出結果,比視圖要復雜點,但功能會很多的。。游標就是在存儲過程中,會對中間表的每一行數據進行讀取,然後其他操作,現在一般不講究游標了,基本上游標都可以用別的代替,可以多用連接
㈣ 存儲過程跟游標之間有什麼關聯么
兩者沒有什麼必然的聯系
游標一般不單獨使用,可以在存儲過程\函數等中使用,使用完後要關閉釋放。
存儲過程可以是一個對象,存儲起來,下次再調用。
㈤ 6、什麼是存儲過程什麼是游標,何時使用、何時不用游標
存儲過程是一組命名了的SQL語句集合,是為了完成特定功能匯集而成的。該集合編譯後存放在資料庫中,可根據實際情況重新編譯,可直接運行,也可遠程運行且存儲過程直接在伺服器端運行。
游標實際上是一種能從包括多條數據記錄的結果集(結果集是select查詢之後返回的所有行數據的集合)中每次提取一條記錄的機制充當指針的作用,遍歷結果中的所有行,但他一次只指向一行。
游標在循環處理欄位的時候使用
建議:盡量避免使用游標,因為游標的效率較差,如果游標操作的數據超過1萬行,那麼就應該考慮改寫;使用基於游標的方法或臨時表方法之前,應先尋找基於集的解決方案來解決問題,基於集的方法通常更有效;與臨時表一樣,游標並不是不可使用。
㈥ 存儲過程中用什麼可以替代游標
Mysql存儲過程優化——使用臨時表代替游標。
Mysql游標在操作小數據量時比較方便,效率可觀,但操作大數據量,速度比較慢,甚至直接產生系統錯誤。
一般說來,當操作的數據超過1萬條時,就避免用游標吧。
為了測試游標性能,寫了下面一個游標對IDC_Gather_Info表中數據進行遍歷
1.數據量15萬,執行成功,耗時8.928s
2.數據量5萬,執行成功,耗時2.994s
3.數據量1萬,執行成功,耗時0.634s
可以看到Mysql的游標在處理大一點的數據量時還是比較乏力的,僅適合用於操作幾百上千的小數據量。
㈦ 在存儲過程中,為了在一個結果集的記錄中進行循環,除了用游標還能用其他的方式嗎
臨時表 或表變數都可以 例如:sqlserver資料庫,你的結果集為 T_Table
if object_id('tempdb..#tmp') > 0
drop table #tmp
declare @ID int
select identity(int,1,1) as ID,* from T_Table
select @ID = 1
while Exists(select * from #tmp)
begin
select @變數 = 欄位 from #tmp where id = @id
select @ID = @ID + 1
end
將臨時表 換成表變數也可以
不用游標可以避免 游標的釋放問題和游標重名的問題。
如果只是為了速度 就無所謂了,游標的性能沒有大家說的那麼差,關鍵就看你怎麼寫就是了
沒有環境,自己調整一下吧
㈧ 存儲過程,如果不用游標,可以用什麼代替
少用游標。盡量用一條sql語句代替。或者用多條SQL語句分批處理。有時間多看看開窗語句,很實用。
㈨ db2的存儲過程的游標cursor怎麼替換
db2的存儲過程的游標cursor替換的解決方法如下:
在sql server 里可以用 臨時表,表變數等 .
可以將復合條件的記錄都插入到臨時表,然後再用 update 等語句對臨時表進行計算.
最後將臨時表的數據插入到正式表.
其實你這個需求 ,是可以不用觸發器的.
多寫幾個 insert ,update 就是了。存儲過程中不是非要用游標啊,他有輸入和輸出參數,只要在過程中做相應的處理就會返回輸出參數。游標的作用主要是為了循環提取數據,游標分隱性游標和顯性游標。 舉個例子(顯性游標): cursor 游標名 is select 語句; while 游標名% found loop end loop;其中的select 語句提取的是一列值,然後每次取一個進行下面的循環。 (隱性游標): for 游標名 in (select 語句)loop end loop;其中的select 語句提取的也是一列值,然後每次取一個進行下面的循環。
㈩ oracle 游標能用別的替換或者如何使游標的
你說的資料上說的盡量不使用游標,那就是使用動態sql+execute immediate的方式了。這主要是程序設計上的問題,比如說一些表名或者欄位名,可以使用變數來代替,這樣寫程序的時候麻煩點,但是方便日後維護。取數據用游標沒什麼錯誤,看你的存儲過程,重要的是還是優化sql。或者可以使用bulk collect 批量的方式取數據。