1. 程式人生 > >MYSQL的儲存過程和遊標的使用

MYSQL的儲存過程和遊標的使用

1、儲存過程

儲存過程是什麼,簡單來講,就像Java中的 方法(函式),不過它是SQL世界中的方法。
大部分時候,我們所使用都是單條SQL,用來針對一個或多表連線。但是也有情況,是據判斷先對錶A執行操作,變動後再結合表B進行操作。即SQL的執行可能需要 考慮包含業務規則在內的智慧處理。封裝操作的好處就不過多說明,無非是簡化,複用,降低耦合等,同時,它還具有更高的效能。
考慮這種業務情況,現在你需要獲得訂單總額,但同時需要增加營業稅,且只針對某些顧客,那麼你需要:
  • 獲得基本的訂單總額
  • 將營業稅有條件地新增到合計中
  • 返回合計

1.1 基本語句

先看基本的語句,然後再看示例,就豁然開朗了:

   
  1. --建立儲存過程
  2. CREATE PROCEDURE <儲存過程的名稱>(<變數的型別定義>)
  3. BEGIN
  4. <執行操作>
  5. END;
  6. --執行儲存過程
  7. CALL <儲存過程的名稱>(<@變數名>);
  8. --刪除儲存過程
  9. DROP PROCEDURE <儲存過程的名稱>;

1.2 建立

然後,根據剛才我們說到的返回包含營業稅的訂單總額,建立如下儲存過程:

   
  1. -- Name: ordertotal
  2. -- Parameters: onumber = order number
  3. -- taxable = 0 if not taxable, 1 if taxable
  4. -- ototal = order total variable
  5. CREATE PROCEDURE ordertotal(
  6. IN onumber INT,
  7. IN taxable BOOLEAN,
  8. OUT ototal DECIMAL
    (8, 2)
  9. ) COMMENT 'Obtain order total, optionally adding tax'
  10. BEGIN
  11. --Declare variable for total
  12. DECLARE total DECIMAL(8, 2);
  13. --Declare tax percentage
  14. DECLARE taxrate INT DEFAULT 6;
  15. --GET the order total
  16. SELECT Sum(item_price*quantity)
  17. FROM orderitems
  18. WHERE order_num = onumber
  19. INTO total;
  20. --Is this taxable
  21. IF taxable THEN
  22. SELECT total+(total/100*taxrate) INTO total;
  23. END IF;
  24. SELECT total INTO ototal;
  25. END;

看起來這麼長好像挺唬人,其實很清楚:

   
  1. CREATE PROCEDURE ordertotal(
  2. IN onumber INT,
  3. IN taxable BOOLEAN,
  4. OUT ototal DECIMAL(8, 2)
  5. ) COMMENT 'Obtain order total, optionally adding tax'
  • 使用CREATE PROCEDURE關鍵詞建立了名為ordertotal的儲存過程
  • 該儲存過程定義了三個變數,IN表示要求輸入的引數,OUT表示輸出的結果。INT、BOOLEAN等表示變數的資料型別
  • COMMENT非必需,如果有,那麼在SHOW PROCEDURE STATUS的結果時會顯示(簡單說,類似於方法的說明)

  1. BEGIN
  2. ...
  3. END;
  • BEGIN和END用來界定儲存過程操作執行的語句

  
  1. --Declare variable for total
  2. DECLARE total DECIMAL(8, 2);
  3. --Declare tax percentage
  4. DECLARE taxrate INT DEFAULT 6;
  5. --GET the order total
  6. SELECT Sum(item_price*quantity)
  7. FROM orderitems
  8. WHERE order_num = onumber
  9. INTO total;
  • DECLARE用來定義儲存過程中的區域性變數
  • INTO表示賦值到變數

   
  1. --Is this taxable
  2. IF taxable THEN
  3. SELECT total+(total/100*taxrate) INTO total;
  4. END IF;
  • IF <boolean> THEN <do something> END IF 為條件執行語句,記得END IF結尾

假如用Java來寫的話,大概是這麼個意思:

   
  1. public void ordertotal(int onumber, boolean taxable, double ototal) {
  2. double total;
  3. int taxrate = 6;
  4. total = getOrderTotal(onumber);
  5. if (taxable) {
  6. total += total / (100 * taxrate);
  7. }
  8. ototal = total;
  9. }

1.3 執行

在1.2我們定義了儲存過程ordertotal(),則執行方式為:

   
  1. --不含營業稅
  2. CALL ordertotal(20005, 0, @total);
  3. SELECT @total
  4. +----------+
  5. | @total |
  6. +----------+
  7. | 149.87 |
  8. +----------+
  9. --包含營業稅
  10. CALL ordertotal(20005, 1, @total);
  11. SELECT @total
  12. +-----------------+
  13. | @total |
  14. +-----------------+
  15. | 158.862200000 |
  16. +-----------------+

定義時我們說過,IN表示定義輸入,OUT表示定義輸出,所以這裡的三個變數中,前兩者由呼叫者傳入,而第三個變數,則作為返回結果的變數。 ( 呼叫儲存過程時,用於臨時儲存返回資料的變數必須以@開頭

1.4 檢查

用來顯示“建立某個儲存過程的CREATE語句”,使用SHOW CREATE PROCEDURE語句:

   
  1. SHOW CREATE PROCEDURE ordertotal;

1.5 刪除


   
  1. DROP PROCEDURE ordertotal;
注意,檢查和刪除儲存過程,都不用加後面的(),只需要給出儲存過程的名稱即可。


2、遊標

在檢索出來的行中,前進或者後退一行或多行,就需要用到所謂的“遊標”。遊標不是某個SELECT語句,但是它是被該 語句檢索出來的結果集,另外, MySQL遊標只能用於儲存過程(和函式)。

2.1 建立遊標

使用 DECLARECURSOR關鍵字:

   
  1. CREATE PROCEDURE processorders()
  2. BEGIN
  3. DECLARE ordernumbers CURSOR
  4. FOR
  5. SELECT order_num FROM orders;
  6. END;

2.2 開啟和關閉遊標

因為遊標侷限於儲存過程,所以如果儲存過程處理完成後,遊標就會消失。所以往往在儲存過程中要關鍵字 OPEN進行開啟。另,遊標相關的SELECT查詢語句,在定義時是不執行的,在OPEN時才執行查詢,儲存檢索出的資料以供瀏覽和滾動。在遊標使用完成後,使用 CLOSE進行關閉:

   
  1. CREATE PROCEDURE processorders()
  2. BEGIN
  3. --Declare
  4. DECLARE ordernumbers CURSOR
  5. FOR
  6. SELECT order_num FROM orders;
  7. --Open
  8. OPEN ordernumbers;
  9. --Close
  10. CLOSE ordernumbers;
  11. END;