存储过程 存储过程的创建语法如下:
CREATE
[DEFINER = user]
PROCEDURE [IF NOT EXISTS] sp_name ([proc_parameter[,...]])
[characteristic ...] routine_bodyproc_parameter:
[ IN | OUT | INOUT ] param_name typetype:
Any valid MySQL data typecharacteristic: {
COMMENT 'string'
| LANGUAGE SQL
| [NOT] DETERMINISTIC
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
}routine_body:
Valid SQL routine statement
routine_body 可以是简单的一句SELECT 和INSERT等语句,也可以是BEGIN…END组成的复合语句,在BEGIN…END中,可以使用IF、WHILE等控制语句组成的复杂逻辑。
DEFINER
DEFINER子句指定了在常规执行时为具有SQL SECURITY DEFINER特性的例程检查访问权限时要使用的MySQL账户。
显示指定,值应该是 ‘user_name’@‘host_name’, CURRENT_USER, 或 CURRENT_USER()。省略时等价于DEFINER = CURRENT_USER。
characteristic
- LANGUAGE SQL,这个是默认的,说是为以后支持SQL以外的其他语言准备的,先忽略
- [NOT] DETERMINISTIC:DETERMINISTIC指的是每次输入一样,那么输出也是一样的。默认是NOT DETERMINISTIC。官方文档只是提到,建议与实际结果保持一致,不然有可能会影响性能。
- { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }:
- CONTAINS SQL:表示不包含读或写数据的语句,这是默认值
- NO SQL:表示不包含SQL语句
- READS SQL DATA: 表示包含读数据的语句
- MODIFIES SQL DATA :表示包含写数据的语句
- SQL SECURITY:取值是DEFINER 或INVOKER,指明是以存储过程的创建者还是调用者的权限来执行。如果是INVOKER,存储过程内部访问了调用者不能访问的资源,会报错。默认值是DEFINER 。
- 严格模式下,数据类型不匹配或溢出,会报错
- 只有标量值可以赋值。像SET x = (SELECT 1, 2)这样的语句是无效的。
- 如果声明中包含CHARACTER SET,那么将使用指定的字符集及其默认的排序方式。如果COLLATE属性也存在,那么将使用该排序而不是默认的排序。如果没有指定字符集,会使用存储过程创建时数据库的字符集。之后改变数据库的字符集,不会自动应用到已存在的存储过程。
CREATE
[DEFINER = user]
FUNCTION [IF NOT EXISTS] sp_name ([func_parameter[,...]])
RETURNS type
[characteristic ...] routine_bodyfunc_parameter:
param_name typetype:
Any valid MySQL data typecharacteristic: {
COMMENT 'string'
| LANGUAGE SQL
| [NOT] DETERMINISTIC
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
}routine_body:
Valid SQL routine statement
【MySQL学习笔记|MySQL8.0学习记录16 - 存储过程与函数对比】函数的创建与存储过程相似,但是函数一定要有返回值(RETURNS type)。而且存储过程的参数可以用IN、OUT、INOUT等类型,函数的参数其实只是相当于IN。
函数与存储过程的对比
- 关键字不同,一个是FUNCTION ,另一个是PROCEDURE
- 函数必须要有返回值,存储过程没有
- 函数参数只能是IN,存储过程的参数类型可以是IN、OUT、INOUT
- 函数内部不能出现显示或者隐含的commit,所以create table 这样的语句不允许出现在函数内部;存储过程可以出现DDL
- 存储过程需要使用call来调用,而函数需要在SQL表达式中使用
- 存储过程内部可以调用函数,但是不可以在函数中调用存储过程
推荐阅读
- #|4-MySQL原理-SQL执行原理
- 笔记|Java技能树评测(以初学者身份)
- linux|MySQL数据库增删改查(基础操作命令详解)
- mysql优化|MySQL到底怎么优化?
- 前端与Python|Pandas 函数方法汇总一览查询(持续补充改进)
- 图数据库|如何从零到一构建一个企业股权图谱系统
- java|学习Java期末总结
- 学习|20220609学习记录(st表、动态规划、数学)
- sql数据库|零基础学习数据库SQL教程(三)(算法函数 时间函数)