iT邦幫忙

DAY 17
3

只談MySQL系列 第 17

只談MySQL (第17天) MySQL Programming Language

昨天談到MySQL的Stored Procedure及Function, 既然談到Procedure及Function, 就一定要介紹MySQL的程式設計及語法, 才能算是完整有用的分享..今天, 我們就來討論MySQL的程式語言...
在MySQL中, 把Procedure和Function統稱為Routine, 我們今天將討論Routine中的變數宣告、流程控制及Return等三個部份, 明天再討論CURSORS.

  1. Routine的變數宣告與指派變數值
    我們舉例說明:

    CREATE PROCEDURE dorepeat(p1 INT)
    BEGIN
    DECLARE @x int;
    SET @x = 0;
    REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT;
    END

這個例子, 我們昨天也有提出, 但昨天沒有用到DECLARE指令, 那麼不用DECLARE行不行? 可以, 但是, 應該先宣告變數名稱及其資料型態, 再指派變數值, 是比較良好的程式設計習慣. 另外, 也有一個SET指令, 這是指派變數值的指令, SET指令很容易瞭解.
DECLARE指令必需在BEGIN....END區塊內使用, 不能放區塊外, 否則會有錯誤訊息, DECLARE指令還可以這樣用:

DECLARE @NAME VARCHAR(40) DEFAULT 'New Commer';
DECLARE @X int DEFAULT 0;

指定預設值, 否則宣告完會先存放空值(NULL).
是否在變數前要加個'@'符號呢? 這只是個人寫程式的習慣, 用來變識出告的區域變數, 不然在同一支Routine中如下使用

DECLARE NAME VARCHAR(40);
SELECT NAME FROM CUSTOMER;

這兩個NAME就會造成小小的困擾. 變數值的指派也可以直在SELECT指令中完成

SELECT NAME INTO @NAME FROM CUSTOMER WHERE CID='10001';

這樣會把CUSTOMER資料表中客戶編'10001'的NAME欄位值放到變數@NAME中
另外, 兩個'@'放在一起是指系統變數..
例如:

SET @@local.sort_buffer_size=10000;

@@local即為系統變數群, 另一個常看見的是@@global, 我們改天再來分享系統變數的細節
2. 流程控制指令
MySQL提供完整的流程控制指令
2.1 IF
條件判斷指令, 語法如下

IF search_condition THEN statement_list
    [ELSEIF search_condition THEN statement_list] ...
    [ELSE statement_list]
END IF

2.2. CASE

CASE case_value
    WHEN when_value THEN statement_list
    [WHEN when_value THEN statement_list] ...
    [ELSE statement_list]
END CASE

例如:

CREATE PROCEDURE p()
  BEGIN
    DECLARE v INT DEFAULT 1;
    CASE v
      WHEN 2 THEN SELECT v;
      WHEN 3 THEN SELECT 0;
      ELSE
        BEGIN
          SET v = 5;
        END;
    END CASE;
  END;

最後v值為5
2.3. LOOP
語法:

[begin_label:] LOOP
    statement_list
END LOOP [end_label]

MySQL的LOOP語法沒有提供離開迴圈的條件, 而是要配合下一個LEAVE指令的執行離開LOOP, 例子就在LEAVE中討論了, 在這裏先提醒的是: end_label必需要在有begin_label時才能存在, 而且end_label要和begin_label相同
2.4. LEAVE
語法很簡單

LEAVE label

舉個子來說:

DECLARE @NAME VARCHAR(40) DEFAULT 'New Commer';
DECLARE @X int DEFAULT 0;

0
當@X值大於100時, 離開LOOP
2.5. ITERATE
ITERATE和LEAVE功能正好相反, 舉例來說

DECLARE @NAME VARCHAR(40) DEFAULT 'New Commer';
DECLARE @X int DEFAULT 0;

1
當p1的值小於10, 就繼續在LOOP中處理, 否則離開LOOP...ITERATE的意思就是直接跳回到LOOP中的第一條指令做下去.
2.6. REPEAT
語法為

DECLARE @NAME VARCHAR(40) DEFAULT 'New Commer';
DECLARE @X int DEFAULT 0;

2
舉例來說

DECLARE @NAME VARCHAR(40) DEFAULT 'New Commer';
DECLARE @X int DEFAULT 0;

3
也是昨天舉的例子, 記得用DELIMITER指令先宣告分隔字元, 再建立Procedure
這個例子會持續迴圈直到@x值大於p1
2.7. WHILE
語法

DECLARE @NAME VARCHAR(40) DEFAULT 'New Commer';
DECLARE @X int DEFAULT 0;

4
舉例如下:

DECLARE @NAME VARCHAR(40) DEFAULT 'New Commer';
DECLARE @X int DEFAULT 0;

5
當v1值小於或等於0時, 離開迴圈. 和REPEAT不同的是, WHILE先判斷條件, 條件滿足才繼續, REPEAT會先做一次再判斷條件...
3. RETURN
RETURN指令只能用在CREATE FUNCTION中, 其他像是CREATE PROCEDURE、CREATE TRIGGER、CREATE EVENT都不能放入RETURN指令, 否則編譯錯誤
例如:

DECLARE @NAME VARCHAR(40) DEFAULT 'New Commer';
DECLARE @X int DEFAULT 0;

6
是宣告名稱為hello的函數, 有一個參數s, 其型能為CHAR(20), hello函數回傳值的型態為CHAR(50), 回傳的內容是CONCAT('Hello, ',s,'!')
所以

DECLARE @NAME VARCHAR(40) DEFAULT 'New Commer';
DECLARE @X int DEFAULT 0;

7
此時變數@x_string的內容為'hell world!'.

我們今天討論到這裏, 明天我們再詳細討論CURSORS...


上一篇
只談MySQL (第16天) Stored Procedure及Function
下一篇
只談MySQL (第18天) Cursors...
系列文
只談MySQL30

1 則留言

0
lovex
iT邦新手 5 級 ‧ 2011-10-26 07:11:26

請問一下

0~6的程式碼範例好像都一樣....是我不了解您的用意嗎?

賽門 iT邦超人 1 級‧ 2011-10-26 08:36:38 檢舉

好像有問題..這不是我當初的PO...我再找看看原稿在不在來修訂...

我要留言

立即登入留言