MySQL存储过程

网络 分享 时间: 收藏本文

MySQL存储过程

大佬教程收集整理的这篇文章主要介绍了存储过程,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。1.引言

存储过程是数据库的一个重要对象,可以封装SQL,完成一些复杂的业务逻辑。使用存储过程,最主要的特点是执行速度快,其经过编译后会比一条一条单独执行快,也能避免频繁的连接而消耗资源。

2.语法结构2.1创建的语法结构

语法结构如下:

create 
    [definer = user]
    procedure  procedure_name([proc_parameter[,...]])
    body

[ = user] 用来指定用户的执行权限,默认所有用户可用;

指定存储过程的名字;

指定存储过程的参数,类型有 in(入参)、out(出参)、(同时作为入参和出参);

body 中写程序体,只要是合法的sql即可。一般会以开始,以end结束,必须成对出现,通常一对即可。

在调用时,根据入参和出参,使用call关键字和存储过程名调用即可。

2.2删除的语法结构

drop procedure procedure_name

删除时指定存储过程名称即可,不能加括号。

2.3示例演示

1)创建存储过程

create procedure proc_test()
begin
    SELEct now() from dual;
end;

2)调用存储过程

call proc_test();

上述的存储过程仅是用来查询时间的,故执行结果是当前时间。

3)删除存储过程

drop procedure proc_test;

3.变量及赋值3.1局部变量

是用户自定义的变量,尽在/end块中有效。

1)语法

declare var_name type [default var_value];

使用关键字声明变量名和类型,可指定默认值。

2)使用set赋值

给变量赋值mysql存储过程怎么写,可以使用set和into关键字,对所有变量都适用。

create procedure proc_var01()
begin
    declare user_name varchar(50);#直接声明,无默认值
    declare age int(11) default 20;#声明的同时指定默认值
    set user_name = '张三';#赋值
    SELEct user_name,age; #查询
end;

若有多个set对其赋值,则最终值是最后一个set的结果。

2)使用into赋值

create procedure proc_var02()
begin
    declare create_time datetime;
    SELEct now() into create_time;
    SELEct create_time;
end;

若在中使用into给多个变量赋值,则使用逗号分隔即可,但前面的值和后面的变量必须一一对应。

3.2用户变量

用户自定义的变量mysql存储过程怎么写,在当前会话有效。

1)语法

@var_name #无需提前声明,使用即声明

2)赋值

create procedure proc_var03()
begin
    set @create_time = now();
    SELEct @create_time;
end;

可看出,并未声明就直接赋值,但变量名前面必须带@符号。

3.3会话变量

系统提供的变量,当前会话有效。由于用的不多,在此略。

3.4全局变量

系统提供的变量,整个服务有效。由于用的不多,在此略。

4.入参和出参4.1语法

in | out | inout param_name type
#in表示传入的参数
#out表示返回的参数
#inout表示传入的参数还作为返回的参数
#type表示参数的类型

4.2入参1)创建存储过程

传入名字进行查询:

create procedure proc_var04(in name varchar(50))
begin
    SELEct name;
end;

参数传入进来后就是局部变量,在整个存储过程内部可用,相当于方法的参数。若有多个参数,使用逗号分隔。

2)调用存储过程

call proc_var04('root');

4.3出参1)创建存储过程

根据传入的手机号,截取后4位返回:

create procedure proc_var05(in phone varchar(11),out phone_suffix varchar(4))
begin
    set phone_suffix = right(phone,4);
end;

2)调用存储过程

call proc_var05('15623524651',@suffiX);
SELEct @suffix;

执行结果是4651。需要注意的是,在接收输出参数时mysql存储过程怎么写,必须使用用户变量,否则接收不到,调用时还会出错。

4.4入参和出参1)创建存储过程

create procedure proc_var06(inout name varchar(100))
begin
    set name = concat('Hello,',Name);
end;

对结果处理后返回。

2)调用存储过程

set @username='张三';
call proc_var06(@userName);
SELEct @username;

5.判断(流程控制)5.1 if判断

if判断有if、if-else、if--else等。其条件在判断等于时用一个等号,条件后使用then,且以 if 开头 end if成对结尾。

1)仅有if

create procedure proc_var07(in age int)
begin
    declare msg varchar(20) default '';
    if age = 20 then
        set msg = '年龄为20';
    end if;
    SELEct msg;
end;

2)if-else

create procedure proc_var08(in age int)
begin
    declare msg varchar(20) default '';
    if age = 20 then
        set msg = '年龄为20';
    else
        set msg = '年龄不为20';
    end if;
    SELEct msg;
end;

3)if--else

create procedure proc_var09(in age int)
begin
    declare msg varchar(20) default '';
    if age > 20 then
        set msg = '年龄大于20';
    elseif age < 20 then
        set msg = '年龄小于20';
    else
        set msg = '年龄等于20';
    end if;
    SELEct msg;
end;

5.2 case分支1)case语法

case的语法有两种,如下,的查询使用case和存储过程使用case类似:

第一种:

case value
    when value1 then result1;
    when value2 then result2;
    when value3 then result3;
    #...可有多个
    else resultn;
end case;

第二种:

case
    when expr1 then result1;
    when expr2 then result2;
    when @R_740_8830@ then result3;
    #...可有多个
    else resultn
end case;

2)存储过程使用

create procedure proc_var10(in age int)
begin
    declare msg varchar(20) default '';
    case
        when age > 20 then
            set msg = '年龄大于20';
        when age < 20 then
            set msg = '年龄小于20';
        else
          set msg = '年龄等于20';
    end case;
    SELEct msg;
end;

6.循环(流程控制)6.1继续、结束循环

由于继续或结束循环常用在循环中,先行说明。

1)结束循环

用于结束循环,其后的语句不会执行。

2)继续循环

用于结束本次循环,进入下一次循环。

6.2 loop循环1)语法

[begin_label:] loop
    statement_list
end loop [begin_label]

是给该循环起个别名,当多个loop嵌套时结束循环需根据别名。另外loop是死循环,必须使用结束循环.

2)存储过程使用

打印1到10:

create procedure proc_var11()
begin
    declare msg varchar(200) default '1';
    declare curr int default 1;
    cnt:loop
    
      if curr >= 10 then
        leave cnt;#结束循环
      end if;
      set curr = curr + 1;
      set msg = concat(msg,',',curr);
        
    end loop cnt;
    
    SELEct msg;
end;

在不符合条件时结束循环。

打印1到10中偶数:

create procedure proc_var11()
begin
    declare msg varchar(200) default '';
    declare curr int default 1;
    cnt:loop
    
        if curr >= 10 then
            leave cnt;#结束循环
        end if;
            
        set curr = curr + 1;
        if (curr mod 2) then
            iterate cnt;
        else
            set msg = concat(msg,',',curr);    
        end if;            
        
    end loop cnt;
    
    SELEct msg;
end;        

在不符合条件时直接进入下一次循环。

6.3 循环1)语法

[begin_label:] repeat
    statement_list
until condition
end repeat [begin_label]

当后面的条件符合时结束循环,否则会一直循环。

2)存储过程使用

打印1到10:

create procedure proc_var12()
begin
    declare msg varchar(200) default '1';
    declare curr int default 1;
        
    cnt:repeat
        
      set curr = curr + 1;
      set msg = concat(msg,',',curr);
                
    until curr >= 10 #符合条件结束循环  
    end repeat cnt;
    
    SELEct msg;
end;

需要注意的是,后不能加逗号。

6.4 循环1)语法

[begin_label:] while condition do    
    statement_list
end while [begin_label]

2)存储过程使用

打印1到10:

create procedure proc_var13()
begin
    declare msg varchar(100) default '';
    declare curr int default 1;
    
    cnt:while curr<=10 do
        set msg = concat(msg,',',curr);
        set curr = curr + 1;
    end while;
    SELEct msg;
end;

7.游标7.1数据准备

创建表并添加数据

create table `emp` (
  `id` int(11) NOT NULL,
  `name` varchar(200) DEFAULT NULL COMMENT '姓名',
  `dept_no` varchar(32) DEFAULT NULL COMMENT '部门编号',
  `sal` decimal(10,2) DEFAULT NULL COMMENT '工资',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
create table `dept` (
  `dept_no` varchar(32) NOT NULL COMMENT '部门编号',
  `dept_name` varchar(200) DEFAULT NULL COMMENT '部门名称',
  PRIMARY KEY (`dept_no`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `dept`(`dept_no`, `dept_name`) VALUES ('A001', '策划部');
INSERT INTO `dept`(`dept_no`, `dept_name`) VALUES ('A002', '开发部');
INSERT INTO `dept`(`dept_no`, `dept_name`) VALUES ('A003', '人事部');
INSERT INTO `emp`(`id`, `name`, `dept_no`, `sal`) VALUES (1, '张飒', 'A002', 5000.00);
INSERT INTO `emp`(`id`, `name`, `dept_no`, `sal`) VALUES (2, '李敏', 'A003', 4500.00);
INSERT INTO `emp`(`id`, `name`, `dept_no`, `sal`) VALUES (3, '赵虹', 'A001', 4350.00);
INSERT INTO `emp`(`id`, `name`, `dept_no`, `sal`) VALUES (4, '赵敏敏', 'A002', 6530.00);
INSERT INTO `emp`(`id`, `name`, `dept_no`, `sal`) VALUES (5, '孙慧', 'A002', 7150.00);

2)查询开发部的所有员工的基本信息,包含工资:

SELEct emp.* from emp,dept
where emp.dept_no = dept.dept_no and dept.dept_name = '开发部';

若先使用存储过程给开发部所有员工加120块的工资,如何去做?

7.2游标语法

#声明游标
declare cursor_name for SELEct_statement
#打开游标
open cursor_name 
#遍历取值
fetch cursor_namE into var_name ...
#关闭游标,使用完后需关闭
close cursor_name 

游标的作用主要是遍历查询的结果集。故在声明游标时for后面就是的查询语句。

使用关键字进行遍历,但当结果集遍历到最后一条时,它会报错,错误码是1329,错误状态是,那么就需要使用(句柄)来判断异常进行处理。

需要注意的是,声明必须按照顺序,变量声明、游标声明、句柄声明的先后顺序不能错。

7.3使用游标

1)给开发部的员工涨工资的存储过程:

create procedure proc_var14(in dept_name varchar(200),in add_sal decimal)
begin
    declare user_id int;
    declare finished int default 0;
    
    declare cur_emp cursor for 
        SELEct e.id  from emp e,DEPT d
        where e.dept_no = d.dept_no and d.dept_name = dept_name;
        
    #声明句柄,
    declare conTinue handler for 1329 set finished = 1;
    open cur_emp;
    
    emp_loop:loop
        fetch cur_emp into user_id;
        if finished = 1 then 
            leave emp_loop;
        else
            update  emp e set sal = e.sal + add_sal where e.id = user_id;
        end if; 
    end loop emp_loop;
    
    close cur_emp;
end;

免责声明:本文系转载,版权归原作者所有;旨在传递信息,不代表本站的观点和立场和对其真实性负责。如需转载,请联系原作者。如果来源标注有误或侵犯了您的合法权益或者其他问题不想在本站发布,来信即删。

雕塑 信息流广告 竞价托管 招生通 古典文学 周易 易经 代理招生 二手车 剧本网 网络推广 自学教程 招生代理 旅游攻略 非物质文化遗产 河北信息网 石家庄人才网 买车咨询 河北人才网 招生考试 精雕图 戏曲下载 河北生活网 好书推荐 工作计划 游戏攻略 心理测试 石家庄网络推广 石家庄招聘 石家庄网络营销 培训网 好做题 游戏攻略 考研真题 代理招生 心理咨询 游戏攻略 兴趣爱好 网络知识 品牌营销 商标交易 游戏攻略 短视频代运营 张家口人才网 秦皇岛人才网 手游下载 育儿经验 PS修图 公务员考试 宝宝起名 零基础学习电脑 电商设计 职业培训 免费发布信息 服装服饰 律师咨询 搜救犬 Chat GPT中文版 语料库 范文网 工作总结 二手车估价 短视频剪辑 情侣网名 爱采购代运营 搬运熊 保定招聘 餐饮品牌 黄金回收价格 情感文案 吊车 古诗词 邯郸人才网 铁皮房 衡水人才网 石家庄点痣 微信运营 养花 名酒回收 石家庄代理记账 女士发型 搜搜作文 石家庄人才网 铜雕 关键词优化 围棋 chatGPT 读后感 玄机派 企业服务 法律咨询 chatGPT国内版 chatGPT官网 励志名言 儿童文学 河北代理记账公司 AI写作 风水运势 狗狗百科 教育培训 游戏推荐 抖音代运营 朋友圈文案 男士发型 培训招生 文玩 大可如意 石家庄招聘 保定人才网 沧州人才网 黄金回收 承德人才网 石家庄人才网 手游下载网 模型机 高度酒 沐盛有礼 公司注册 十亩地 公司起名 造纸术 唐山人才网 沐盛传媒 铜雕厂家