1. 程式人生 > 資料庫 >MySQL學習筆記之流程控制

MySQL學習筆記之流程控制

一、分支結構

  1. if函式
  語法:if(表示式1,表示式2,表示式3)
  如果表示式1成立,則返回表示式2的值,否則返回表示式3的值
  mysql> select if(2<3,'True','False');
  +------------------------+
  | if(2<3,'True','False') |
  +------------------------+
  | True                   |
  +------------------------+
  1 row in set (0.00 sec)

  mysql> select if(2>3,'True','False');
  +------------------------+
  | if(2>3,'True','False') |
  +------------------------+
  | False                  |
  +------------------------+
  1 row in set (0.00 sec)

  2. case結構
  case 有兩種用法:
        ① 語法:
        case 表示式|變數|欄位
        when 判斷的值1 then 返回值1
        when 判斷的值2 then 返回值2
        ...
        when 判斷的值n then 返回值n
        else 返回值
        end case
        ② 語法:
        case
        when 條件1 then 返回值1或語句1
        when 條件2 then 返回值2或語句2
        ...
        when 條件n then 返回值n或語句n
        else 返回值或語句
        end case
        如果作為表示式使用,case結構可以在任何地方使用,如果作為獨立的語句使用,則只能放在begin...end中使用。
        例1:作為表示式使用
        mysql> select name,case gender when 1 then '男' when 2 then '女' else '未知' end 性別 from students;
        +-----------+--------+
        | name      | 性別   |
        +-----------+--------+
        | 李四      | 男     |
        | 周芷若    | 女     |
        | 趙敏      | 女     |
        | Lucy      | 女     |
        | Tony      | 男     |
        | Lucy      | 女     |
        | 蕭峰      | 男     |
        +-----------+--------+
        7 rows in set (0.00 sec)

        例2:作為獨立語句使用
        mysql> delimiter $$
        mysql> create procedure get_students_grade(in name varchar(20),in subject varchar(20))
              -> begin
              -> declare su_score int default 0;
              -> select s.score into su_score from students st left join score s on st.id=s.student_id left join subject su on su.id=s.subject_id where st.name=name and su.name=subject;
              -> case 
              -> when su_score >= 90 then select '優秀';
              -> when su_score >= 80 then select '良好';
              -> when su_score >= 60 then select '及格';
              -> else select '不及格';
              -> end case;
              -> end $$
        Query OK, 0 rows affected (0.11 sec)

        mysql> delimiter ;
        mysql> call get_students_grade('周芷若','數學');
        +-----------+
        | 不及格    |
        +-----------+
        | 不及格    |
        +-----------+
        1 row in set (0.00 sec)

  3. if結構
        語法:
        if expr1 then 語句1
        elseif expr2 then 語句2
        ...
        [else 語句n]
        end if;
        if結構只能在begin...end中使用
        mysql> delimiter $$
        mysql> create procedure getGradre(in score int)
              -> begin
              -> if score >= 90 then select 'A';
              -> elseif score >= 80 then select 'B';
              -> elseif score >= 60 then select 'C';
              -> else select 'D';
              -> end if;
              -> end $$
        Query OK, 0 rows affected (0.02 sec)

        mysql> delimiter ;
        mysql> call getGradre(85);
        +---+
        | B |
        +---+
        | B |
        +---+
        1 row in set (0.00 sec)

二、迴圈結構
MySQL的迴圈結構分為while、loop、repeat三種,迴圈控制結構有:iterate(類似於continue)和leave(類似於break)。

  1. while迴圈結構
  語法:
        [標籤:]while 迴圈條件 do
              迴圈體;
        end while [標籤];
  
  2. loop迴圈結構
  語法:
        [標籤:]loop
              迴圈體;
        end loop [標籤];
  可以用來模擬簡單的死迴圈,搭配leave結束迴圈。

  3. repeat迴圈結構
  語法:
        [標籤:]repeat
              迴圈體;
        until 結束迴圈條件
        end repeat [標籤]

三、MySQL迴圈結構使用示例

  1. 建立測試表
  create table admin(
        id int auto_increment primary key,
        name varchar(20),
        passwd char(32)
  ) engine=innodb default charset=utf8mb4 collate=utf8mb4_unicode_ci;

  2. 建立儲存過程,使用while迴圈結構,批量插入指定數量的資料
  set autocommit = 0;#關閉事務的自動提交
  delimiter $
  create procedure insertAdmin(in insertCount int)
  begin
        declare i int default 1;
        start transaction;
        while insertCount >= i do
        insert into admin(name,passwd) values(concat('abcd',i),md5('aaaa'));
        set i = i+1;
        end while;
        commit;
  end $
  delimiter ;
  call insertAdmin(2);

  mysql> select * from admin;
  +----+-------+----------------------------------+
  | id | name  | passwd                           |
  +----+-------+----------------------------------+
  |  1 | abcd1 | 74b87337454200d4d33f80c4663dc5e5 |
  |  2 | abcd2 | 74b87337454200d4d33f80c4663dc5e5 |
  +----+-------+----------------------------------+
  2 rows in set (0.00 sec)

  3. 建立儲存過程,使用loop迴圈結構,批量插入指定數量的資料

  delimiter $
  create procedure insertAdminLoop(in insertCount int)
  begin
        declare i int default 1;
        loopName:loop
              insert into admin(name,passwd) values(concat('efgh',i),md5('bbbb'));
              if insertCount <= i then leave loopName;
              end if;
              set i = i+1;
        end loop loopName;
        commit;
  end $
  delimiter ;
  call insertAdminLoop(2);

  4. 建立儲存過程,使用repeat迴圈結構,批量插入指定數量的資料

  mysql> delimiter $
  mysql> create procedure insertAdminRepeat(in insertCount int)
        -> begin
        -> declare i int default 1;
        -> repeat
        -> insert into admin(name,passwd) values(concat('fwcweAX',i),md5(concat('sdfewf',i)));
        -> set i = i+1;
        -> until insertCount < i
        -> end repeat;
        -> commit;
        -> end $
  Query OK, 0 rows affected (0.01 sec)

  mysql> delimiter ;

四、使用儲存函式和儲存過程灌入資料

  1. 建立部門表
  create table dept(
        id int auto_increment primary key,
        deptName varchar(30) default null,
        address varchar(40) default null
  )engine=innodb default charset=utf8mb4 collate=utf8mb4_unicode_ci;

  2. 建立員工資訊表
  create table emp(
        id int auto_increment primary key,
        name varchar(20) default null,
        age tinyint(3) default null,
        deptid int default null,
        empno int not null,
        key idx_dept_id (deptid)
  )engine=innodb default charset=utf8mb4 collate=utf8mb4_unicode_ci;

  3. 建立函式,獲取隨機字串
  delimiter $
  create function rand_str(n int) returns varchar(255) reads sql data
  begin
        declare chars_str varchar(60) default 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        declare return_str varchar(60) default '';
        declare i int default 1;
        while i <= n do
              set return_str = concat(return_str,substr(chars_str,floor(rand()*52+1),1));
              set i = i+1;
        end while;
        return return_str;
  end $

  4. 建立函式,獲取部門隨機編號
  create function rand_number(from_num int,to_num int) returns int no sql
  begin
        declare i int default 0;
        set i = floor(from_num + rand() * (to_num - from_num + 1));
        return i;
  end $

  5. 建立儲存過程,批量插入員工資訊資料
  create procedure insertEmp(in start_num int, in end_num int)
  begin
        declare i int default 0;
        declare name_len int default 1;
        set name_len = floor(5 + rand()*6);
        set autocommit = 0;
        start transaction;
        repeat
              set i = i+1;
              insert into emp(name,age,deptid,empno) values(rand_str(name_len),rand_number(30,50),rand_number(1,100000),(start_num+i));
              until end_num <= i
        end repeat;
        commit;
        set autocommit=1;
  end $
  call insertEmp(100000,5000000);

  6. 建立儲存過程,批量插入部門資訊資料
  create procedure insertDept(in total int)
  begin
        declare i int default 0;
        declare deptName_len int default 1;
        declare addr_len int default 1;
        set deptName_len = floor(6+rand()*7);
        set addr_len = floor(10+rand()*11);
        set autocommit = 0;
        start transaction;
        repeat
              set i = i+ 1;
              insert into dept(deptName,address,ceo) values(rand_str(deptName_len),rand_str(addr_len),rand_number(1,5000000));
        until i>=total
        end repeat;
        commit;
        set autocommit=1;
  end $
  call insertDept(100000);