这一部分比较重要,加油!!!部分代码忘记保存了,嘻嘻,练习代码在最后,大家共勉!!!
通俗来讲,视图是死的,但是这个可以根据传入的参数不同来得到不同的结果,其实就是对sql的一个封装,封装成一个模块,一个函数
数据添加
一、入门案例
二、变量定义
局部变量
只在begin/end块中有效
可以直接给变量赋值
也可以通过select into给语句赋值
用户变量
MySQL服务器和navicat之间连接就是一个会话,会话存在时用户变量可以正常使用,会话不存在时无效
不需要声明,使用就是声明
离开了函数,也可以单独使用
系统变量
系统变量分为全局变量和会话变量
时MySQL提前给你定义好的,你不能随便定义,你可以查看和修改他的值
也就是,会话变量数据和全局变量一样,只是会话变量是全局变量的一个拷贝
但是全局变量修改会影响到整个服务器,但是对会话变量修改,只会影响到当前的会话(也就是当前的数据库连接)
全局变量
由系统提供,在整个数据库有效
会话变量
由系统提供,当前会话(连接)有效
会话变量和全局变量的语法基本上差不多,把全局变量的global改成session即可
三、参数传递
in
in表示传入的参数,可以传入数值或者变量,即使传入变量,并不会更改变量的值,可以内部更改,仅仅作用在函数范围内
其实就是定义一个参数,然后后续调用时,在传入相应的参数后,返回对应的值
相当于写了一个变量是param_empno,后续调用时直接传入这个变量相对应的值
也可以一次性传入多个参数,跟python很像,有基础的话会更好理解一点
out
out表示从存储过程内部传值给调用者
相当于调用时,给一个变量,会返回这个变量
返回多个变量
inout
inout表示从外部传入的参数经过修改后可以返回的变量,既可以使用传入变量的值也可以修改变量的值(即使函数执行完)
concat_ws是一个拼接函数
in、out、inout,三者的区别
in:输入参数,意思说你的参数要传到存储过程的过程里面去,在存储过程中修改该参数的值不能被返回
out:输出参数,该值可在存储过程内部被改变,并向外输出
inout:输入输出参数,既能输入一个值又能传出来一个值
四、流程控制
分支语句-if
if 语句包含多个条件判断,根据结果为TRUE、FALSE执行语句,与编程语言中的if、else if、else语法类似
elseif可以写多个
也可以直接输入
分支语句-case
case是另一个条件判断的语句,类似于编程语言中的switch语法
case格式2和if格式一模一样
循环语句-介绍
循环分类:while、repeat、loop
循环控制:leave类似于break,跳出,结束当前所在的循环
iterate类似于continue,继续,结束本次循环,继续下一次
循环语句-while
truncate table user;清空表的数据
while结合leave时,就需要加入标签了
while+leave
语句的位置不一样,也会造成不一样的效果
while+iterate
循环语句-repeat循环
语法都差不多,就是until这里不一样
循环语句-loop
五、游标cursor的使用
游标是用来存储查询结果集的数据类型,在存储过程和函数中可以使用光标对结果集进行循环的处理,光标的使用包括光标的声明、open、fetch和close。
游标的具体操作
六、异常处理-句柄handler
-- 定义句柄,就是异常的处理方式
-- 1、异常处理完之后程序改怎么执行
-- continue:继续执行剩余代码
-- exit:直接终止程序
-- undo:不用他,不支持
-- 2、触发条件 条件码:1329
-- 条件名:sqlwarning、not found、sqlexception
-- 3、异常触发之后执行什么代码 设置flag的值---》0
加上异常值的处理,就不会报错了
七、练习

预备知识
date_add就是给当前时间在加上一个时间段
获取下一个月的最后一天
结果代码展示
生成了下一个月的表
-- 思路:循环构建表名user_2021_11_01 到 user_2021_11_30:并执行create语句
create database mydb18_proc_demo;
use mydb18_proc_demo;
drop procedure if exists proc22_demo;
delimiter $$
create procedure proc22_demo()
begin
declare next_year int; -- 下一个月的年份
declare next_month int; -- 下一个月的月份
declare next_month_day int; -- 下一个月最后一天的日期
declare next_month_str varchar(2); -- 下一个月的月份字符串
declare next_month_day_str char(2); -- 下一个月的日字符串
-- 处理每天的表名
declare table_name_str char(10);
declare t_index int default 1;
-- 获取下个月的年份
set next_year =year(date_add(now(),interval 1 month)); -- 年份
-- 获取下个月是几月
set next_month = month(date_add(now(),interval 1 month)); -- 月份
-- 下个月最后一天是几号
set next_month_day = dayofmonth(last_day(date_add(now(),interval 1 month))); -- 日期
if next_month < 10
then set next_month_str = concat('0',next_month); -- 1 --> 01
else
set next_month_str = concat('',next_month); -- 11 -->11
end if;
while t_index <= next_month_day do
if (t_index < 10)
then set next_month_day_str = concat('0',t_index);
else
set next_month_day_str = concat('',t_index);
end if;
-- 2021_11_01
set table_name_str = concat(next_year,'_',next_month_str,'_',next_month_day_str);
-- 拼接create sql语句
set @create_table_sql = concat('create table user_',table_name_str,
'(uid int ,uname varchar(50),information varchar(50)) collate = \'utf8_general_ci\' engine = innodb');
-- from后面不能使用局部变量!
prepare create_table_stmt from @create_table_sql; -- 预处理
execute create_table_stmt; -- 执行预处理
deallocate prepare create_table_stmt; -- 将他释放
set t_index = t_index + 1;
end while;
end $$
delimiter ;
call proc22_demo;
八、总结
九、存储函数
和存储过程差不多
调用的时候直接调用即可
没有参数
有参数
传入参数时只用在后面加上传入参数的类型即可
十、部分代码
-- 思路:循环构建表名user_2021_11_01 到 user_2021_11_30:并执行create语句
create database mydb18_proc_demo;
use mydb18_proc_demo;
drop procedure if exists proc22_demo;
delimiter $$
create procedure proc22_demo()
begin
declare next_year int; -- 下一个月的年份
declare next_month int; -- 下一个月的月份
declare next_month_day int; -- 下一个月最后一天的日期
declare next_month_str varchar(2); -- 下一个月的月份字符串
declare next_month_day_str char(2); -- 下一个月的日字符串
-- 处理每天的表名
declare table_name_str char(10);
declare t_index int default 1;
-- 获取下个月的年份
set next_year =year(date_add(now(),interval 1 month)); -- 年份
-- 获取下个月是几月
set next_month = month(date_add(now(),interval 1 month)); -- 月份
-- 下个月最后一天是几号
set next_month_day = dayofmonth(last_day(date_add(now(),interval 1 month))); -- 日期
if next_month < 10
then set next_month_str = concat('0',next_month); -- 1 --> 01
else
set next_month_str = concat('',next_month); -- 11 -->11
end if;
while t_index <= next_month_day do
if (t_index < 10)
then set next_month_day_str = concat('0',t_index);
else
set next_month_day_str = concat('',t_index);
end if;
-- 2021_11_01
set table_name_str = concat(next_year,'_',next_month_str,'_',next_month_day_str);
-- 拼接create sql语句
set @create_table_sql = concat('create table user_',table_name_str,
'(uid int ,uname varchar(50),information varchar(50)) collate = \'utf8_general_ci\' engine = innodb');
-- from后面不能使用局部变量!
prepare create_table_stmt from @create_table_sql; -- 预处理
execute create_table_stmt; -- 执行预处理
deallocate prepare create_table_stmt; -- 将他释放
set t_index = t_index + 1;
end while;
end $$
delimiter ;
call proc22_demo;
-- 存储函数
create database mydb9_function;
use mydb9_function;
-- 准备数据
CREATE TABLE dept(
deptno INT PRIMARY KEY,
dname VARCHAR(20),
loc VARCHAR(20)
);
INSERT INTO dept VALUES(10, '教研部','北京'),
(20, '学工部','上海'),
(30, '销售部','广州'),
(40, '财务部','武汉');
CREATE TABLE emp(
empno INT PRIMARY KEY,
ename VARCHAR(20),
job VARCHAR(20),
mgr INT,
hiredate DATE,
sal NUMERIC(8,2),
comm NUMERIC(8, 2),
deptno INT,
-- FOREIGN KEY (mgr) REFERENCES emp(empno),
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);
-- 允许创建函数权限信任
set global log_bin_trust_function_creators = TRUE;
-- 创建存储函数-没有参数
drop function if exists myfunc1_emp;
delimiter $$
create function myfunc1_emp() returns int
begin
-- 定义局部变量
declare cnt int default 0;
select count(*) into cnt from emp;
return cnt;
end $$
delimiter ;
-- 调用存储函数
select myfunc1_emp();
-- 有参数
-- 传入一个员工的编号,返回员工的名字
drop function if exists myfunc2_emp;
delimiter $$
create function myfunc2_emp(in_empno int) returns varchar(50)
begin
declare out_ename varchar(50);
select ename into out_ename from emp where empno = in_empno;
return out_ename;
end $$
delimiter ;
-- 调用存储函数
select myfunc2_emp(1008);