如何避免使用游標

2021-08-31 02:43:13 字數 1133 閱讀 5807

如何避免使用游標

文章分類:資料庫

問題的提出

我們在根據乙個結果集的內容,處理另乙個結果集的時候,一般的會考慮到使用下面形式的游標:

游標定義

開啟游標

從游標中取第一條資料

迴圈開始,以游標取數後的狀態為迴圈控制條件

修改相關資料表的內容

從游標中取下一條資料

迴圈結束

關閉游標

上面的流程在處理的資料量比較小的時候沒有什麼問題,但如果兩個結果集的資料量比較大,那麼該游標的執行會產生大量的、長時間的鎖,可能會造成其他使用者的等待,甚至產生死鎖。

解決方案

不使用臨時表

如果作為迴圈控制條件的結果集中有可以唯一識別每一行資料的列,我們稱為關鍵列,那麼,我們可以把上面的流程改寫為下面的形式:

從結果集中取出最小關鍵列的值

以最小關鍵列值為條件,取出其他列的資料

迴圈開始,以最小關鍵列是否有值為迴圈控制條件

修改相關資料表的內容

從結果集中取出比關鍵列大的最小值

迴圈結束

該流程的優點是比游標的方式執行效率高,並且不會由於資源的占用而造成其他使用者的等待,更不會造成死鎖。

該流程的缺點是:要求作為迴圈控制條件的結果集必須有關鍵列。

使用臨時表

如果作為迴圈控制條件的結果集沒有關鍵列,我們也可以考慮把結果集儲存在臨時表中,並增加乙個關鍵列,改寫後的流程類似下面的形式:

create table #temp(tempid int identity(1,1) not null,結果集其他列)

將結果集的資料插入到臨時表

從臨時表中取出最小關鍵列的值

以最小關鍵列值為條件,取出其他列的資料

迴圈開始,以最小關鍵列是否有值為迴圈控制條件

修改相關資料表的內容

從臨時表中取出比關鍵列大的最小值

迴圈結束

該流程的優點是比游標的方式執行效率高,並且不會由於資源的占用而造成其他使用者的等待,更不會造成死鎖。

該流程的缺點是:如果臨時表中記錄數量比較大,比如上千條,那麼該方法的效率可能不是很好,因為臨時表也是 tempdb 資料庫上的物理表,並且沒有索引,所以大資料量的臨時表的效率是不會很高的。

使用游標 引數游標

參游標是指帶有引數的游標。在定義了引數游標之後,當使用不同引數值多次開啟游標時,可以生成不同的結果集。定義引數游標的語法如下 cursor cursor name parameter name datetype is select statement 注意,當定義引數游標時,游標引數只能指定資料型別...

使用游標 游標FOR迴圈

游標for迴圈是在pl sql塊中使用游標最簡單的方式,它簡化了對游標的處理。當使用游標for迴圈時,oracle會隱含的開啟游標,提取游標資料並關閉游標。例子 顯示emp表所有雇員名及其工資 declare cursor emp cursor isselect ename,sal from emp...

MYSQL使用游標

一 使用游標 一 宣告游標。delare cursor name cursor for select statement 解釋 cursor name是游標的名字 select statement表示select語句。因為游標需要遍歷結果集的每一行,增加了伺服器的負擔,導致游標的效率並不高效,如果使...