SQL第8/n篇(更新中)存储过程与函数

存储过程

含义:一组预先编译好的sql语句,可以理解成批处理语句,有点类似于函数
优点:
提高代码重用性,
简化操作,
减少编译次数和数据库服务器的连接次数,提高效率

一、创建语法

 create procedure 存储过程名(参数列表)
 begin

      存储过程体(一组合法的sql语句)
 end

注意:
1.参数列表包含三部分
参数模式 参数名 参数类型
举例:
in fun_name varchar(20)

参数模式
in:输入,需要调用方传入值
out:输出,可以作为返回值
inout:既可以作为输入又可以作为输出,既要传入值又可以返回值

2.加入存储过程体只有一句话,begin end 可以省略
存储过程体中的结尾必须加分号,存储过程体的结尾用delimiter重新设置
语法:
delimiter 结束标志
举例:delimiter $

二、调用方法:

CALL 存储过程名(实参列表)
in : call myp(值)out: set @name call myp(@name)inout: set @name=值 call myp(@name)$

1.空参列表

案例:向gils库中的admin表插入5条数据

SELECT * FROM admin; #id is AUTO_INCREMENT


DELIMITER $
CREATE PROCEDURE myp1()
BEGIN 

    INSERT INTO admin (username,`password`)
    VALUES('a','111'),('b','112'),('c','113'),
    ('d','114'),('e','115'),('f','116');
END $

CALL myp1()$

注意结束符号的使用


myp1-执行.png

插入后的结果


myp1.png

2.创建带in参数的存储过程

案例:创建存储过程,根据女神名查询对应的男神的信息

CREATE PROCEDURE myp2(IN beautyName VARCHAR(20))
BEGIN

    SELECT bo.* FROM boys bo RIGHT JOIN beauty b
    ON bo.id=b.boyfriend_id
    WHERE b.name=beautyName;
END$

CALL myp2('杨紫')$

cmd中设置字符集,显示中文。


myp2-in参数.png

案例:创建存储过程,用户是否登录(admin里存在即登录成功,查询个数>=1)

CREATE PROCEDURE myp3(IN username VARCHAR(20), IN `password` VARCHAR(20))
BEGIN

    DECLARE result INT DEFAULT 0;#变量的声明与初始化
    
    SELECT COUNT(*) INTO result  #赋值
    FROM admin
    WHERE admin.`username`=username #加表的前缀以区分,或者起别名
    AND admin.`password`=`password`;
    
    SELECT IF(result>0,'已登录','未登录');#变量的使用
END$

CALL myp3('张飞','0000')$

if函数的使用


myp3.png

3.带out参数的存储过程

案例:根据女神名,返回对应的男神名

CREATE PROCEDURE myp5(IN beautyName VARCHAR(20),OUT girlName VARCHAR(20),OUT boyName VARCHAR(20))
BEGIN
    SELECT b.name ,bo.boyName INTO  girlName,boyName
    FROM beauty b JOIN boys bo
    ON b.boyfriend_id =bo.id
    WHERE b.name=beautyName;
END$

SET @bName$
CALL myp5('李沁',@bName)$

#或者 直接使用用户变量@bName
CALL myp5('杨紫',@bName,@boName)$
SELECT @bName,@boName$

多个out 的形式


多个out.png

4.带inout参数法存储过程

案例:传入a,b,将a,b翻倍并返回

CREATE PROCEDURE myp6(INOUT a INT , INOUT b INT)
BEGIN
    SET a=a*2;
    SET b=b*2;
END$

SET @m=10$
SET @n=20$
CALL myp6(@m,@n)$  #调用的时候传入的是变量,所以先去声明变量
SELECT @m,@n$
inout参数.png

三、删除存储过程

一次只能删除一个
语法: drop procedure 存储过程名

DROP PROCEDURE myp4;

四、查看存储过程信息

SHOW CREATE PROCEDURE myp5;
不能修改存储过程中间的sql语句,想修改的话,直接删掉重新建。

五、案例练习

1.创建存储过程或者函数,传入日期,返回xx年xx月xx日

CREATE PROCEDURE test_myp1(IN mydate DATETIME, OUT date_str VARCHAR(50))
BEGIN
    SELECT DATE_FORMAT(mydate,'%y年%m月%d日') INTO date_str;
END$

CALL test_myp1(NOW(),@str_date)$
SELECT @str_date$
test1.png

2.根据女神名,返回'女神名 and 男神名',如果女神没有对应的男神,返回 '女神名 and null'
与之前的多输出进行对比,看看区别与联系,concat的使用,ifnull的使用

DROP PROCEDURE test_myp2$
CREATE PROCEDURE test_myp2(IN beautyName VARCHAR(20),OUT str VARCHAR(50))
BEGIN
    SELECT CONCAT(beautyName ,' and ',IFNULL(bo.boyName,'null')) INTO str
    FROM beauty b LEFT JOIN boys bo
    ON b.boyfriend_id =bo.id
    WHERE b.name=beautyName;
END$


CALL test_myp2('苍老师',@result)$
SELECT @result$
concat连接.png

3.根据传入的条目数和起始索引,查询beauty表的记录

CREATE PROCEDURE test_myp3( IN start_index INT,IN size INT )
BEGIN 
    SELECT * FROM beauty LIMIT  start_index,size;
END$

CALL test_myp3(3,5)$

limit的使用,起始索引,显示条数;


limit.png

函数

含义与优点与存储过程相同
区别:
存储过程:可以有0个返回值也可以有多个返回值,适合批量插入,更新
函数:有且只有1个返回值,适合处理数据后返回一个结果

一、创建语法

      CREATE FUNCTION 函数名(参数列表) RETURNS 返回类型
      BEGIN

          函数体
      END

注意:
1.参数列表包含两部分:参数名 参数类型

2.函数体:肯定要有return语句,如果ruturn语句没有放在函数体最后也不报错,但是不建议
3.函数仅有一条语句,begin end 可以省略
4.使用delimiter 设置结束标记

二、调用函数

  SELECT 函数名(参数列表)

三、案例演示

1.无参数

返回员工个数

USE `myemployees`$
CREATE FUNCTION myf1() RETURNS INT
BEGIN
    DECLARE c INT DEFAULT 0;
    
    SELECT COUNT(*) INTO c
    FROM `employees`;
    
    RETURN c;
END$

SELECT myf1()$

2.有参数

根据员工名返回他的工资

CREATE FUNCTION myf2(employee_name VARCHAR(20)) RETURNS DOUBLE
BEGIN
    SET @sal=0;
    SELECT salary  INTO @sal
    FROM `employees`
    WHERE `last_name`=employee_name ;
    
    RETURN @sal;
END$

SELECT myf2('Kochhar')$

3.根据部门名返回该部门的平均工资

DROP FUNCTION myf3$
CREATE FUNCTION myf3(department_name VARCHAR(20)) RETURNS DOUBLE
BEGIN
    DECLARE result DOUBLE ;
    
    SELECT AVG(salary) INTO result
    FROM employees e JOIN `departments` d
    ON e.`department_id`=d.`department_id`
    WHERE d.`department_name`=department_name;
    
    RETURN result;
END$

SELECT myf3('Exe')$

三、查看与删除

SHOW CREATE FUNCTION myf3;
DROP FUNCTION myf3;
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,911评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,014评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,129评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,283评论 1 264
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,159评论 4 357
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,161评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,565评论 3 382
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,251评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,531评论 1 292
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,619评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,383评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,255评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,624评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,916评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,199评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,553评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,756评论 2 335