複合語句linux
在MariaDB 10.1.1+版本中,咱們能夠在存儲過程之外來使用複合語句了,顧名思義,複合語句就是將多條語句做爲一個總體來執行,能夠在其中使用一些邏輯判斷,循環等功能,大大提升了SQL語言的可編程性。編程
在存儲過程之外使用複合語句須要遵照如下約定:編程語言
當要使用複合語句時,可使用以下的格式來使用:事務
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 | +--------------------------------------------------------------------------------------------+