MySQL使用游標數據實例教程

使用游標數據

在一個游標被打開后,可以使用 FETCH 語句分別訪問它的每一行。FETCH 指定檢索什么數據(所需的列),檢索出來的數據存儲在什么地方。它還向前移動游標中的內部行指針,使下一條 FETCH 語句檢索下一行(不重復讀取同一行)。

第一個例子從游標中檢索單個行(第一行):

輸入:

create?procedure?processorders()  BEGIN  --?declare?local?variables  declare?o?int;  --?declare?the?cursor  declare?ordernumbers?cursor  for  select?order_num?from?orders:  --?open?the?cursor  open?ordernumbers;  --?get?order?number  fetch?ordernumbers?into?o;  --?close?the?cursor  close?ordernumbers;  end;

分析:其中 FETCH 用來檢索當前行的 order_num 列(將自動從第一行開始)到一個名為 o 的局部聲明的變量中。對檢索出的數據不做任何處理。

在下一個例子中,循環檢索數據,從第一行到最后一行:

輸入:

create?procedure?processorders()  BEGIN  --?declare?local?variables  declare?done?boolean?default?0;  declare?o?int;  --?declare?the?cursor  declare?ordernumbers?cursor  for  select?order_num?from?orders:  --declare?continue?handler  declare?continue?handler?for?sqlstate?'02000'?set?done?=?1;  --?open?the?cursor  open?ordernumbers;  --loop?through?all?rows  repeat  --?get?order?number  fetch?ordernumbers?into?o;  --?end?of?loop  until?done?end?repeat;  --?close?the?cursor  close?ordernumbers;  end;

分析:與前一個例子一樣,這個例子使用 FETCH 檢索當前 order_num到聲明的名為 o 的變量中。但與前一個例子不一樣的是,這個例子中的 FETCH 是在 REPEAT 內,因此它反復執行直到 done 為真(由 UNTILdone END REPEAT; 規定)。為使它起作用,用一個 DEFAULT 0 (假,不結束)定義變量 done 。那么, done 怎樣才能在結束時被設置為真呢?答案是用以下語句:

declare?continue?handler?for?sqlstate?'02000'?set?done?=?1;

這條語句定義了一個 CONTINUE HANDLER ,它是在條件出現時被執行的代碼。這里,它指出當 SQLSTATE ‘02000’ 出現時, SET done=1。SQLSTATE ‘02000’ 是一個未找到條件,當 REPEAT 由于沒有更多的行供循環而不能繼續時,出現這個條件。

MySQL的錯誤代碼 關于MySQL 5使用的MySQL錯誤代碼列表,請參閱http://dev.mysql.com/doc/mysql/en/error-handling.html。

DECLARE 語句的次序 DECLARE 語句的發布存在特定的次序。用 DECLARE 語句定義的局部變量必須在定義任意游標或句柄之前定義,而句柄必須在游標之后定義。不遵守此順序將產生錯誤消息。

如果調用這個存儲過程,它將定義幾個變量和一個 CONTINUE HANDLER ,定義并打開一個游標,重復讀取所有行,然后關閉游標。如果一切正常,你可以在循環內放入任意需要的處理(在 FETCH 語句之后,循環結束之前)。

重復或循環? 除這里使用的 REPEAT 語句外,MySQL還支持循環語句,它可用來重復執行代碼,直到使用 LEAVE 語句手動退出為止。通常 REPEAT 語句的語法使它更適合于對游標進行循環。

為了把這些內容組織起來,下面給出我們的游標存儲過程樣例的更進一步修改的版本,這次對取出的數據進行某種實際的處理:

輸入:

create?procedure?processorders()  BEGIN  --?declare?local?variables  declare?done?boolean?default?0;  declare?o?int;  declare?t?decimal(8,2);  --?declare?the?cursor  declare?ordernumbers?cursor  for  select?order_num?from?orders;  --?declare?continue?handler  declare?continue?handler?for?sqlstate?'02000'?set?done?=?1;  --?create?a?table?to?store?the?results  create?table?if?not?exists?ordertotals  (order_num?int,?total?decimal(8,2));  --?open?the?cursor  open?ordernumbers;  --?loop?through?all?rows  repeat  --?get?order?number  fetch?ordernumbers?into?o;  --?get?the?total?for?this?order  call?ordertotal(o,1,t);  --?insert?order?and?total?into?ordertotals  insert?into?ordertotals(order_num,total)  values(o,t);  --?end?of?loop  until?done?end?repeat;  --?close?the?cursor  close?ordernumbers;  END;

分析:在這個例子中,我們增加了另一個名為 t 的變量(存儲每個訂單的合計)。此存儲過程還在運行中創建了一個新表(如果它不存在的話),名為 ordertotals 。這個表將保存存儲過程生成的結果。 FETCH像以前一樣取每個 order_num ,然后用 CALL 執行另一個存儲過程(我們在前一章中創建)來計算每個訂單的帶稅的合計(結果存儲到 t )。最后,用 INSERT 保存每個訂單的訂單號和合計。

此存儲過程不返回數據,但它能夠創建和填充另一個表,可以用一條簡單的 SELECT 語句查看該表:

輸入:

select?*?from?ordertotals;

輸出:

MySQL使用游標數據實例教程

這樣,我們就得到了存儲過程、游標、逐行處理以及存儲過程調用其他存儲過程的一個完整的工作樣例。

? 版權聲明
THE END
喜歡就支持一下吧
點贊15 分享