MySQL全面瓦解20:可程式設計性之流程控制語句

itread01 2021-01-22 16:16:38
Mysql 全面 程式 瓦解 之流


背景

說到流程控制語句,我們在程式語法中用的比較多,比如C#的if..else...,while...,?: 等。同樣的,在MySQL中,也有一些流程控制的語法,方便我們在寫函式、儲存過程的時候對邏輯進行控制和處理。

常見的過程式SQL語句可以用在儲存過程或者函式體中。其中包括:IF函式、IF條件語句、CASE語句、LOOP語句、WHILE語句、REPEAT語句、LEAVE語句和ITERATE語句,它們極大的方便了我們進行流程控制。

下面我們一個一個來看。

流程語句分解

資料基礎

 1 mysql> select * from students; 2 +-----------+-------------+-------+---------+-----+ 3 | studentid | studentname | score | classid | sex | 4 +-----------+-------------+-------+---------+-----+ 5 | 1 | brand | 105.5 | 1 | 1 | 6 | 2 | helen | 98.5 | 1 | 0 | 7 | 3 | lyn | 97 | 1 | 0 | 8 | 4 | sol | 97 | 1 | 1 | 9 | 5 | b1 | 89 | 2 | 1 |10 | 6 | b2 | 90 | 2 | 1 |11 | 7 | c1 | 76 | 3 | 0 |12 | 8 | c2 | 73.5 | 3 | 0 |13 | 9 | lala | 73 | 0 | 0 |14 | 10 | A | 100 | 3 | 1 |15 | 16 | test1 | 100 | 0 | 1 |16 | 17 | trigger2 | 107 | 0 | 1 |17 | 22 | trigger1 | 100 | 0 | 0 |18 +-----------+-------------+-------+---------+-----+19 13 rows in set20 21 mysql> select * from scores;22 +-----------+---------+-------+23 | scoregrad | downset | upset |24 +-----------+---------+-------+25 | A | 81 | 90 |26 | B | 71 | 80 |27 | C | 61 | 70 |28 | D | 51 | 60 |29 | S | 91 | 100 |30 | S+ | 101 | 120 |31 +-----------+---------+-------+32 6 rows in set 

IF函式

有點類似C#語法中的三元表示式,有3個引數,第一個引數是表示式,後面兩個是值,當表示式成立的時候取第一個值,表示式不成立的時候取第二個值。

1 if(expr,val1,val2); --語法 

輸出學生資訊中的名稱和性別(1為男,0為女,這邊用if函式進行轉換)

 1 mysql> select studentname,if(sex=0,'女','男') from students where classid<>0; 2 +-------------+---------------------+ 3 | studentname | if(sex=0,'女','男') | 4 +-------------+---------------------+ 5 | brand | 男 | 6 | helen | 女 | 7 | lyn | 女 | 8 | sol | 男 | 9 | b1 | 男 |10 | b2 | 男 |11 | c1 | 女 |12 | c2 | 女 |13 | A | 男 |14 +-------------+---------------------+15 9 rows in set 

IF條件語句

IF語句用來進行條件判斷,根據不同的條件執行不同的操作。該語句在執行時首先判斷IF後的條件是否為真,則執行THEN後的語句,如果為假則繼續判斷IF語句直到為真為止,當以上都不滿足時則執行ELSE語句後的內容。

1 IF condition THEN2 ...3 ELSEIF condition THEN4 ...5 ELSE6 ...7 END IF 

程式碼示例,根據考試成績來分佈不同的成績等級

 1 mysql> 2 /*如果存在函式func_test2,則刪除*/ 3 DROP FUNCTION IF EXISTS fun_if; 4 /*宣告結束符為$*/ 5 DELIMITER $ 6 /*建立函式*/ 7 CREATE FUNCTION fun_if(score DECIMAL(10,2)) 8 RETURNS CHAR 9 BEGIN10 DECLARE score_grad VARCHAR(5) DEFAULT '';11 IF score>100 THEN SET score_grad='S'; 12 ELSEIF (score BETWEEN 91 AND 100) THEN SET score_grad='A';13 ELSEIF (score BETWEEN 81 AND 90) THEN SET score_grad='B';14 ELSEIF (score BETWEEN 71 AND 80) THEN SET score_grad='C' ;15 ELSE set score_grad='D';16 END IF;17 return score_grad;18 END $19 /*重置結束符為;*/20 DELIMITER ;21 Query OK, 0 rows affected 

執行結果

1 mysql> select fun_if(101),fun_if(100),fun_if(90),fun_if(80),fun_if(70);2 +-------------+-------------+------------+------------+------------+3 | fun_if(101) | fun_if(100) | fun_if(90) | fun_if(80) | fun_if(70) |4 +-------------+-------------+------------+------------+------------+5 | S | A | B | C | D |6 +-------------+-------------+------------+------------+------------+7 1 row in set 

CASE語句

CASE語句為多分支語句結構,該語句首先從WHEN後的VALUE中查詢與CASE後的VALUE相等的值,如果查詢到則執行該分支的內容,否則執行ELSE後的內容。CASE語句表示形式如下,類似C#中switch:

1 CASE expr2 WHEN val1 THEN result1 or state1[;](可選項,如果是語句需要加分號,結果值可以加)3 WHEN val2 THEN result2 or state24 ...5 ELSE resultn or staten6 END [CASE] (可選項,在begin end之間需加case,select後就不需要) 

在select中使用示例

 1 mysql> select studentname,case sex WHEN 0 THEN '女' WHEN 1 THEN '男' end as sex 2 from students where classid<>0; 3 +-------------+-----+ 4 | studentname | sex | 5 +-------------+-----+ 6 | brand | 男 | 7 | helen | 女 | 8 | lyn | 女 | 9 | sol | 男 |10 | b1 | 男 |11 | b2 | 男 |12 | c1 | 女 |13 | c2 | 女 |14 | A | 男 |15 +-------------+-----+16 9 rows in set 

在函式或儲存過程中使用示例

 1 mysql> 2 /*如果存在函式func_test2,則刪除*/ 3 DROP FUNCTION IF EXISTS fun_case; 4 /*宣告結束符為$*/ 5 DELIMITER $ 6 /*建立函式*/ 7 CREATE FUNCTION fun_case(sex INT) 8 RETURNS VARCHAR(20) 9 BEGIN10 DECLARE sexStr VARCHAR(20) DEFAULT '';11 CASE sex 12 WHEN 0 then set sexStr='女';13 WHEN 1 then set sexStr='男';14 ELSE set sexStr='不確定';15 END CASE;16 return sexStr;17 END $18 /*重置結束符為;*/19 DELIMITER ;20 21 Query OK, 0 rows affected 

函式執行結果

 1 mysql> select studentname,fun_case(sex) from students where classid<>0; 2 +-------------+---------------+ 3 | studentname | fun_case(sex) | 4 +-------------+---------------+ 5 | brand | 男 | 6 | helen | 女 | 7 | lyn | 女 | 8 | sol | 男 | 9 | b1 | 男 |10 | b2 | 男 |11 | c1 | 女 |12 | c2 | 女 |13 | A | 男 |14 +-------------+---------------+15 9 rows in set 

迴圈語句while

迴圈語句while 類似於C#中的while迴圈,我們知道在C#的while 或者 for 語句中,經常有用到兩個關鍵語法:跳過當前迴圈(continue) 和 結束迴圈(break)。

同樣的,在MySQL中也有兩個語法對應跳過和結束迴圈。

1 ITERATE loop_label; --跳過當前迴圈
1 LEAVE loop_label; --結束迴圈
while 語法
1 [loop_label:]while condition do2 --Todo:loop body3 end while [loop_label]; 

loop_label:迴圈標籤,和iterateleave結合用於在迴圈內部對迴圈進行控制:如:跳過本次迴圈、結束迴圈。

condition:迴圈條件,當滿足條件的時候,就會執行迴圈體,條件不成立的時候結束迴圈。

while示例

下面指令碼程式碼演示了將students表中studentid在給定數值範圍內的資料儲存到另外一張表中。

 1 /*先清除studentCount表記錄*/ 2 truncate table studentcount; 3 /*儲存過程如果存在則刪除*/ 4 DROP PROCEDURE IF EXISTS sp_while1; 5 /*宣告結束符為$*/ 6 DELIMITER $ 7 /*建立儲存過程*/ 8 CREATE PROCEDURE sp_while1(varial_count int) 9 BEGIN10 DECLARE idx int DEFAULT 1;11 DECLARE uname VARCHAR(30) DEFAULT '';12 loop_label:WHILE idx<=varial_count DO13 select studentname into uname from students where studentid = idx;14 INSERT into studentCount values (idx,uname);15 SET idx=idx+1;16 END WHILE;17 END $18 /*結束符置為;*/19 DELIMITER ; 

呼叫儲存過程,給定數值範圍是10,所以這邊取出1~10的資料儲存到studentCount表中

 1 mysql> CALL sp_while1(10); 2 Query OK, 1 row affected 3 4 mysql> select * from studentCount; 5 +-----------+-------------+ 6 | studentid | studentname | 7 +-----------+-------------+ 8 | 1 | brand | 9 | 2 | helen |10 | 3 | lyn |11 | 4 | sol |12 | 5 | b1 |13 | 6 | b2 |14 | 7 | c1 |15 | 8 | c2 |16 | 9 | lala |17 | 10 | A |18 +-----------+-------------+19 10 rows in set 
while示例:包含iterate/leave

前面我們說明過了,iterate 和 leave 分別代表跳過本次迴圈,類似於C#中的continue和break。我們在例子中測試下吧:

遇到studentname=lala時,結束迴圈,遇到偶數時候跳過單次迴圈。

 1 /*先清除studentCount表記錄*/ 2 truncate table studentcount; 3 /*儲存過程如果存在則刪除*/ 4 DROP PROCEDURE IF EXISTS sp_while2; 5 /*宣告結束符為$*/ 6 DELIMITER $ 7 /*建立儲存過程*/ 8 CREATE PROCEDURE sp_while2(varial_count int) 9 BEGIN10 DECLARE idx int DEFAULT 0;11 DECLARE uname VARCHAR(30) DEFAULT '';12 loop_label:WHILE idx<=varial_count DO 13 SET idx=idx+1;14 select studentname into uname from students where studentid = idx;15 /*如果遇到studentname為lala的同學,結束迴圈*/16 IF uname='lala' THEN17 LEAVE loop_label;18 /*如果idx為偶數,則跳過本次迴圈*/19 ELSEIF idx%2=0 THEN20 ITERATE loop_label;21 END IF; 22 INSERT into studentCount values (idx,uname); 23 END WHILE;24 END $25 /*結束符置為;*/26 DELIMITER ; 

呼叫儲存過程,輸出符合要求的資料:

 1 mysql> CALL sp_while2(10); 2 Query OK, 1 row affected 3 4 mysql> select * from studentCount; 5 +-----------+-------------+ 6 | studentid | studentname | 7 +-----------+-------------+ 8 | 1 | brand | 9 | 3 | lyn |10 | 5 | b1 |11 | 7 | c1 |12 +-----------+-------------+13 4 rows in set

迴圈語句repeat

repeat語法
1 [loop_label:]repeat2 -- Todo loop body3 until condition 4 end repeat [loop_label]; 

可以對比下上面while的語法,while是先判斷條件是否成立再執行迴圈體,repeat迴圈更像是的do...while迴圈,就是迴圈始終都會先執行一次,然後再判斷結束迴圈的條件,不滿足結束條件,迴圈體繼續執行。

 1 /*先清除studentCount表記錄*/ 2 truncate table studentcount; 3 /*儲存過程如果存在則刪除*/ 4 DROP PROCEDURE IF EXISTS sp_repeat; 5 /*宣告結束符為$*/ 6 DELIMITER $ 7 /*建立儲存過程*/ 8 CREATE PROCEDURE sp_repeat(varial_count int) 9 BEGIN10 DECLARE idx int DEFAULT 0;11 DECLARE uname VARCHAR(30) DEFAULT '';12 loop_label:REPEAT 13 SET idx=idx+1;14 select studentname into uname from students where studentid = idx;15 /*如果遇到studentname為lala的同學,結束迴圈*/16 IF uname='lala' THEN17 LEAVE loop_label;18 /*如果idx為偶數,則跳過本次迴圈*/19 ELSEIF idx%2=0 THEN20 ITERATE loop_label;21 END IF; 22 INSERT into studentCount values (idx,uname); 23 UNTIL idx>varial_count 24 END REPEAT;25 END $26 /*結束符置為;*/27 DELIMITER ; 

注意條件的變化,下面是呼叫儲存過程,輸出需要的資料:

 1 mysql> CALL sp_repeat(10); 2 Query OK, 1 row affected 3 4 mysql> select * from studentCount; 5 +-----------+-------------+ 6 | studentid | studentname | 7 +-----------+-------------+ 8 | 1 | brand | 9 | 3 | lyn |10 | 5 | b1 |11 | 7 | c1 |12 +-----------+-------------+13 4 rows in set 

迴圈語句loop

loop語法
1 [loop_label:]loop2 --Todo loop body3 end loop [loop label]; 

loop不像while和repeat那樣有控制條件,條件不符合的時候會跳出。所以它實際上是會一直執行的,如果不主動中斷或者跳出的話,類似於一個死迴圈,需要在迴圈體中使用iterate或者leave來控制迴圈的執行。

 1 /*先清除studentCount表記錄*/ 2 truncate table studentcount; 3 /*儲存過程如果存在則刪除*/ 4 DROP PROCEDURE IF EXISTS sp_loop; 5 /*宣告結束符為$*/ 6 DELIMITER $ 7 /*建立儲存過程*/ 8 CREATE PROCEDURE sp_loop(varial_count int) 9 BEGIN10 DECLARE idx int DEFAULT 0;11 DECLARE uname VARCHAR(30) DEFAULT '';12 loop_label:LOOP 13 SET idx=idx+1;14 select studentname into uname from students where studentid = idx;15 /*如果遇到studentname為lala的同學,結束迴圈*/16 IF uname='lala' THEN17 LEAVE loop_label;18 /*如果idx為偶數,則跳過本次迴圈*/19 ELSEIF idx%2<>0 THEN20 ITERATE loop_label;21 /*這邊加一個終結計數跳出的條件*/22 ELSEIF idx>varial_count THEN23 LEAVE loop_label;24 END IF; 25 INSERT into studentCount values (idx,uname); 26 27 END LOOP;28 END $29 /*結束符置為;*/30 DELIMITER ; 

呼叫儲存過程,並輸出你需要的資料:

 1 mysql> CALL sp_loop(6); 2 Query OK, 1 row affected 3 4 mysql> select * from studentCount; 5 +-----------+-------------+ 6 | studentid | studentname | 7 +-----------+-------------+ 8 | 2 | helen | 9 | 4 | sol |10 | 6 | b2 |11 +-----------+-------------+12 3 rows in set

總結

1、瞭解了IF函式,它常用在SELECT語句中,類似於C#中的三元表示式。
2、IF條件表示式,類似於C#中的IF... ELSE...,多用於函式或儲存過程中的判斷選擇邏輯。
3、瞭解CASE語句的兩種用法,一種用在SELECT中使用,一種用在函式和儲存過程中。
4、瞭解了三種迴圈體的使用,while、repeat分別對應C#中的while 和 do while迴圈,loop類似於一個while(true)的死迴圈。
5、迴圈體都包含在begin end中,迴圈體的控制依靠leave和iterate,leave相當於break,即退出整個迴圈體,iterate類似於continue,即跳過本次循

版权声明
本文为[itread01]所创,转载请带上原文链接,感谢
https://www.itread01.com/content/1611302884.html

  1. 【计算机网络 12(1),尚学堂马士兵Java视频教程
  2. 【程序猿历程,史上最全的Java面试题集锦在这里
  3. 【程序猿历程(1),Javaweb视频教程百度云
  4. Notes on MySQL 45 lectures (1-7)
  5. [computer network 12 (1), Shang Xuetang Ma soldier java video tutorial
  6. The most complete collection of Java interview questions in history is here
  7. [process of program ape (1), JavaWeb video tutorial, baidu cloud
  8. Notes on MySQL 45 lectures (1-7)
  9. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  10. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  11. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  12. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  13. 【递归,Java传智播客笔记
  14. [recursion, Java intelligence podcast notes
  15. [adhere to painting for 386 days] the beginning of spring of 24 solar terms
  16. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)
  17. K8s Series Part 8 (service, endpoints and high availability kubeadm deployment)
  18. 【重识 HTML (3),350道Java面试真题分享
  19. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  20. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  21. [re recognize HTML (3) and share 350 real Java interview questions
  22. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  23. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  24. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  25. RPC 1: how to develop RPC framework from scratch
  26. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  27. RPC 1: how to develop RPC framework from scratch
  28. 一次性捋清楚吧,对乱糟糟的,Spring事务扩展机制
  29. 一文彻底弄懂如何选择抽象类还是接口,连续四年百度Java岗必问面试题
  30. Redis常用命令
  31. 一双拖鞋引发的血案,狂神说Java系列笔记
  32. 一、mysql基础安装
  33. 一位程序员的独白:尽管我一生坎坷,Java框架面试基础
  34. Clear it all at once. For the messy, spring transaction extension mechanism
  35. A thorough understanding of how to choose abstract classes or interfaces, baidu Java post must ask interview questions for four consecutive years
  36. Redis common commands
  37. A pair of slippers triggered the murder, crazy God said java series notes
  38. 1、 MySQL basic installation
  39. Monologue of a programmer: despite my ups and downs in my life, Java framework is the foundation of interview
  40. 【大厂面试】三面三问Spring循环依赖,请一定要把这篇看完(建议收藏)
  41. 一线互联网企业中,springboot入门项目
  42. 一篇文带你入门SSM框架Spring开发,帮你快速拿Offer
  43. 【面试资料】Java全集、微服务、大数据、数据结构与算法、机器学习知识最全总结,283页pdf
  44. 【leetcode刷题】24.数组中重复的数字——Java版
  45. 【leetcode刷题】23.对称二叉树——Java版
  46. 【leetcode刷题】22.二叉树的中序遍历——Java版
  47. 【leetcode刷题】21.三数之和——Java版
  48. 【leetcode刷题】20.最长回文子串——Java版
  49. 【leetcode刷题】19.回文链表——Java版
  50. 【leetcode刷题】18.反转链表——Java版
  51. 【leetcode刷题】17.相交链表——Java&python版
  52. 【leetcode刷题】16.环形链表——Java版
  53. 【leetcode刷题】15.汉明距离——Java版
  54. 【leetcode刷题】14.找到所有数组中消失的数字——Java版
  55. 【leetcode刷题】13.比特位计数——Java版
  56. oracle控制用户权限命令
  57. 三年Java开发,继阿里,鲁班二期Java架构师
  58. Oracle必须要启动的服务
  59. 万字长文!深入剖析HashMap,Java基础笔试题大全带答案
  60. 一问Kafka就心慌?我却凭着这份,图灵学院vip课程百度云