如何避免使用游標
文章分類:資料庫
問題的提出
我們在根據乙個結果集的內容,處理另乙個結果集的時候,一般的會考慮到使用下面形式的游標:
游標定義
開啟游標
從游標中取第一條資料
迴圈開始,以游標取數後的狀態為迴圈控制條件
修改相關資料表的內容
從游標中取下一條資料
迴圈結束
關閉游標
上面的流程在處理的資料量比較小的時候沒有什麼問題,但如果兩個結果集的資料量比較大,那麼該游標的執行會產生大量的、長時間的鎖,可能會造成其他使用者的等待,甚至產生死鎖。
解決方案
不使用臨時表
如果作為迴圈控制條件的結果集中有可以唯一識別每一行資料的列,我們稱為關鍵列,那麼,我們可以把上面的流程改寫為下面的形式:
從結果集中取出最小關鍵列的值
以最小關鍵列值為條件,取出其他列的資料
迴圈開始,以最小關鍵列是否有值為迴圈控制條件
修改相關資料表的內容
從結果集中取出比關鍵列大的最小值
迴圈結束
該流程的優點是比游標的方式執行效率高,並且不會由於資源的占用而造成其他使用者的等待,更不會造成死鎖。
該流程的缺點是:要求作為迴圈控制條件的結果集必須有關鍵列。
使用臨時表
如果作為迴圈控制條件的結果集沒有關鍵列,我們也可以考慮把結果集儲存在臨時表中,並增加乙個關鍵列,改寫後的流程類似下面的形式:
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語句。因為游標需要遍歷結果集的每一行,增加了伺服器的負擔,導致游標的效率並不高效,如果使...