mysql存储过程和存储函数

2023-10-26

一、存储过程概述

1、mysql存储过程和存储函数是将复杂sql集合在一起,应用程序只需调用即可,不必关注mysql存储过程和存储函数sql逻辑

存储过程预先经过编译的一组sql,存储在 MySQL 服务器上,需要执行的时候,客户端只需要向服务器端发出调用存储过程的命令,服务器端就可以把预先存储好的这一系列 SQL 语句全部执行。

2、好处

  • 简化操作,提高了sql语句的重用性,减少了开发程序员的压力
  • 减少操作过程中的失误,提高效率
  • 减少网络传输量 (客户端不需要把所有的 SQL 语通过网络发给服务器
  • 减少了 SOL 语句暴露在网上的风险,也提高了数据查询的安全性

3、存储过程和视图、函数的对比
它和视图有着同样的优点,清晰、安全,还可以减少网络传输量。不过它和视图不同,视图是 虚拟表,通常不对底层数据表直接操作,而存储过程是程序化的 SOL,可以 直接操作底层数据表,相比于面向集合的操作方式,能
够实现一些更复杂的数据处理
-旦存储过程被创建出来,使用它就像使用函数一样简单,我们直接通过调用存储过程名即可。相较于函数,存储过程是 没有返回值 的。

4、分类

存储过程的参数类型可以是IN、OUT和INOUT。根据这点分类如下
1、没有参数(无参数无返回)
2、仅仅带 IN 类型 (有参数无返回)
3、仅仅带 OUT 类型 (无参数有返回)
4、既带 IN 又带 OUT (有参数有返回)
5、带INOUT (有参数有返回)
注意: IN、OUT、INOUT 都可以在一个存储过程中带多个

二、存储过程和调用

1、创建储存过程

语法

CREATE PROCEDURE 存储过程名(IN|OUT|INOUT 参数名 参数类型,...)
[characteristics ...]
BEGIN
	存储过程体
END

说明

1、参数

  • IN:输入参数,存储过程读取该参数的值,参数默认类型为IN
  • OUT:输出参数,经存储过程处理后,应用程序可以读取该参数值
  • INOUT:既可以作为输入参数,也可以作为输出参数

2、characteristics 表示创建存储过程时指定的约束条件,取值信息如下:

characteristic 说明
LANGUAGE SQL 说明存储过程由SQL语句组成
[NOT] DETERMINISTIC 指明存储过程执行的结果是否确定,默认为:NOT DETERMINISTIC
{CONTAINS SQL / NO SQL / READS SQL DATA / MODIFIES SQL DATA } 指明子程序使用SQL语句的限制, 默认为:CONTAINS SQL
SQL SECURITY { DEFINER / INVOKER } 指明执行当前存储过程的权限,默认为:DEFINER
COMMENT 'string' 注释信息

3、存储过程中的SQL语句需要放在 BEGIN … END 中

  • BEGIN…END:BEGIN…END 中间包含了多个语句,每个语句都以(;)号为结束符
  • DECLARE:DECLARE 用来声明变量,使用的位置在于 BEGIN…END 语句中间,而且需要在其他语句使用之前进行变量的声明
  • SET:赋值语句,用于对变量进行赋值
  • SELECT… INTO:把从数据表中查询的结果存放到变量中,也就是为变量赋值 

  4、需要设置新的结束标记 DELIMITER 新的结束标记

举例

#sql语句是;结束执行的 ,为了sql组完整执行,DELIMITER 定义新的结束符号,符号自定义
DELIMITER $
CREATE PROCEDURE select_all_data()
BEGIN
	SELECT * FROM emps;
END $
#结束之后再改;
DELIMITER ;


# 举例2:创建存储过程avg_employee_salary(),返回所有员工的平均工资
DELIMITER //
CREATE PROCEDURE avg_employee_salary()
BEGIN
	SELECT AVG(salary) FROM emps;
END //
DELIMITER ;


# 举例3:创建存储过程show_max_salary(),用来查看“emps”表的最高薪资值
DELIMITER //
CREATE PROCEDURE show_max_salary()
BEGIN
	SELECT MAX(salary) FROM emps;
END //
DELIMITER ;


# 举例4:创建存储过程show_min_salary(),查看“emps”表的最低薪资值。并将最低薪资通过OUT参数“ms”输出
DESC emps;

DELIMITER //
CREATE PROCEDURE show_min_salary(OUT ms DOUBLE)
BEGIN
	SELECT MIN(salary) INTO ms FROM emps;
END //
DELIMITER ;


# 举例5:创建存储过程show_someone_salary(),查看“emps”表的某个员工的薪资,并用IN参数empname输入员工姓名
DELIMITER //
CREATE PROCEDURE show_someone_salary(IN empname VARCHAR(25))
BEGIN
	SELECT salary FROM emps WHERE last_name = empname;
END //
DELIMITER ;


# 举例6:创建存储过程show_someone_salary2(),查看“emps”表的某个员工的薪资,并用IN参数empname输入员工姓名,用OUT参数empsalary输出员工薪资
DELIMITER //
CREATE PROCEDURE show_someone_salary2(IN empname VARCHAR(25), OUT empsalary DOUBLE)
BEGIN
	SELECT salary INTO empsalary FROM emps WHERE last_name = empname;
END //
DELIMITER ;


# 举例7:创建存储过程show_mgr_name(),查询某个员工领导的姓名,并用INOUT参数“empname”输入员工姓名,输出领导的姓名
DELIMITER //
CREATE PROCEDURE show_mgr_name(INOUT empname VARCHAR(25))
BEGIN
	SELECT last_name INTO empname FROM emps
	WHERE employee_id = (SELECT manager_id FROM emps WHERE last_name = empname);
END //
DELIMITER ;

2、存储过程调用

调用格式

CALL 存储过程名(实参列表);
若要执行其他数据库中的存储过程,需要指明数据库名: CALL dbname.procname;

  • 调用IN模式的参数:
    CALL procname(‘值’);
  • 调用OUT模式的参数:
    SET @name;
    CALL procname(@name);
    SELECT @name;
  • 调用INOUT模式的参数:
    SET @name=值;
    CALL procname(@name);
    SELECT @name;

以此调用上面1中创建好存储过程

# 2.2节中举例1
CALL select_all_data();

# 2.2节中举例2
CALL avg_employee_salary();

# 2.2节中举例3
CALL show_max_salary();

# 2.2节中举例4
SET @ms;
CALL show_min_salary(@ms);
SELECT @ms;

# 2.2节中举例5
SET @empname='Abel';
CALL show_someone_salary(@empname);

# 2.2节中举例6
SET @empname='Abel';
SET @empsalary;
CALL show_someone_salary2(@empname, @empsalary);
SELECT @empname, @empsalary;

# 2.2节中举例7
SET @empname='Abel';
CALL show_mgr_name(@empname);
SELECT @empname;
# 举例8:创建存储过程,实现累加运算,计算 1+2+…+n 等于多少
DELIMITER //
CREATE PROCEDURE add_num(IN n INT)
BEGIN
	DECLARE i INT;
	DECLARE `sum` INT;
	SET i = 1;
	SET `sum` = 0;
	
	WHILE i <= n DO
		SET `sum` = `sum` + i;
		SET i = i + 1;
	END WHILE;
	
	SELECT `sum`;
END //
DELIMITER ;

CALL add_num(50);

 可以通过SELECT语句把程序的中间结果查询出来,来调试一个SQL语句的正确性。

三、存储函数创建和调用

1、语法格式

说明:

  1. 参数列表:指定参数为IN,OUTINOUT只对PROCEDURE是合法的,FUNCTION中总是默认为IN参数
  2. RETURNS type 语句表示函数返回数据的类型
  3. characteristic 创建函数时指定对函数的约束,取值与存储过程相同
  4. 函数体也用BEGIN...END来表示SQL代码的开始和结束

调用方式

SELECT 函数名(实参列表); 

注意:若在创建存储函数中报错“ you might want to use the less safe log_bin_trust_function_creators variable ”,有两种处理方法:

  • 方式1:加上必要的函数特性“[NOT] DETERMINISTIC”和“{CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA}
  • 方式2:SET GLOBAL log_bin_trust_function_creators = 1;

 举例

# 举例1:创建存储函数,名称为email_by_name(),参数定义为空,该函数查询Abel的email,并返回,数据类型为字符串型
SET GLOBAL log_bin_trust_function_creators = 1;

DESC emps;

DELIMITER //

CREATE FUNCTION email_by_name()
RETURNS VARCHAR(25)
BEGIN
	RETURN (SELECT email FROM emps WHERE last_name = 'Abel');
END //

DELIMITER ;

SELECT email_by_name();


# 举例2:创建存储函数,名称为email_by_id(),参数传入emp_id,该函数查询emp_id的email,并返回,数据类型为字符串型
DELIMITER //

CREATE FUNCTION email_by_id(emp_id INT)
RETURNS VARCHAR(25)
BEGIN
	RETURN (SELECT email FROM emps WHERE employee_id = emp_id);
END //

DELIMITER ;

SELECT email_by_id(100);


# 举例3:创建存储函数count_by_id(),参数传入dept_id,该函数查询dept_id部门的员工人数,并返回,数据类型为整型
DELIMITER //

CREATE FUNCTION count_by_id(dept_id INT)
RETURNS INT
BEGIN
	RETURN (SELECT COUNT(*) FROM emps WHERE department_id = dept_id);
END //

DELIMITER ;

SELECT count_by_id(100);

 

2、对比存储函数和存储过程

关键字 调用语法 返回值 应用场景
存储过程 PROCEDURE CALL 存储过程() 理解为有0个或多个 一般用于更新
存储函数 FUNCTION SELECT 存储函数() 只能是一个 一般用于查询结果为一个值并返回时

存储函数可以放在查询语句中使用,存储过程不行。

四、存储过程和函数的查看、修改、删除

1、查看

使用SHOW CREATE语句查看存储过程和函数的创建信息

SHOW CREATE {PROCEDURE | FUNCTION} 存储过程或函数名;

SHOW CREATE PROCEDURE avg_employee_salary;

SHOW CREATE FUNCTION count_by_id;

使用SHOW STATUS语句查看存储过程和函数的状态信息

 SHOW {PROCEDURE | FUNCTION} STATUS [LIKE 'PATTERN'];

SHOW PROCEDURE STATUS LIKE 'avg_employee_salary';

SHOW PROCEDURE STATUS;	# 列出所有存储过程信息

SHOW FUNCTION STATUS LIKE 'count_by_id';

SHOW FUNCTION STATUS;	# 列出所有存储函数信息

information_schema.Routines表中查看存储过程和函数的信息 

SELECT * FROM information_schema.Routines WHERE ROUTINE_NAME = '存储过程或函数名' [AND ROUTINE_TYPE = {'PROCEDURE | FUNCTION'}];

SELECT * FROM information_schema.Routines;

SELECT * FROM information_schema.Routines WHERE ROUTINE_NAME = 'avg_employee_salary' AND ROUTINE_TYPE = 'PROCEDURE';

2、修改 

修改存储过程或函数,不影响存储过程或函数的功能,只是修改相关特性
ALTER {PROCEDURE | FUNCTION} 存储过程或函数名 [characteristic ...];

# 举例1:修改存储过程 show_someone_salary 的定义。将读写权限改为MODIFIES SQL DATA,并指明调用者可以执行
SELECT * FROM information_schema.Routines WHERE ROUTINE_NAME = 'show_someone_salary';

ALTER PROCEDURE show_someone_salary
MODIFIES SQL DATA
SQL SECURITY INVOKER;

# 举例2:修改存储函数 email_by_name 的定义。将读写权限改为READS SQL DATA,并加上注释信息“FIND NAME”
SELECT * FROM information_schema.Routines WHERE ROUTINE_NAME = 'email_by_name';

ALTER FUNCTION email_by_name
READS SQL DATA
COMMENT 'FIND NAME';

3、删除

DROP {PROCEDURE | FUNCTION} [IF EXISTS] 存储过程或函数名;

DROP PROCEDURE IF EXISTS show_someone_salary;

DROP FUNCTION IF EXISTS email_by_name;

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

mysql存储过程和存储函数 的相关文章

  • Mysql带限制的删除语句

    我试图从表中删除行 但出现错误 DELETE FROM chat messages ORDER BY timestamp DESC LIMIT 20 50 我在 50 时收到此错误 您的 SQL 语法有错误 检查与您的 MySQL 服务器版
  • MySql 视图脚本中的注释

    可以这样做吗 我尝试过多个 gui mysql workbench navicat toad for mysql 但没有一个保存这样的注释 something important select something else importan
  • 无法与重定向器建立连接。确保“sql browser”服务正在运行

    所以我尝试这个 sql server 2012 由于这个错误我无法打开任何 ssis 包 无法与重定向器建立连接 确保 sql browser 服务正在运行 我的 Sql 浏览器肯定正在运行 我尝试在本地服务 本地系统和网络下更改它 仍然没
  • MySQL“列计数与第 1 行的值计数不匹配”是什么意思

    这是我收到的消息 ER WRONG VALUE COUNT ON ROW 列计数与第 1 行的值计数不匹配 这是我的全部代码 我的错误在哪里 DROP TABLE student CREATE TABLE employee emp id I
  • 是否可以从子查询中获取多个值?

    有没有办法让子查询在oracle db中返回多列 我知道这个特定的sql会导致错误 但它很好地总结了我想要的 select a x select b y b z from b where b v a v from a 我想要这样的结果 a
  • 计算2个日期之间每个日期的记录数

    我必须创建一个查询来返回多轴图表的结果 我需要计算为 2 个日期之间的每个日期创建的 ID 数量 我试过这个 DECLARE StartDate datetime2 7 11 1 2020 EndDate datetime2 7 2 22
  • Django 将 JSON 数据传递给静态 getJSON/Javascript

    我正在尝试从 models py 中获取数据并将其序列化为views py 中的 JSON 对象 模型 py class Platform models Model platformtype models CharField max len
  • 无法连接到 MAMP 上的 phpMyAdmin

    我收到此错误消息 MySQL 说道 无法连接 设置无效 phpMyAdmin 尝试连接 MySQL 服务器 但服务器拒绝连接 您应该检查配置中的主机 用户名和密码 并确保它们与 MySQL 服务器管理员提供的信息相对应 用户和通行证是默认的
  • rake db 问题:迁移 -

    我无法为 Ruby on Rails 设置 MySQL 数据库 设置数据库并确保 config database yml 文件匹配后 我遇到了以下错误消息 U Rails alpha gt rake db migrate trace in
  • 多边形内的 SQL 地理点在 STIntersect 上不返回 true(但使用 Geometry 返回 true)

    我不想仅仅为了在 STIntersect 中返回 true 而将地理数据转换为几何图形 下面是 SQL 中的代码 DECLARE point GEOGRAPHY GEOGRAPHY Point 1 1 4326 DECLARE polygo
  • mysql 如何将 varchar(10) 转换为 TIMESTAMP?

    我已将所有日期存储到数据库中varchar 10 现在我想将它们转换为 TIMESTAMP 当我运行sql时 ALTER TABLE demo3 CHANGE date date TIMESTAMP NOT NULL 它提醒 1292 In
  • MySQL InnoDB 约束不起作用

    我偶然发现 innoDB 约束的奇怪行为 但找不到原因 我有包含数据的表格 下面列出了它们的结构 CREATE TABLE contents id int 10 unsigned NOT NULL AUTO INCREMENT title
  • 如何从 MySQL 数据查询创建 XML 文件?

    我想知道一种仅使用 MySQL 查询创建 XML 文件的方法 根本不使用任何脚本语言 有关于这个主题的书籍 教程吗 UPDATE 我想澄清一下 我想使用 sql 查询将 XML 数据转发到 php 脚本 Here s 关于从 MySQL S
  • 使用 DISTINCT 进行查询需要很长时间

    我正在使用 Microsoft Access 2003 我的项目中的一个表单需要很长时间才能向用户显示 这是适用的查询 SELECT DISTINCT tb KonzeptDaten DFCC tb KonzeptDaten OBD Cod
  • 来自数据库的 jfreechart 散点图

    如何使用java中的jfreechart绘制mysql数据库表中数据的散点图 我使用过 Swing 库 任何链接都会有帮助 我搜索了谷歌但找不到理解的解决方案 如果您有代码 请提供给我 实际上我确实做了条形图并使用 jfreechart 绘
  • 如何在 SQL Server 2012 中选择除一列之外的所有列? [复制]

    这个问题在这里已经有答案了 有没有一种方法可以选择所有列 但只选择我不想选择的特定列 我的意思是有时我会遇到这样的问题 表有数百个字段 而我只需要删除一个字段 我需要重写所有列吗 有什么窍门吗 喜欢select
  • MySQL如何获取unix时间戳的时间差

    我有一个保存值1506947452的变量 需要使用公式从该日期提取分钟 started data now date 但started date采用unix时间戳格式10位int数字 我以ajax形式收到并需要放入mysql查询i试试这个 S
  • 使用函数的 SQL 查询 - 如何获取列表的最大计数

    如何查询 MAXIMUM COUNT 交易次数 我的代码如下 SELECT customer id COUNT customer id FROM rental GROUP BY customer id HAVING MAX COUNT cu
  • 替换字符串中的多个字符,而不使用任何嵌套替换函数

    我的表中存储了一个方程 我一次获取一个方程 并希望将所有运算符替换为任何其他字符 输入字符串 N 100 6858 6858 N 100 0 2 N 35 运算符或模式 替换字符 输出字符串 N 100 6858 6858 N 100 0
  • 使用 PHP 将 latin1_swedish_ci 转换为 utf8

    我有一个数据库 里面充满了类似的值 Dhaka 应该是 Dhaka 因为我在创建数据库时没有指定排序规则 现在我想修复它 我无法从最初获取数据的地方再次获取数据 所以我在想是否可以在 php 脚本中获取数据并将其转换为正确的字符 我已将数据

随机推荐

  • typescript基础之object和Object

    TypeScript 的 object 和 Object 是两种不同的类型 它们的区别和用途如下 object 类型是 TypeScript 2 2 引入的新类型 它表示非原始对象 也就是除了 number string boolean s
  • 实时时钟电路DS1302的原理及应用

    2006 05 11 10 10 39 实时时钟电路DS1302的原理及应用
  • 使用windeployqt.exe打包QT工程,windows系统可执行程序

    前言 因为自己打包qt程序遇到点问题 提示0xc000007b错误 发现是因为打包工具和工程编译工具不对应导致 于是为了记录打包方法 有了此篇文章 记录使用windeployqt exe打包qt工程在windows系统的可执行文件 一 确定
  • adb install 命令参数

    adb install 6个参数描述 t 允许测试包 l 锁定该应用程序 s 把应用程序安装到sd卡上 g 为应用程序授予所有运行时的权限 r 替换已存在的应用程序 也就是说强制安装 d 允许进行将见状 也就是安装的比手机上带的版本低
  • activiti-serviceTask(服务任务)

    Activiti服务任务 serviceTask Activiti服务任务 serviceTask 作者 邓家海 都有一段沉默的时间 等待厚积薄发 应用场景 当客户有这么一个需求 下一个任务我需要自动执行一些操作 并且这个节点不需要任何的人
  • 一文让你深刻理解异步请求池-DNS解析与实现

    一 DNS概念简述 DNS Domain Name Service 域名解析服务 工作在应用层 是互联网的一项服务 它作为将域名和IP地址相互映射的一个分布式数据库 能够使人更方便地访问互联网 DNS监听在TCP和UDP端口53 FQDN
  • SpringMVC系列(十)(处理静态资源)和...

  • 通俗理解泰勒公式

    本博客只用于自身学习 如有错误 虚心求教 在维基百科上的解释 在数学中 泰勒公式 英语 Taylor s Formula 是一个用函数在某点的信息描述其附近取值的公式 这个公式来自于微积分的泰勒定理 Taylor s theorem 泰勒定
  • 计算方法——C语言实现——迭代法求解线性方程组

    最近在上计算方法这门课 要求是用MATLAB做练习题 但是我觉得C语言也很棒棒啊 题目 和直接法不同 迭代法是一种逐次逼近的方法 将复杂问题简单化 求比较大的方程组时一般都不会用直接法 迭代法有好几种 这里使用了Jacobi迭代与Gauss
  • 8.4收官之战非农蓄力能否引爆黄金单边行情?

    近期有哪些消息面影响黄金走势 黄金多空该如何研判 黄金消息面解析 周五 8月4日 亚洲时段 现货黄金在近三周低位窄幅震荡 目前交投于1937 60美元 盎司附近 美联储7月决策符合预期 如期加息25个基点 虽然美国通胀增速放缓 但仍高于美联
  • Git 大文件push失败

    目录 1 下载并安装Git Large File Storage命令行扩展 2 配置lfs跟踪的文件 3 commit 并push到远程仓库 由于git有push文件的大小限制 100MB 因此如果push操作中右超过100MB的文件 就会
  • 抽签小程序(C语言随机数),C# 抽签小程序

    设计背景 设置一个Excel名单表 对名单进行随机抽取 设计思路 使用Timer定时器 运行定时器进行名单随机滚动 停止定时器获得抽签结果 相关技术 随机数 Excel读取 导出 XML文档读写 相关类库 C1 C1Excel Excel操
  • 《深入浅出话数据结构》系列之什么是B树、B+树?为什么二叉查找树不行?

    本文将为大家介绍B树和B 树 首先介绍了B树的应用场景 为什么需要B树 然后介绍了B树的查询和插入过程 最后谈了B 树针对B树的改进 在谈B树之前 先说一下B树所针对的应用场景 那么B树是用来做什么的呢 B树是一种为辅助存储设计的一种数据结
  • 达梦DCA认证培训和考试

    本人有幸参加了达梦DCA认证培训并参加了认证考试 培训内容包括 第一天 国产数据库现状及未来 DM8企业版安装 创建数据库及数据库实例管理 DM8体系结构 第二天 表空间管理 用户管理 DMSQL 第三天 模式对象管理 备份还原 配置作业
  • 数据结构课程设计 最小生成树,拓扑排序以及最短路径

    通信网络的架设问题 问题描述 若要在n 10 个城市之间建设通信网络 只需要架设n 1条线路即可 如何以最低的经济代价建设这个通信网 是一个网的最小生成树问题 基本要求 1 利用二种方法 Prim算法和克鲁斯卡尔 Kruskual 生成网中
  • 阿里Java后端电话面试

    生平第一次面试 还是阿里 非常紧张 因为是校招 所以面的比较简单 都是我简历上说熟悉的东西 回答的不是很理想 面试官说我广度还行 深度差的比较多 面试官 你好同学 我是蚂蚁金服的 现在方便面试吗 我 方便方便 面试官 请简单介绍一下自己 这
  • Fultter学习日志(2)-构建第一个flutter应用

    依照上一篇中我们新建的flutter应用 让我们更改pubspec yaml中的内容为 name namer app description A new Flutter project publish to none Remove this
  • 在 Python Lambda 中使用 Await

    异步编程不是多线程或多进程 相反 它是并发编程 我们可以运行一个可能长时间运行的任务 并允许我们的程序在该任务仍在运行时响应其他任务 而不是等待完成 对于异步编程 HTTP 请求操作或用户选择可能会花费大量时间 因此 允许其他任务在这些操作
  • 100天精通Python(数据分析篇)——第72天:Pandas文本数据处理方法之判断类型、去除空白字符、拆分和连接

    文章目录 每篇前言 一 Python字符串内置方法 1 判断类型 2 去除空白字符 3 拆分和连接 二 Pandas判断类型 1 str isspace 2 str isalnum 3 str isalpha 4 str isdecimal
  • mysql存储过程和存储函数

    一 存储过程概述 1 mysql存储过程和存储函数是将复杂sql集合在一起 应用程序只需调用即可 不必关注mysql存储过程和存储函数sql逻辑 存储过程预先经过编译的一组sql 存储在 MySQL 服务器上 需要执行的时候 客户端只需要向