Mysql 流程式控制制 認識 從我目前所接觸的編程語言,C, R, VB, Python, Javascript...,來看, 無非就是 變數, 表達式, 流程式控制制(順序, 分支, 迴圈), 封裝了一些更高級的數據結構而已 , 區別在於應用場景和語言特性, 其實邏輯都是相同的, 唯手熟爾. 選擇結構 ...
Mysql 流程式控制制
認識
從我目前所接觸的編程語言,C, R, VB, Python, Javascript...,來看, 無非就是變數, 表達式, 流程式控制制(順序, 分支, 迴圈), 封裝了一些更高級的數據結構而已, 區別在於應用場景和語言特性, 其實邏輯都是相同的, 唯手熟爾.
選擇結構 if-else; case
-- if-esle 語法
IF search_condition THEN
statement_list;
[ELSEIF search_condition THEN
statement_list; ....]
ELSE
statement_list;
END IF;
-- CASE 語法
CASE case_value
WHEN when_value THEN statement_list
[WHEN when_value THEN statement_list]...
[ELSE statement_list]
END CASE;
OR:
CASE
WHEN search_condition THEN statement_list
[WHEN search_condition THEN statement_list] ...
[ELSE statement_list]
END CASE
-- 隨機推送一句表白
drop procedure if exists sayLove;
delimiter //
create procedure sayLove()
begin
declare num int default 0;
-- 生成一個1-5間的隨機數
set num := round(rand()*5);
-- 判斷
case num
when 1 then select "人生若只如初見";
when 2 then select "春風十里不如你";
when 3 then select "愛你就像愛生命";
else
select "今晚的月色真美";
end case;
end //
delimiter ;
call sayLove();
-- out
mysql> call sayLove();
+----------------+
| 今晚的月色真美 |
+----------------+
| 今晚的月色真美 |
+----------------+
1 row in set (0.09 sec)
Query OK, 0 rows affected (0.00 sec)
mysql> call sayLove();
+----------------+
| 愛你就像愛生命 |
+----------------+
| 愛你就像愛生命 |
+----------------+
1 row in set (0.14 sec)
Query OK, 0 rows affected (0.00 sec)
mysql> call sayLove();
+----------------+
| 春風十里不如你 |
+----------------+
| 春風十里不如你 |
+----------------+
1 row in set (0.11 sec)
CASE 能實現的, IF-ELSE也完全能, 只是提供了更多的選擇而已.
-- 用 if-esle實現
drop procedure if exists sayLove;
delimiter //
create procedure sayLove()
begin
declare num int default 0;
-- 生成一個1-5間的隨機數
set num := round(rand()*5);
-- 判斷
if num=1 then select "人生若只如初見";
elseif num=2 then select "春風十里不如你";
elseif num-3 then select "愛你就像愛生命";
else
select "今晚的月色真美";
end if;
end //
delimiter ;
call sayLove();
MySql 迴圈
- WHILE ... DO ... END WHILE 叫什麼"當"型迴圈, 滿足條件才進入迴圈體
- LOOP ... LEAVE...END LOOP "直到型迴圈"
- REPEAT ... UNTIL ... END REPEAT
while ...do ...迴圈
while search_condition do
statement_list;
end while;
repeat ...until ...迴圈
repeat
statement_list;
until search_condition;
end repeat;
loop ...leave 迴圈
[begin_label:] loop
statement_list;
leave [begin_label];
end loop [end_label];
迴圈-案例 1+2+...n
-- while 實現 求1+2+3+..n和
-- 自己容易混的點: 忘在結尾; end; 變數忘了 set;
-- 傳入參數: in 傳入值; out: 傳入變數去接收返回的值; inout 傳入又輸出
drop procedure if exists sumN_while;
delimiter //
create procedure sumN_while(in n int)
begin
declare total int default 0;
declare i int default 0;
-- while ...do ....
while i <= n do
set total := total + i;
set i := i + 1;
-- 列印一下結果
end while;
select concat("1+2+..", n, "的和是:", total) as '輸出啦';
end //
delimiter ;
call sumN_while(100);
-- out
call sumN_while(100);
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
+----------------------+
| 輸出啦 |
+----------------------+
| 1+2+..100的和是:5050 |
+----------------------+
1 row in set (0.10 sec)
同樣同 repeat ... until ..實現, 順便練習下 out 類型參數
-- repeat 實現 1+2+..n的和
drop procedure if exists sumN_repeat;
delimiter //
-- 設置傳入out型參數變數, 用來接收輸出值
create procedure sumN_repeat(out total int)
begin
xxxx
end //
delimiter ;
drop procedure if exists sumN_repeat;
delimiter //
-- 設置再傳入out型參數變數, 用來接收輸出值
create procedure sumN_repeat(in n int)
begin
declare i int default 0;
declare total int default 0;
-- repeat ... until ...
repeat
set total := total + i;
set i := i + 1;
-- 退出條件 until..True時才退出哦, 註意跟while的區別
until i > n
end repeat;
-- 在內部列印出結果
select total;
end //
delimiter ;
-- out
call sumN_repeat(100);
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
+-------+
| total |
+-------+
| 5050 |
+-------+
1 row in set (0.09 sec)
用out類型參數.
-- repeat 實現 1+2+..n的和
drop procedure if exists sumN_repeat;
delimiter //
-- 設置再傳入out型參數變數, 用來接收輸出值
create procedure sumN_repeat(in n int, out total int)
begin
declare i int default 0;
set total := 0; -- 順序: 先decalre 再是set, 不能亂,兄弟
-- repeat ... until ...
repeat
set total := total + i;
set i := i + 1;
-- 退出條件 until..註意是條件為True時退出哦
until i > n
end repeat;
end //
delimiter ;
-- set @ret := 0;
-- call sumN_repeat(100, @ret);
-- select @ret;
-- out
mysql> set @ret := 0; -- 這個全局變數 @ret 用來接收過程的 total值哦
Query OK, 0 rows affected (0.00 sec)
mysql> call sumN_repeat(10000, @ret);
Query OK, 0 rows affected (0.04 sec)
mysql> select @ret;
+----------+
| @ret |
+----------+
| 50005000 |
+----------+
1 row in set (0.08 sec)
再用 loop....leave 來整一波
-- loop ...leave ... 來實現 求 1+2+..n 的和
drop procedure if exists sumN_loop;
delimiter //
create procedure sumN_loop(in n int, out total int)
begin
declare i int default 0;
set total := 0;
-- loop, 先取一個標簽名, 再寫退出條件, if-then...
myLoop: loop
if i > n then
leave myLoop;
end if;
set total := total + i;
set i := i + 1;
end loop;
end //
delimiter ;
-- out
mysql> set @ret := 0;
Query OK, 0 rows affected (0.00 sec)
mysql> call sumN_loop(100, @ret);
Query OK, 0 rows affected (0.00 sec)
mysql> select @ret;
+------+
| @ret |
+------+
| 5050 |
+------+
1 row in set (0.11 sec)
小結MySql控制流
補充: 存儲過程的參數聲明
- in 類型: 要求在調用的時候, 接收從外界傳入一個值.
- out 類型: 要求在調用時, 傳入一個變數去接收procedure的"返回值"
- inout 類型: 輸入輸出型
補充: MySql變數定義
- 在存儲過程內, 用: declare 變數名 類型 [default 值]; 類似"局部變數"
- 在外邊運行, 用: @變數 := 值; 類似"全局變數", 註意MySql的標準賦值符號是 " := ", 而 "=" 只有在update 和set時表示賦值, 其餘場景都是 "等號".
- 選擇結構(if, case):
- if - elseif- esle -end if;
- case value when value1 then ; when value2 ...then .. else .. . end case;
- 迴圈結構(while, repeat, loop)
- while .... do .... end while;
- repeat ... until .... end repeat;
- myLoop: loop ..... if ... then leave myLoop; end if ; ..... end loop;