当前位置: 首页 > news >正文

MySQL的存储过程

这一部分比较重要,加油!!!部分代码忘记保存了,嘻嘻,练习代码在最后,大家共勉!!!

通俗来讲,视图是死的,但是这个可以根据传入的参数不同来得到不同的结果,其实就是对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);
 

相关文章:

  • 数学复习笔记 12
  • 深入浅出 MinIO:身份管理与权限配置实战 !
  • C#学习第23天:面向对象设计模式
  • SD2351核心板:开启AI视觉普惠化新时代
  • 涂色不踩雷:如何优雅解决 LeetCode 栅栏涂色问题
  • Room数据库
  • 筑牢信息安全防线:涉密计算机与互联网隔离的理论实践与风险防控
  • 【pbootcms】打开访问首页显示未检测到您服务器环境的sqlite3数据库拓展,请检查php.ini中是否已经开启该拓展
  • 现代计算机图形学Games101入门笔记(十二)
  • React中使用openLayer画地图
  • 拟合(最小二乘拟合)
  • React Flow 节点类型详解与实战:内置节点使用与自定义组件开发
  • 58. 区间和
  • 【GaussDB迁移攻略】DRS支持CDC,解决大规模数据迁移挑战
  • 【软件工程】符号执行与约束求解缺陷检测方法
  • 前端精度问题全解析:用“挖掘机”快速“填平精度坑”的完美解决方案
  • 深入探索:Core Web Vitals 进阶优化与新兴指标
  • AWS云入门宝典
  • 哈希表实现(1):
  • Spring Cloud:Gateway(统一服务入口)
  • 当智慧农场遇见绿色工厂:百事如何用科技留住春天的味道?
  • 机器人为啥热衷“搞体育”,经济日报:是向加速融入日常生活发起的冲锋
  • 南宁一学校发生伤害案件,警方通报:嫌疑人死亡,2人受伤
  • 科普|认识谵妄:它有哪些表现?患者怎样走出“迷雾”?
  • 李成钢:近期个别经济体实施所谓“对等关税”,严重违反世贸组织规则
  • 收到延期付款利息,该缴纳增值税吗?