From 29be0e839b8c5a33cf54ba2bd84d0090ccb18052 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B7=AF=E7=8E=B2?= <1516489926@qq.com> Date: Mon, 9 Oct 2023 23:00:07 +0800 Subject: [PATCH] =?UTF-8?q?if=E5=92=8Ccase=E8=AF=AD=E5=8F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../20231009 if\345\222\214case.md" | 296 ++++++++++++++++++ 1 file changed, 296 insertions(+) create mode 100644 "29 \350\267\257\347\216\262/20231009 if\345\222\214case.md" diff --git "a/29 \350\267\257\347\216\262/20231009 if\345\222\214case.md" "b/29 \350\267\257\347\216\262/20231009 if\345\222\214case.md" new file mode 100644 index 0000000..6d20d60 --- /dev/null +++ "b/29 \350\267\257\347\216\262/20231009 if\345\222\214case.md" @@ -0,0 +1,296 @@ +## 3. 流程控制 + +### 1) 分支结构之 IF + +* IF 语句的语法结构是: + +```mysql +IF 表达式1 THEN 操作1 sql语句 +[ELSEIF 表达式2 THEN 操作2]…… +[ELSE 操作N] +END IF +``` + +根据表达式的结果为TRUE或FALSE执行相应的语句。这里“[]”中的内容是可选的。 + +* 特点:① 不同的表达式对应不同的操作 ② 使用在begin end中 + +* 举例1: + +```mysql +IF val IS NULL + THEN SELECT 'val is null'; +ELSE SELECT 'val is not null'; +END IF; +``` + +* 举例2:声明存储过程“update_salary_by_eid1”,定义IN参数emp_id,输入员工编号。判断该员工薪资如果低于8000元并且入职时间超过5年,就涨薪500元;否则就不变。 + +```mysql +DELIMITER // +CREATE PROCEDURE update_salary_by_eid1(IN emp_id INT) +BEGIN + DECLARE emp_salary DOUBLE; + DECLARE hire_year DOUBLE; + SELECT salary INTO emp_salary FROM employees WHERE employee_id = emp_id; + SELECT DATEDIFF(CURDATE(),hire_date)/365 INTO hire_year + FROM employees WHERE employee_id = emp_id; + IF emp_salary < 8000 AND hire_year > 5 + THEN UPDATE employees SET salary = salary + 500 WHERE employee_id = emp_id; + END IF; +END // +DELIMITER ; +``` + +### 2) 分支结构之 CASE + +* CASE 语句的语法结构1: + +```mysql +#情况一:类似于switch +CASE 表达式 +WHEN 值1 THEN 结果1或语句1(如果是语句,需要加分号) +WHEN 值2 THEN 结果2或语句2(如果是语句,需要加分号) +... +ELSE 结果n或语句n(如果是语句,需要加分号) +END [case](如果是放在begin end中需要加上case,如果放在select后面不需要) +``` + +* CASE 语句的语法结构2: + +```mysql +#情况二:类似于多重if +CASE +WHEN 条件1 THEN 结果1或语句1(如果是语句,需要加分号) +WHEN 条件2 THEN 结果2或语句2(如果是语句,需要加分号) +... +ELSE 结果n或语句n(如果是语句,需要加分号) +END [case](如果是放在begin end中需要加上case,如果放在select后面不需要) +``` + +* 举例1:使用CASE流程控制语句的第1种格式,判断val值等于1、等于2,或者两者都不等。 + +```mysql +CASE val + WHEN 1 THEN SELECT 'val is 1'; + WHEN 2 THEN SELECT 'val is 2'; + ELSE SELECT 'val is not 1 or 2'; +END CASE; +``` + +* 举例2:声明存储过程“update_salary_by_eid4”,定义IN参数emp_id,输入员工编号。判断该员工 薪资如果低于9000元,就更新薪资为9000元;薪资大于等于9000元且低于10000的,但是奖金比例 为NULL的,就更新奖金比例为0.01;其他的涨薪100元。 + +```mysql +DELIMITER // +CREATE PROCEDURE update_salary_by_eid4(IN emp_id INT) +BEGIN + DECLARE emp_sal DOUBLE; + DECLARE bonus DECIMAL(3,2); + SELECT salary INTO emp_sal FROM employees WHERE employee_id = emp_id; + SELECT commission_pct INTO bonus FROM employees WHERE employee_id = emp_id; + CASE + WHEN emp_sal<9000 + THEN UPDATE employees SET salary=9000 WHERE employee_id = emp_id; + WHEN emp_sal<10000 AND bonus IS NULL + THEN UPDATE employees SET commission_pct=0.01 WHERE employee_id = emp_id; + ELSE + UPDATE employees SET salary=salary+100 WHERE employee_id = emp_id; + END CASE; +END // +DELIMITER ; +``` + +* 举例3:声明存储过程update_salary_by_eid5,定义IN参数emp_id,输入员工编号。判断该员工的 入职年限,如果是0年,薪资涨50;如果是1年,薪资涨100;如果是2年,薪资涨200;如果是3年, 薪资涨300;如果是4年,薪资涨400;其他的涨薪500。 + +```mysql +DELIMITER // +CREATE PROCEDURE update_salary_by_eid5(IN emp_id INT) +BEGIN + DECLARE emp_sal DOUBLE; + DECLARE hire_year DOUBLE; + SELECT salary INTO emp_sal FROM employees WHERE employee_id = emp_id; + SELECT ROUND(DATEDIFF(CURDATE(),hire_date)/365) INTO hire_year FROM employees + WHERE employee_id = emp_id; + CASE hire_year + WHEN 0 THEN UPDATE employees SET salary=salary+50 WHERE employee_id = emp_id; + WHEN 1 THEN UPDATE employees SET salary=salary+100 WHERE employee_id = emp_id; + WHEN 2 THEN UPDATE employees SET salary=salary+200 WHERE employee_id = emp_id; + WHEN 3 THEN UPDATE employees SET salary=salary+300 WHERE employee_id = emp_id; + WHEN 4 THEN UPDATE employees SET salary=salary+400 WHERE employee_id = emp_id; + ELSE UPDATE employees SET salary=salary+500 WHERE employee_id = emp_id; + END CASE; +END // +DELIMITER ; +``` + +### 3) 循环结构之LOOP + +LOOP循环语句用来重复执行某些语句。LOOP内的语句一直重复执行直到循环被退出(使用LEAVE子 句),跳出循环过程。 + +LOOP语句的基本格式如下: + +```mysql +[loop_label:] LOOP +循环执行的语句 +END LOOP [loop_label] +``` + +其中,loop_label表示LOOP语句的标注名称,该参数可以省略。 + +举例1:使用LOOP语句进行循环操作,id值小于10时将重复执行循环过程。 + +```mysql +DECLARE id INT DEFAULT 0; +add_loop:LOOP + SET id = id +1; + IF id >= 10 THEN LEAVE add_loop; + END IF; +END LOOP add_loop; +``` + +举例2:当市场环境变好时,公司为了奖励大家,决定给大家涨工资。声明存储过程 “update_salary_loop()”,声明OUT参数num,输出循环次数。存储过程中实现循环给大家涨薪,薪资涨为 原来的1.1倍。直到全公司的平均薪资达到12000结束。并统计循环次数。 + +```mysql +DELIMITER // +CREATE PROCEDURE update_salary_loop(OUT num INT) +BEGIN + DECLARE avg_salary DOUBLE; + DECLARE loop_count INT DEFAULT 0; + SELECT AVG(salary) INTO avg_salary FROM employees; + label_loop:LOOP + IF avg_salary >= 12000 THEN LEAVE label_loop; + END IF; + UPDATE employees SET salary = salary * 1.1; + SET loop_count = loop_count + 1; + SELECT AVG(salary) INTO avg_salary FROM employees; + END LOOP label_loop; + SET num = loop_count; +END // +DELIMITER ; +``` + +### 4) 循环结构之WHILE + +WHILE语句创建一个带条件判断的循环过程。WHILE在执行语句执行时,先对指定的表达式进行判断,如 果为真,就执行循环内的语句,否则退出循环。WHILE语句的基本格式如下: + +```mysql +[while_label:] WHILE 循环条件 DO +循环体 +END WHILE [while_label]; +``` + +while_label为WHILE语句的标注名称;如果循环条件结果为真,WHILE语句内的语句或语句群被执行,直 至循环条件为假,退出循环。 + +* 举例1:WHILE语句示例,i值小于10时,将重复执行循环过程,代码如下: + +```mysql +DELIMITER // +CREATE PROCEDURE test_while() +BEGIN + DECLARE i INT DEFAULT 0; + WHILE i < 10 DO + SET i = i + 1; + END WHILE; + SELECT i; +END // +DELIMITER ; +#调用 +CALL test_while(); +``` + +* 举例2:市场环境不好时,公司为了渡过难关,决定暂时降低大家的薪资。声明存储过程 “update_salary_while()”,声明OUT参数num,输出循环次数。存储过程中实现循环给大家降薪,薪资降 为原来的90%。直到全公司的平均薪资达到5000结束。并统计循环次数。 + +```mysql +DELIMITER // +CREATE PROCEDURE update_salary_while(OUT num INT) +BEGIN + DECLARE avg_sal DOUBLE ; + DECLARE while_count INT DEFAULT 0; + SELECT AVG(salary) INTO avg_sal FROM employees; + WHILE avg_sal > 5000 DO + UPDATE employees SET salary = salary * 0.9; + SET while_count = while_count + 1; + SELECT AVG(salary) INTO avg_sal FROM employees; + END WHILE; + SET num = while_count; +END // +DELIMITER ; +``` + +### ## 作业 + +```mysql +create database work17 charset utf8; +use work17; + + + create table student( + id int primary key auto_increment, + name varchar(15) not null, + phone varchar(15) unique, + birth date, + salary int + ); + + insert into student(name,phone,birth,salary) + values + ('朱茵','13201233453','1982-02-12',4500), + ('孙燕姿','13501233653','1980-12-09',48796), + ('田馥甄','13651238755','1983-08-21',4561), + ('邓紫棋','17843283452','1991-11-12',45500), + ('刘若英','18635575464','1989-05-18',12000), + ('杨超越','13761238755','1994-05-11',2000); + + + + +-#1. 创建函数test_if_case(),实现传入成绩,如果成绩>90,返回A,如果成绩>80,返回B,如果成绩>60,返回C,否则返回D +#要求:分别使用if结构和case结构实现 + +#方式1:if +delimiter // +create procedure test_if_case(in score double(4,1)) +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 // +delimiter ; + +call test_if_case(90); + + +#方式2:case when ... +delimiter // +create procedure test_if_case2(in s2 double(4,1)) +begin +case when s2>90 then select 'A'; +when s2>80 then select 'B'; +when s2>60 then select 'C'; +else select 'D'; +end case; +end // +delimiter ; + +call test_if_case2(67); + + +#2. 创建存储过程test_if_pro(),传入工资值,如果工资值<3000,则删除工资为此值的员工, +# 如果3000 <= 工资值 <= 5000,则修改此工资值的员工薪资涨1000,否则涨工资500 + +delimiter // +create procedure test_if_pro(in snum int) +begin +if snum<3000 then delete from student where salary=snum; +elseif 3000<=snum<=5000 then update student set salary=snum+1000; +elseif 3000>snum or snum>5000 then update student set salary=snum+500; +end if; +end // +delimiter ; +call test_if_pro(4561); +select * from student; +drop procedure test_if_pro; +``` + -- Gitee