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 |
+--------------------------------------------------------------------------------------------+
相关文章
相关标签/搜索