12.Mysql存储过程和函数
12.存储过程和函数
12.1 什么是存储过程和函数
存储过程和函数是事先经过编译并存储在数据库中的一段SQL语句的集合,
调用存储过程和函数简化应用开发人员的工作,减少数据在数据库和应用服务器之间的传输,有利于提高数据的处理效率。
存储过程和函数的区别:
函数必须有返回值,而存储过程没有;
存储过程的参数类型可以是IN、OUT、INOUT,而函数的参数类型只能是IN;
函数一般通过select语句调用,存储过程通过call命令调用;
函数中只能进行select操作,存储过程中可进行select\insert\update\delete操作。
12.2 存储过程和函数的相关操作
create routine 创建存储过程和函数的权限
alter routine 修改或删除存储过程和函数的权限
execute 执行存储过程和函数的权限
12.2.1 创建、修改存储过程和函数
1.创建存储过程语法:
delemiter $$
create procedure proc_name([参数类型 参数名 数据类型[,...]])
[characteristic特征]
begin
过程体
end $$
delemiter ;
说明:
参数类型取值分为:输入参数IN、输出参数OUT、输入输出参数INOUT,默认值为IN
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} 执行存储过程的角色,sql security definer指使用创建者权限执行存储过程,sql security invoker指使用调用者权限执行存储过程,默认sql security definer。
| comment 'string' 存储过程的注释信息
过程体:有效的存储过程语句,
允许包含DDL语句(create\alter\drop\truncate等)和DCL语句(commit\rollback),
不允许包括load data infile语句,允许调用其它存储过程和函数。
delemiter $$ 将语句结束符设置为$$,使存储过程和函数中的";"不被错误的认为是语句结束符。
delemiter ; 将语句结束符设置为;,将语句结束符更改回原来的符号。
存储过程目前还不支持create or replace语法,如果需要修改存储过程可使用alter或先drop再create。
2.修改存储过程语法:
alter procedure proc_name [characteristic特征];
characteristic特征:
| {contains sql | no sql | reads sql data | modifies sql data} 对数据的处理方式
| sql security {definer | invoker} 安全控制
| comment 'string' 说明、注释
3.创建函数语法:
create function func_name([参数名 数据类型[,...]]) returns 返回值类型
[characteristic特征]
begin
函数体
end$$
说明:
函数参数类型只能为IN,默认参数类型也是IN,所以不用写参数类型
4.修改函数语法:
alter function func_name [characteristic特征];
characteristic特征:
| {contains sql | no sql | reads sql data | modifies sql data} 对数据的处理方式
| sql security {definer | invoker} 安全控制
| comment 'string' 说明、注释
5.调用过程语法
call proc_name([参数类型 参数名 数据类型[,...]]);
6.调用函数
select proc_name([参数名 数据类型[,...]]);
12.2.2 删除存储过程和函数
删除存储过程语法:
drop procedure [if exists] proc_name;
删除函数语法:
drop function [if exists] func_name;
注意:
一次只能删除一个存储过程或函数;
删除存储过程或函数时要有对该存储过程或函数的alter routine权限。
12.2.3 查看存储过程和函数
查看存储过程的状态:
show procedure status like 'proc_name';
查看函数的状态:
show function status like 'func_name';
查看存储过程的定义:
show create procedure proc_name;
查看函数的定义:
show create function func_name;
通过数据字典查看更详细的存储过程和函数信息:
select * from information_schema.routines where routine_name='具体的存储过程或函数名';
12.2.4 变量的使用
1.定义变量
语法:
declare v_name[,...] datatype [default value];
说明:
变量不区分大小写;
变量为局部变量,作用域在Begin和end之间;
变量定义要写在其它语句之前;
可以一次定义多个相同类型的变量;
可以给变量用default赋默认值;
2.变量赋值
直接赋值
set v_name=expr[,v_name2=expr2]...
查询赋值
select col_name into v_name from table_name where condition limit 1;
说明:
变量可以赋值常量,也可以赋值表达式;
set语句可以一次给多个变量赋值;
查询赋值时查询结果必须限定为一行。
12.2.5 定义条件和处理
定义条件和处理可以用来定义在处理过程中遇到问题时相应的处理步骤。
1.定义条件
declare cond_name condition for sqlstate [Value] sqlstate_value | mysql_error_code;
2.定义处理(异常处理)
declare handler_type handler for condition_value[,...] sp_statement;
说明:
handler_type取值包括:即当遇到condition_value定义的异常时程序如何跳转
continue 继续执行下面的语句;
exit 执行终止,直接退出;
undo 执行终止,并回滚前面的语句,目前还不支持。
condition_value取值包括:
cond_name 条件中定义的条件名
mysql_error_code 报错编码
sqlstate [Value] sqlstate_value SQL状态值
sqlwarning 警告,以01开头的sqlstate代码
not found 未找到数据,以02开头的sqlstate代码
sqlexception 异常,没有被sqlwarning和not found捕获的sqlstate代码
程序没有定义异常处理时,如果程序执行过程中遇到异常时,则抛出异常并退出;
程序定义异常处理后,如果程序执行过程中遇到异常时,则按照定义的异常处理执行,不会将异常抛出,一般用于批量处理的程序中。
12.2.6 光标的使用
光标可以对结果集进行循环处理。
光标使用步骤分为:定义光标、打开光标、提取数据、关闭光标。
定义光标:
declare cursor_name cursor for select语句;
declare exit handler for not found colse cursor_name;
打开光标:
open cursor_name;
提取数据:
repeat
fetch cursor_name into var_name[,var_name2]...;
until 0 end repeat;
关闭光标:
close cursor_name;
说明:
声明顺序:变量--》条件--》光标--》异常处理;
每个存储过程中只能声明一个光标;
声明光标后必须紧跟着声明异常处理declare exit handler for not found colse cursor_name;
其它类型的异常处理类型不能和光标的异常处理类型重复,即不能包含not found;
在循环repeat中逐行提取数据,用多个变量逐个接收1行记录的多个列信息。
12.2.7 流程控制
流程控制包括:if,case,loop,leave,iterate,repeat,while等条件分支语句和循环语句。
1.IF条件语句语法
if expr_condition then
语句1;
[elseif expr_condition2 then
语句2;]...
[else
语句n;]
end if;
说明:
IF条件语句实现了一重分支,二重分支,多重分支;
根据各条件表达式的真假,有选择的执行语句1|语句2|...|语句n。
2.case条件语句语法:
等值比较:
case 表达式
when 表达式1 then 语句1;
[when 表达式2 then 语句2;]...
[else 语句n;]
end case;
说明:
当表达式与表达式1相等时执行语句1,
当表达式与表达式2相等时执行语句2,...一次类推
当表达式与上述表达式都不相等时执行语句n。
范围比较:
case
when 逻辑表达式1 then 语句1;
[when 逻辑表达式2 then 语句2;]...
[else 语句n;]
end case;
说明:
当逻辑表达式1为真时执行语句1,
当逻辑表达式2为真时执行语句2,...一次类推
当上述逻辑表达式都不为真时执行语句n。
3.loop循环语句语法
lable_name: loop
语句1;
end loop lable_name;
说明:
无限循环语句1;
一般情况下需要在Loop循环中增加循环退出的条件。
4.leave退出本层循环
lable_name: loop
语句1;
if expr_condition then
leave lable_name;
end if;
语句2;
end loop lable_name;
说明:
Loop循环在expr_condition为真时退出本层Loop循环。
5.iterate退出本层次循环,接着进行下次循环
lable_name: loop
语句1;
if expr_condition then
iterate lable_name;
end if;
语句2;
end loop lable_name;
说明:
Loop循环在expr_condition为真时退出本次Loop循环,即不执行本次的语句2,接接着语句1开始下次循环。
6.repeat条件控制循环
lable_name: repeat
语句1;
until search_condition
end repeat lable_name;
说明:
当满足search_condition条件时退出循环
7.while
lable_name: while search_condition do
语句1;
end while lable_name;
说明:
当满足search_condition条件时进入循环,不满足时退出循环
12.2.8 事件调度器
定义:按照自定义的时间周期特定的执行某种操作。
语法:
create event 事件名 on schedule 时间周期 do 某种操作;
说明:
create event子句指定事件名;
on schedule子句指定事件的执行时间和频次;
do子句指定要执行的具体操作。
例子1:
create event my_event1 on schedule at current_timestamp + interval 1 hour do update emp set sal=sal+1;
例子2:
创建测试表test
create table test(id1 varchar(10),create_time datetime);
创建事件调度器,每5秒插入一条数据
create event event_test1 on schedule every 5 second do insert into test values ('test',now());
查看事件调度器:
show events;
select * from information_schema.events;
查看事件调度器状态(系统参数):
show variables like '%scheduler%';
show variables like 'event_scheduler';
select * from information_schema.GLOBAL_VARIABLES where variable_name='EVENT_SCHEDULER';
select * from information_schema.SESSION_VARIABLES where variable_name='EVENT_SCHEDULER';
select * from information_schema.GLOBAL_STATUS;
Error Code 3167解决方法:
show variables like '%show_compatibility_56%';
set global show_compatibility_56=on;
select * from information_schema.SESSION_VARIABLES
select * from information_schema.GLOBAL_VARIABLES;
select * from information_schema.GLOBAL_STATUS;
启用事件调度器(修改系统参数):数据库重启后需要重新启用事件调度器
set global event_scheduler=1;
查看后台进程:发现多了一个调度进程
show processlist;
'4', 'event_scheduler', 'localhost', NULL, 'Daemon', '1', 'Waiting for next activation', NULL
在查看test表,发现已有数据插入,为了防止表中数据快速增长,创建新的事件调度器,每2分钟清空一次test表:
create event event_test2 on schedule every 2 minute do truncate table test;
禁用事件调度器:
alter event event_test2 disable;
删除事件调度器:
drop event event_test1;
时间周期:
every 5 second 每隔5秒
every 1 minute 每隔1分钟
at current_timestamp + interval 1 hour 首次执行为当前时间,后续每隔1小时执行
当前日期:select CURDATE();
当前日期+1天:select DATE_ADD(CURDATE(), INTERVAL 1 DAY);
当前日期+1天+1小时:select DATE_ADD(DATE_ADD(CURDATE(), INTERVAL 1 DAY), INTERVAL 1 HOUR);
ON SCHEDULE 计划任务,有两种设定计划任务的方式:
1. AT 时间戳,用来完成单次的计划任务。
2. EVERY 时间(单位)的数量时间单位[STARTS 时间戳] [ENDS时间戳],用来完成重复的计划任务。
在两种计划任务中,
时间戳可以是任意的TIMESTAMP 和DATETIME 数据类型, 时间戳需要大于当前时间。
在重复的计划任务中,时间(单位)的数量可以是任意非空(Not Null)的整数式,时间单位是关键词:YEAR,MONTH,DAY,HOUR,MINUTE 或者SECOND。
例子:
create event event_incremental on schedule at '2018-08-12 01:00:00' + interval 1 DAY do call zgai_db.proc_incremental();
类型:一次
执行时间:2018-08-13 01:00:00
create event event_incremental3 on schedule at '2018-08-12 01:00:00' + interval 1 HOUR do call zgai_db.proc_incremental();
类型:一次
执行时间:2018-08-12 02:00:00
create event event_incremental on schedule EVERY 1 DAY do call zgai_db.proc_incremental();
类型:循环
间隔:1天
起始时间:当前时间
CREATE EVENT IF NOT EXISTS event_incremental4
ON SCHEDULE EVERY 1 DAY STARTS DATE_ADD(DATE_ADD(CURDATE(), INTERVAL 1 DAY), INTERVAL 1 HOUR)
ON COMPLETION PRESERVE ENABLE
DO call zgai_db.proc_incremental();
类型:循环
间隔:1天
起始时间:明天1点
查看event是否开启: show variables like '%sche%';
将事件计划开启: set global event_scheduler=1;
关闭事件任务: alter event e_test ON COMPLETION PRESERVE DISABLE;
开户事件任务: alter event e_test ON COMPLETION PRESERVE ENABLE;
12.3 小结
12.4 mysql动态sql示例
预制语句的SQL语法基于三个SQL语句:
PREPARE stmt_name FROM preparable_stmt;
EXECUTE stmt_name [USING @var_name [, @var_name] ...];
{DEALLOCATE | DROP} PREPARE stmt_name;
查询某个表的行数
USE `zgai_db`;
DROP PROCEDURE IF EXISTS `proc_dynamic_test`;
delimiter $$
USE `zgai_db`$$
CREATE PROCEDURE proc_dynamic_test(IN table_name varchar(255))
begin
declare var_sql varchar(800);
set var_sql = concat_ws(' ', 'select count(*) from ', table_name,' where 1=1');
set @sql = var_sql;
PREPARE s1 from @sql;
EXECUTE s1;
deallocate prepare s1;
end$$
delimiter ;
call proc_dynamic_test('AI_const');
12.Mysql存储过程和函数的更多相关文章
- 12 MySQL存储过程与函数
存储过程和函数 存储过程和函数是事先经过编译并存储在数据库中的一段SQL语句的集合. 调用存储过程和函数可以简化应用开发人员的工作,减少数据在数据库和应用服务器之间的传输,提高数据处理 ...
- MYSQL存储过程和函数学习笔记
学至Tarena金牌讲师,金色晨曦科技公司技术总监沙利穆课程笔记的综合. 1. 什么是存储过程和函数 将SQL语句放入一个集合里,然后直接调用存储过程和函数来执行已经定义好的SQL语句,通过存储过程和 ...
- Paip.断点调试MYSQL存储过程跟函数的解决方案大法
Paip.断点调试MYSQL存储过程跟函数的解决方案大法 作者Attilax , EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog.csdn ...
- Mysql存储过程和函数
Mysql存储过程和函数 基本概念: 创建存储过程和函数是指将经常使用的一组SQL语句的组合在一起,并将这些SQL语句当作一个整体存储在MySQL服务器中.例如,银行经常需要计算用户的利息.不同类别的 ...
- MySql存储过程与函数详解
存储过程和函数是在数据库中定义一些SQL语句的集合,然后直接调用这些存储过程和函数来执行已经定义好的SQL语句.存储过程和函数可以避免开发人员重复的编写相同的SQL语句.而且,存储过程和函数是在MyS ...
- mysql 存储过程,函数,触发器
存储过程和函数 mysql> HELP CREATE PROCEDURE; Name: 'CREATE PROCEDURE' Description: Syntax: CREATE [DEFIN ...
- MySql存储过程、函数
存储过程和函数是在数据库中定义一些SQL语句的集合,然后直接调用这些存储过程和函数来执行已经定义好的SQL语句.存储过程和函数可以避免开发人员重复的编写相同的SQL语句.而且,存储过程和函数是在MyS ...
- Mysql - 存储过程/自定义函数
在数据库操作中, 尤其是碰到一些复杂一些的系统, 不可避免的, 会用到函数/自定义函数, 或者存储过程. 实际项目中, 自定义函数和存储过程是越少越好, 因为这个东西多了, 也是一个非常难以维护的地方 ...
- MySQL 存储过程和函数
概述 一提到存储过程可能就会引出另一个话题就是存储过程的优缺点,这里也不做讨论,一般别人问我我就这样回答你觉得它好你就用它.因为mysql中存储过程和函数的语法非常接近所以就放在一起,主要区别就是函数 ...
随机推荐
- Chrome 不能访问tensorboard解决
Chrome 不能访问tensorboard解决 Run: Cmd Result: C:\Users\think>tensorboard --logdir=C:\Users\think\sour ...
- VS2012/VS2013配色方案
VS的配色方案下载地址 http://www.hanselman.com/blog/VisualStudioProgrammerThemesGallery.aspx 或者 http://studios ...
- Python之路 - 网络编程之粘包
Python之路 - 网络编程之粘包 粘包
- spark 学习_rdd常用操作
[spark API 函数讲解 详细 ]https://www.iteblog.com/archives/1399#reduceByKey [重要API接口,全面 ] http://spark.apa ...
- Java:类加载机制及反射
一.Java类加载机制 1.概述 Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息:如构造函数,属性和方法等,Java允 ...
- Unity3D中的Quality
Quality Level:质量等级,默认为打包最低的那个等级 Name:质量级别的名称 Pixel Light Count:像素灯数量(前向渲染使用的像素灯的最大数量) Texture Qualit ...
- 如何正确获取MYSQL的ADO连接字符串
首先你正确安装了MYSQL的数据库驱动程序(mysql-connector-odbc-5.3.2-win32.msi )http://dev.mysql.com/downloads/connector ...
- 设置https以及http转https的问题
公司用的是阿里云服务器win2008server r2 ,环境是phpwamp,出现许多问题.2018-11-12 一 设置https 1.设置httpd.ini 取消以下三个配置的# LoadMod ...
- gitlab-ce 安装、汉化与阿里邮箱配置(注意是CE)
环境准备 yum install curl openssh-server openssh-clients postfix cronie policycoreutils-python –y curl h ...
- docker的理解
作者:刘允鹏链接:https://www.zhihu.com/question/28300645/answer/67707287来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...