Mariadb學習總結(十二):複合語句和流程控制

複合語句linux

在MariaDB 10.1.1+版本中,咱們能夠在存儲過程之外來使用複合語句了,顧名思義,複合語句就是將多條語句做爲一個總體來執行,能夠在其中使用一些邏輯判斷,循環等功能,大大提升了SQL語言的可編程性。編程

在存儲過程之外使用複合語句須要遵照如下約定:編程語言

  • 僅可以使用BEGIN, IF, CASE, LOOP, WHILE, REPEAT語句
  • BEGIN必須使用BEGIN NOT ATOMIC,這樣不會規避autocommit
  • 不能以標籤開頭

當要使用複合語句時,可使用以下的格式來使用:事務

BEGIN [NOT ATOMIC]
    [statement_list]
END

由於SQL語句要使用;來做爲結束的標識符,可是,多條SQL語句,到底哪一個纔是結束符了?因此咱們能夠將複合語句的結束符修改成其餘字符,使用以下命令便可:|能夠替換爲任意數量的任意字符。字符串

delimiter |
//該命令在當前會話有效,會影響後續全部SQL語句的結束符

複合語句例子get

MariaDB [world]> DELIMITER ||
MariaDB [world]> BEGIN NOT ATOMIC
    -> SELECT * FROM user;
    -> SELECT * FROM department;
    -> END
    -> ||

會順序顯示兩張表的內容,可是,有什麼呢?it

嘿,都說了,增長了可編程性,還沒判斷、循環呢。io

定義本地變量test


本地變量僅在當前BEGIN..END內生效,定義一個本地變量的語法以下:變量

DECLARE var_name [, var_name] type [DEFAULT value]

type就是MariaDB中支持的那些數據類型。

好比以下例子:查詢test1用戶的組ID並放入到tmpdid變量中去

MariaDB [world]> BEGIN NOT ATOMIC
    ->     DECLARE tmpdid INT DEFAULT 0;
    ->     SELECT deptid INTO tmpdid FROM user WHERE name='test1';
    ->     SELECT tmpdid;
    ->     END|
+--------+
| tmpdid |
+--------+
|      1 |
+--------+
1 row in set (0.00 sec)

因此說,BEGIN...END是能夠嵌套使用的,如在IF語句中使用BEGIN...END來建立一個新的定義域,固然BEGIN...END也是開啓事務的標誌

IF語句

語法以下:

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

這個就跟編程語言中的同樣了,再也不絮叨,來試試吧。

BEGIN NOT ATOMIC
    DECLARE tmpdid INT DEFAULT 0;
    SELECT deptid INTO tmpdid FROM user WHERE name='test1';
    IF (tmpdid = 1) THEN 
    SELECT 'The User test1 is the member of salse';
    ELSE
    SELECT * FROM department WHERE id = tmpdid;
    END IF;
    END|

因此search_condition只要是能夠表達TRUE或FALSE的表達式都行,好比:

BEGIN NOT ATOMIC
    IF EXISTS(SELECT * FROM user WHERE name = 'lucy') THEN
    SELECT 'Find the user lucy';
    ELSE
    SELECT 'Not Find';
    END IF;
    END|
+--------------------+
| Find the user lucy |
+--------------------+
| Find the user lucy |
+--------------------+
1 row in set (0.00 sec)

CASE 語句

CASE有兩種用法,一種是像編程語言中的SWITCH同樣,進行數據的挑選,另外一種則是實現了多分支的IF-ELSE語句,語法以下:

//對某一個值進行篩選
CASE case_value
    WHEN when_value THEN statement_list
    [WHEN when_value THEN statement_list] ...
    [ELSE statement_list]
END CASE

//多分支的IF-ELSE
CASE
    WHEN search_condition THEN statement_list
    [WHEN search_condition THEN statement_list] ...
    [ELSE statement_list] 
END CASE

...想不出來例子,放棄,哪天想到了再來補吧。

附官方例子一枚:

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

LOOP語句

LOOP以前沒有用過,好像不少編程語言裏都沒有LOOP這個關鍵字了,用來實現簡單的循環,須要配合LEAVE語句跳出循環。

設置一變量,將其加到100並退出:爲啥要加到100?鬼知道,哈哈哈。

BEGIN NOT ATOMIC
     DECLARE tempNum INT DEFAULT 0;
     test:LOOP
     SET tempNum=tempNum+1;
     IF tempNum=100 THEN
     LEAVE test;
     END IF;
     END LOOP test;
     SELECT tempNum;
END;
     |

因此LOOP的語法以下:

[begin_label:] LOOP
    statement_list
END LOOP [end_label]

一般,須要設置一個begin_label,用於標識該循環,以方便使用LEAVE跳出該循環,而end_label能夠省略,可是若是想要給end_label的話,必須與begin_label的名稱相同,而LEAVE的語法就很簡單了:

LEAVE label

WHILE語句

WHILE就與編程語言中的同樣了,語法以下:

[begin_label:] WHILE search_condition DO
    statement_list
END WHILE [end_label]

當search_condition表達式不爲TRUE時則再也不執行循環。

查找某一用戶的ID值爲多少,爲何要寫個循環呢?不知道呀,用WHERE不更好嗎?

REPEAT..LOOP循環

REPEAT循環看起來很是像do...while循環,好吧,其實就是一回事。

第一次循環體不判斷任何條件執行一次,而後再判斷條件,若是條件還知足則繼續執行,直到條件不知足爲之,語法以下:

[begin_label:] REPEAT
    statement_list
UNTIL search_condition
END REPEAT [end_label]

拼接全部用戶名爲一個字符串:

MariaDB [world]> BEGIN NOT ATOMIC
    ->     DECLARE i INT DEFAULT 1;
    ->     DECLARE userNames VARCHAR(200) DEFAULT '';
    ->     DECLARE tmpName VARCHAR(10) DEFAULT '';
    ->     DECLARE userNums INT DEFAULT 0;
    ->     SELECT COUNT(id) INTO userNums FROM user;
    ->     REPEAT 
    ->         SELECT name INTO tmpName FROM user WHERE id = i;
    ->         SET userNames = CONCAT(userNames,',',tmpName);
    ->         SET i = i +1;
    ->     UNTIL NOT i< =userNums ->     END REPEAT;
    ->     SELECT userNames;
    ->     END|
+--------------------------------------------------------------------------------------------+
| userNames                                                                                  |
+--------------------------------------------------------------------------------------------+
| ,test,test1,lucy,mars,mark,test6,test7,test7,test8,test8,test9,test10,test11,test12,test13 |
+--------------------------------------------------------------------------------------------+
相關文章
相關標籤/搜索