存储过程类似于其他编程语言的函数学到现在发现 select 相当于其他编程语言里的 print不能修改存储过程只能删除后重新创建删除语法drop procedure 存储过程名;练习用的数据CREATE TABLE dept( deptno INT PRIMARY KEY, dname VARCHAR(20), loc VARCHAR(20) ); INSERT INTO dept VALUES(10, 教研部,北京), (20, 学工部,上海), (30, 销售部,广州), (40, 财务部,武汉); create table if not exists emp( empno int primary key, ename varchar(20), job varchar(20), mgr int, hiredate date, sal numeric(8,2), -- 与 decimal 类型具有相同的含义用于存储精确的小数值。 comm numeric(8, 2), -- 该字段的总长度为 8其中小数位数为 2 deptno int, FOREIGN KEY (deptno) REFERENCES dept(deptno) ON DELETE SET NULL ON UPDATE CASCADE ); INSERT INTO emp VALUES(1001, 甘宁, 文员, 1013, 2000-12-17, 8000.00, null, 20), (1002, 黛绮丝, 销售员, 1006, 2001-02-20, 16000.00, 3000.00, 30), (1003, 殷天正, 销售员, 1006, 2001-02-22, 12500.00, 5000.00, 30), (1004, 刘备, 经理, 1009, 2001-4-02, 29750.00, null, 20), (1005, 谢逊, 销售员, 1006, 2001-9-28, 12500.00, 14000.00, 30), (1006, 关羽, 经理, 1009, 2001-05-01, 28500.00, null, 30), (1007, 张飞, 经理, 1009, 2001-09-01, 24500.00, null, 10), (1008, 诸葛亮, 分析师, 1004, 2007-04-19, 30000.00, null, 20), (1009, 曾阿牛, 董事长, null, 2001-11-17, 50000.00, null, 10), (1010, 韦一笑, 销售员, 1006, 2001-09-08, 15000.00, 0.00, 30), (1011, 周泰, 文员, 1008, 2007-05-23, 11000.00, null, 20), (1012, 程普, 文员, 1006, 2001-12-03, 9500.00, null, 30), (1013, 庞统, 分析师, 1004, 2001-12-03, 30000.00, null, 20), (1014, 黄盖, 文员, 1007, 2002-01-23, 13000.00, null, 10); create table if not exists salgrade( grade int primary key, losal int, hisal int ); INSERT INTO salgrade VALUES(1,7000,12000), (2,12010,14000),(3,14010,20000),(4,20010,30000);定义变量局部变量default是设定默认值。方式1方式2用户变量系统变量参数传递in练习1、 通过传入员工编号查询员工信息2、 通过传入部门名和薪资查询指定部门并且薪资大于指定值的员工信息-- 通过传入员工编号查询员工信息 delimiter $$ create PROCEDURE proc03(in p_empno int) begin select * from emp where empno p_empno; end $$ delimiter ; call proc03(1001); -- 通过传入部门名和薪资查询指定部门并且薪资大于指定值的员工信息 delimiter $$ CREATE PROCEDURE proc04(IN p_dname VARCHAR(20),in p_sal int) BEGIN SELECT * FROM emp,dept WHERE emp.deptnodept.deptno and dept.dnamep_dname and salp_sal; END $$ delimiter ; call proc04(销售部,13000);out-- 封装有参数的存储过程传入员工编号返回员工名字和薪资 delimiter $$ CREATE PROCEDURE proc05(IN p_empno INT,OUT p_ename VARCHAR(20),OUT p_sal INT) BEGIN SELECT ename,sal into p_ename,p_sal FROM emp WHERE empnop_empno; END $$ delimiter ; call proc05(1001,o_ename,o_sal); SELECT o_ename,o_sal;inout-- 传入员工名拼接部门号传入薪资求出年薪 delimiter $$ CREATE PROCEDURE proc06(inout p_ename VARCHAR(20),inout p_sal int) BEGIN select concat(deptno,_,ename) into p_ename from emp where ename p_ename; set p_salp_sal*12; end $$ delimiter ; set o_ename 关羽; set o_sal 3000; call proc06(o_ename,o_sal); SELECT o_ename,o_sal;流程控制分支语句if练习-- 输入学生的成绩来判断成绩的级别:score60:不及格score 60score80:及格score 80,score 90 :良好score 90,score 100:优秀score100:成绩错误delimiter $$ create procedure proc07_if(in in_score int) begin if in_score 60 then select 不及格; elseif in_score 80 then select 及格; elseif in_score90 then select 良好; elseif in_score100 then select 优秀; else select 成绩错误; end if; end $$ delimiter ; call proc07_if(120);-- 输入员工的名字判断工资的情况。sal10000:试用薪资sal 10000 and sal20000:转正薪资sal20000:元老薪资delimiter $$ create procedure proc08_if(in in_name varchar(20)) BEGIN declare p_sal varchar(20); declare state varchar(20); select sal into p_sal from emp where enamein_name; if p_sal 10000 then set state 试用薪资; elseif p_sal 20000 then set state 转正薪资; ELSE set state 元老薪资; end if; select state; end $$ delimiter ; call proc08_if(张飞);caseend case 结束要加分号;1、支付方式1微信支付、2支付宝支付、3银行卡支付、其他支付2、 输入学生的成绩来判断成绩的级别:score60:不及格score 60score80:及格score 80,score 90 :良好score 90,score 100:优秀score100:成绩错误delimiter $$ create procedure proc09_case(in type int) begin declare res varchar(20); case type when 1 then set res微信支付; when 2 then set res支付宝支付; when 3 then set res银行卡支付; else set res其他支付; end case; select res; end $$ delimiter ; call proc09_case(2); -- ------------------------------------------------------------- delimiter $$ create procedure proc10_case(in in_score int) begin case when in_score 60 then select 不及格; when in_score 80 then select 及格; when in_score90 then select 良好; when in_score100 then select 优秀; else select 成绩错误; end case; end $$ delimiter ; call proc10_case(120);循环语句while常用数据准备create table user( uid int PRIMARY KEY, uname varchar(50), password varchar(50) );1、向表中循环添加五条数据delimiter $$ create procedure proc11_while(in in_count int) begin declare i int default 1; label:while iin_count do insert into user(uid,uname,password) values(i,concat(user-,i),123456); set i i1; end while label; end $$ delimiter ; call proc11_while(5);运行结果用truncate table user;把表中的数据清除了再对这个表进行新的插入操作2、当加了五条数据就跳出循环delimiter $$ create procedure proc12_while(in in_count int) begin declare i int default 1; label:while iin_count do insert into user(uid,uname,password) values(i,concat(user-,i),123456); if i 5 then leave label; end if; set i i1; end while label; end $$ delimiter ; call proc12_while(10);运行结果3、跳过编号5的数据插入delimiter $$ create procedure proc13_while(in in_count int) begin declare i int default 0; label:while iin_count do set i i1; if i 5 then iterate label; end if; insert into user(uid,uname,password) values(i,concat(user-,i),123456); end while label; end $$ delimiter ;repeat类似于do...while...循环1、向表中循环添加5条数据delimiter $$ create procedure proc14_repeat(in cnt int) begin declare i int default 1; REPEAT insert into user(uid,uname,password) values(i,concat(user-,i),645645); set ii1; UNTIL icnt END REPEAT; end $$ delimiter ; call proc14_repeat(5);loop1、向表中循环添加5条数据delimiter $$ create procedure proc15_loop(in cnt int) begin declare i int default 1; label:loop insert into user(uid,uname,password) values(i,concat(user-,i),645645); set ii1; if icnt then leave label; end if; END loop; end $$ delimiter ; call proc15_loop(5);游标用例需求:输入一个部门名查询该部门员工的编号、名字、薪资将查询的结果集添加游标。delimiter $$ CREATE PROCEDURE proc16_cursor(in in_dname varchar(20)) BEGIN declare t_num int; declare t_name varchar(20); declare t_sal decimal(8,2); -- 声明游标 declare my_cursor cursor for select empno,ename,sal from dept a,emp b where a.deptnob.deptno and a.dname in_dname; -- 打开游标 open my_cursor; label: LOOP -- 取值 fetch my_cursor into t_num,t_name,t_sal; select t_num,t_name,t_sal; END LOOP label; -- 关闭游标 close my_cursor; END $$ delimiter ; call proc16_cursor(销售部);运行结果运行一次fetch查询结果表中的一行所以有这么多结果按理来说我们写的这个循环的一个死循环但是它没有一直循环下去而是在最后报错了就是下图的情况。这和游标的读取方式有关它是在表中一个一个往下查的到查不到的时候就报错了。异常处理对于上面这种报错情况就需要用到异常处理了。大概就是你在写的时候遇到报错的一些情况之后你来安排一下接下来怎么办可以使代码顺利运行完成。针对上面游标的情况增加一个异常处理来进行优化delimiter $$ CREATE PROCEDURE proc17_handler(in in_dname varchar(20)) BEGIN -- 定义局部变量 declare t_num int; declare t_name varchar(20); declare t_sal decimal(8,2); -- 定义标记值 declare flag int default 1; -- 声明游标 declare my_cursor cursor for select empno,ename,sal from dept a,emp b where a.deptnob.deptno and a.dname in_dname; -- 定义句柄异常处理方式 /* 1:异常处理完之后程序该怎么执行continue:继续执行剩余代码exi计:直接终止程序undo:不支持 2:触发条件 条件码: 如1329 条件名: SQLWARNING NOT FOUND SQLEXCEPTION 3:异常触发之后执行什么代码 */ declare continue handler for 1329 set flag0; -- 打开游标 open my_cursor; label: LOOP -- 取值 fetch my_cursor into t_num,t_name,t_sal; if flag1 then select t_num,t_name,t_sal; else leave label; end if; END LOOP label; -- 关闭游标 close my_cursor; END $$ delimiter ; call proc17_handler(销售部);运行结果这个时候就不会有报错了