diff --git "a/29 \350\267\257\347\216\262/20231011 \345\276\252\347\216\257\344\275\234\344\270\232.md" "b/29 \350\267\257\347\216\262/20231011 \345\276\252\347\216\257\344\275\234\344\270\232.md" new file mode 100644 index 0000000000000000000000000000000000000000..799a2dd737c4deca8a6a9abb57538d8dbfd01cd0 --- /dev/null +++ "b/29 \350\267\257\347\216\262/20231011 \345\276\252\347\216\257\344\275\234\344\270\232.md" @@ -0,0 +1,180 @@ +## 笔记 + +### 跳转语句之LEAVE语句 + +LEAVE语句:可以用在循环语句内,或者以 BEGIN 和 END 包裹起来的程序体内,表示跳出循环或者跳出 程序体的操作。如果你有面向过程的编程语言的使用经验,你可以把 LEAVE 理解为 break。 + +基本格式如下: + +```mysql +LEAVE 标记名 +``` + +其中,label参数表示循环的标志。LEAVE和BEGIN ... END或循环一起被使用。 + +举例1:创建存储过程 “leave_begin()”,声明INT类型的IN参数num。给BEGIN...END加标记名,并在 BEGIN...END中使用IF语句判断num参数的值。 + +如果num<=0,则使用LEAVE语句退出BEGIN...END; 如果num=1,则查询“employees”表的平均薪资; 如果num=2,则查询“employees”表的最低薪资; 如果num>2,则查询“employees”表的最高薪资。 + +IF语句结束后查询“employees”表的总人数。 + +```mysql +DELIMITER // +CREATE PROCEDURE leave_begin(IN num INT) + begin_label: BEGIN + IF num<=0 + THEN LEAVE begin_label; + ELSEIF num=1 + THEN SELECT AVG(salary) FROM employees; + ELSEIF num=2 + THEN SELECT MIN(salary) FROM employees; + ELSE + SELECT MAX(salary) FROM employees; + END IF; + SELECT COUNT(*) FROM employees; + END // +DELIMITER ; +``` + +举例2: 当市场环境不好时,公司为了渡过难关,决定暂时降低大家的薪资。声明存储过程“leave_while()”,声明 OUT参数num,输出循环次数,存储过程中使用WHILE循环给大家降低薪资为原来薪资的90%,直到全公司的平均薪资小于等于10000,并统计循环次数。 + +```mysql +DELIMITER // +CREATE PROCEDURE leave_while(OUT num INT) +BEGIN + DECLARE avg_sal DOUBLE;#记录平均工资 + DECLARE while_count INT DEFAULT 0; #记录循环次数 + SELECT AVG(salary) INTO avg_sal FROM employees; #① 初始化条件 + while_label:WHILE TRUE DO #② 循环条件 + #③ 循环体 + IF avg_sal <= 10000 THEN + LEAVE while_label; + END IF; + 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 ; +``` + +### 7) 跳转语句之ITERATE语句 + +ITERATE语句:只能用在循环语句(LOOP、REPEAT和WHILE语句)内,表示重新开始循环,将执行顺序转到语句段开头处。如果你有面向过程的编程语言的使用经验,你可以把 ITERATE 理解为 continue,意思为“再次循环”。 + +语句基本格式如下: + +```mysql +ITERATE label +``` + +label参数表示循环的标志。ITERATE语句必须跟在循环标志前面。 + +举例: 定义局部变量num,初始值为0。循环结构中执行num + 1操作。 + +* 如果num < 10,则继续执行循环; +* 如果num > 15,则退出循环结构; + +```mysql +DELIMITER // +CREATE PROCEDURE test_iterate() +BEGIN + DECLARE num INT DEFAULT 0; + my_loop:LOOP + SET num = num + 1; + IF num < 10 + THEN ITERATE my_loop; + ELSEIF num > 15 + THEN LEAVE my_loop; + END IF; + SELECT 'MySQL'; + END LOOP my_loop; +END // +DELIMITER ; +``` + +## 作业 + +```mysql +create database work2_18 charset utf8; +use work2_18; +-- 写一个存储过程,可以输入一个整数,输入小于或等于0时,提示非法输入,并中止这个存储过程, +-- 否则先判断这个数和是不是大于20,如果大于20就从1循环到这个数,并找出所有的偶数(但遇到逢10的数要跳过)。小于等于20就提示数太小了,并退出。 + +-- 要求,循环部分,要用三种语法分别做一遍 +drop procedure p1; -- loop +delimiter // +create procedure p1(in num int) +begin +declare i int default 1; +a:loop + if num<=0 then select '非法输入';leave a; + elseif num<=20 then select '数太小了';leave a; + else + b:loop + if i%10=0 then iterate b; + end if; + if i%2=0 then select i; + end if; + if i>=num then leave b; + end if; + set i=i+1; + end if; + end loop a; +end // +delimiter ; +call p1(14); + +-- while + +delimiter // +create procedure p2(in num int) +begin +declare i int default 1; + if num<=0 then select '非法输入'; + elseif num<=20 then select '数太小了'; + else + while + i%2=0 do + b:while + i%10=0 do + c:while + i>=num do + leave c; + end while c; + iterate b; + end while b; + select i; + set i=i+1; + end while; + end if; +end // +delimiter ; +call p1(14); + +-- repeat + +delimiter // +create procedure p3(in num int) +begin +declare i int default 1; + if num<=0 then select '非法输入'; + elseif num<=20 then select '数太小了'; + else + a:repeat + if i%10=0 then iterate a; + end if; + if i%2=0 then select i; + end if; + set i=i+1; + until i>=num + end repeat a; + end if; +end // +delimiter ; +call p1(14); +``` +