1、存储过程

1》创建存储过程:create procedure

create procedure sp_name ([in | out | inout] param_name type)
[characteristics ...]  routine_body

characteristics指定存储过程的特性:

1>language sql:说明routine_body部分是由sql语句组成的,当前系统支持的语言为sql,sql是language特性的唯一值。

2>[not] deterministic:指明存储过程执行的结果是否确定。deterministic表示结果是确定的。每次执行存储过程时,相同的输入会得到相同的输出。not deterministic表示结果是不确定的,相同的输入可能得到不同的输出。如果没有指定任意一个值,默认为not deterministic。

3>{contains sql | no sql | reads sql data | modifies sql data}:指明子程序使用sql语句的限制。contains sql表明子程序包含sql语句,但是不包含读写数据的语句;no sql表明子程序不包含sql语句;reads sql data说明子程序包含读数据的语句;modifies sql data表明子程序包含写数据的语句。默认情况下,系统会指定为contains sql。

4>sql security{definer | invoker}:指明谁有权限来执行。definer表示只有定义者才能执行。invoker表示拥有权限的调用者可以执行。默认情况下,系统指定为definer。

5>comment 'string':注释信息,可以用来描述存储过程或函数。

routine_body:sql代码的内容,可以用begin...end;来表示sql代码的开始和结束。

//最简单的存储过程create procedure p_get_avg()
begin...
end;

//"delimiter //"的作用是将MySQL的结束符设置为//,因为MySQL默认的语句结束符号为分号";",//为了避免与存储过程中sql语句的结束符相冲突,需要使用delimiter改变存储过程的结束符,并//"end//"结束存储过程。"delimiter ;"则是恢复默认的";"结束符。mysql> delimiter //
mysql> create procedure p_get_avg()-> begin->   select * from test;-> end//
Query OK, 0 rows affected (0.02 sec)mysql> delimiter ;

2、存储函数

1》创建存储函数:create function

//指定in、out、inout只对procedure是合法的,在function中总是默认为in类型//如果return返回的类型不同于returns指定的类型,返回值将会被强制转换为恰当的类型。create function func_name([in | out | inout] param_name type)
returns type
[characteristic ...] routine_body

mysql> delimiter //
mysql> create function f_get_avg()-> returns char(25)-> begin->   return (select name from test where id=1);-> end//
Query OK, 0 rows affected (0.00 sec)mysql> delimiter ;

mysql> delimiter //
mysql> drop function if exists f_get_avg;-> CREATE FUNCTION f_get_avg()-> RETURNS int-> begin->   declare i int default 0;->   select 666 into i from dual;->   return i;-> end//
Query OK, 0 rows affected (0.02 sec)Query OK, 0 rows affected (0.02 sec)mysql> delimiter ;
mysql> select f_get_avg();
+-------------+
| f_get_avg() |
+-------------+
|         666 |
+-------------+
1 row in set (0.00 sec)mysql>

注:trigger和function都需要写成 select ...into  这种句式,否者会报1415错误?CREATE DEFINER=`root`@`localhost` FUNCTION `f_get_avg`() RETURNS int(11)
begindeclare i int default 0; /*select 666 into i from dual;*/return i;
end

CREATE DEFINER=`root`@`localhost` FUNCTION `f_get_avg`() RETURNS int(11)
begindeclare i int default 0; /*select 666 into i from dual;*/set i=999;return i;
end

3、变量的使用

1》在存储过程中使用declare语句定义变量:

declare var_name [,var_name]... data_type [default value];即:declare var1,var2,var3 int;

2》为变量赋值:定义变量后,MySQL使用set语句为变量赋值

set var_name = expr [,var_name=expr] ...;或者select col_name[,...] into var_name[,...] tb_expr;即:set var1=10,var2=20;

4、定义条件和处理程序:都是使用declare关键字

1》定义条件

//codition_name:表示条件的名称;condition_type参数表示条件的类型;//sqlstste_value和mysql_error_code:都可以表示MySQL的错误//sqlstate_value:为长度为5的字符串类型错误代码。//mysql_error_code:为数值类型错误代码。//例如:error 1142(42000)中,sqlstate_value的值是42000,mysql_error_code的值为1142。declare condition_name condition for [condition_type]其中[condition_type]:sqlstate [value] sqlstate_value                    | mysql_error_code即:declare condition_name condition for sqlstate [value] sqlstate_value或者
declare condition_name condition for mysql_error_code

举例:

//定义"error 1148(42000)"错误,名称为command_not_allowed//方法一:使用sqlstate_value
declare command_not_allowed condition for sqlstate '42000';//方法二:使用mysql_error_code
declare command_not_allowed condition for 1148;

2》定义处理程序

declare handler_type handler for condition_value[,...] sp_statement
sp_statement:程序语句段,表示遇到定义的错误时,需要执行的存储过程或函数

//错误处理方式//continue:表示遇到错误不处理。继续执行;//exit:遇到错误马上退出;//undo:表示遇到错误后撤回之前的操作,MySQL暂时不支持这样的操作。
handler_type:continue | exit | undo
//错误类型//sqlstate [value] sqlstate_value:包含5个字符的字符串错误值//condition_name:表示declare condition定义的错误条件名称//mysql_error_code:匹配数值类型错误代码//sqlwarning:匹配所有以01开头的sqlstate错误代码//not found:匹配所有以02开头的sqlstate错误代码//sqlexception:匹配所有没有被sqlwarning或not found捕获的sqlstate错误代码condition_value:sqlstate [value] sqlstate_value| condition_name| mysql_error_code| not found| sqlexception| sqlwarning

举例:

//方法一:捕获sqlstate_value
DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SET @info='NO_SUCH_TABLE';//方法二:捕获mysql_error_code
DECLARE CONTINUE HANDLER FOR 1146 SET @info=' NO_SUCH_TABLE ';//方法三:先定义条件,然后调用
DECLARE  no_such_table  CONDITION  FOR  1146;
DECLARE CONTINUE HANDLER FOR NO_SUCH_TABLE SET @info=' NO_SUCH_TABLE ';//方法四:使用SQLWARNING
DECLARE EXIT HANDLER FOR SQLWARNING SET @info='ERROR';//方法五:使用NOT FOUND
DECLARE EXIT HANDLER FOR NOT FOUND SET @info=' NO_SUCH_TABLE ';//方法六:使用SQLEXCEPTION
DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @info='ERROR'; 

mysql> DELIMITER //
mysql> CREATE PROCEDURE handlerdemo ()->       BEGIN->        DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1;->        SET @x = 1;->        INSERT INTO t VALUES (1);->        SET @x = 2;->        INSERT INTO t VALUES (1);->        SET @x = 3;->       END;->      //
Query OK, 0 rows affected (0.02 sec)mysql> DELIMITER ;
mysql> CALL handlerdemo();
Query OK, 0 rows affected (0.02 sec)mysql> select @x;
+------+
| @x   |
+------+
|    3 |
+------+
1 row in set (0.00 sec)mysql> select @x2;
+------+
| @x2  |
+------+
|    1 |
+------+
1 row in set (0.00 sec)mysql> select * from t;
+----+
| s1 |
+----+
|  1 |
+----+
1 row in set (0.00 sec)mysql>

@x是一个用户变量,执行结果@x等于3,说明存储过程被执行到了最后面一句。如果省去异常处理那一句,第2个insert因为主键约束强制失败之后,存储过程可能已经采取默认(exit)路径,此时select @x返回的结果可能是2。

"@var_name"表示用户变量,使用set语句为其赋值,用户变量与连接有关,一个客户端定义的变量不能被其他客户端看到或使用。当客户端连接退出时,该客户端连接的所有变量将自动释放。

5、光标的使用:MySQL中的光标只能在存储过程、存储函数中使用

1》声明光标

declare cursor_name cursor for select_statement;

2》打开关标

open cursor_name;

3》使用光标

fetch cursor_name into var_name[,var_name] ...;

4》关闭光标

close cursor_name;

  举个例子:

create procedure p3()
begindeclare id int;declare name varchar(15);declare flag int default 0;-- 声明游标declare mc cursor for select * from class1;declare continue handler for not found set flag = 1;-- 打开游标open mc;-- 获取结果
    loop_label_0:loop fetch mc into id,name;if flag=1 then -- 当无法fetch会触发handler continue
           leave loop_label_0;end if;-- 这里是为了显示获取结果insert into class2 values(id,name);-- 关闭游标end loop;close mc;
end;call p3();-- 不报错
select * from class2;

6、流程控制使用

MySQL中用于流程控制的语句有:if、case、loop、leave、iterate、repeat、while语句。每个流程可能包含一个单独语句,或者使用begin...end构造的符合语句,构造可以被嵌套。

1》if语句

//statement_list可以包含一个或者多个语句
if expr_condition then    statement_list
 [elseif expr_condition then statement_list ...] ...
 [else statement_list]
end if

2》case语句。与“控制流程函数”中的case是不同的。

//第一种方式:
//匹配表达式的值
case case_exprwhen  when_value  then  statement_list[when  when_value  then statement_list] ...[else statement_list]   //不能有else null子句
end case//第二种方式:
//逐个表达式执行,直到有一个表达式为true被执行
casewhen expr_condition then statement_list[when expr_condition then statement_list] ...[else statement_list]   //不能有else null子句
end case

3》loop语句

[loop_label:] loopstatement_list//如果要跳出循环,这时候label是必须的   if expr_condition then leave loop_label   end if;
end loop [loop_label]

4》leave语句

//用来退出任何被标注的流程控制构造,包括begin...end和循环体。leave label

5》iterate语句

//将执行顺序转到语句段开头处//iterate只可以出现在loop、repeat、while语句内,iterate表示再次循环,label参数表示循环的标志。//iterate语句必须跟在循环标志前面。
iterate label

CREATE PROCEDURE doiterate()
BEGIN
DECLARE p1 INT DEFAULT 0;
my_loop: LOOPSET p1= p1 + 1;IF p1 < 10 THEN ITERATE my_loop;ELSEIF p1 > 20 THEN LEAVE my_loop;END IF;SELECT 'p1 is between 10 and 20';
END LOOP my_loop;
END

6》repeat语句

创建一个带条件判断的循环过程,每次语句执行完毕,会对条件表达式进行判断,如果表达式为真,则循环结束;否则重复执行循环中的语句。相当于do...while语句。

[repeat_label:]repeatstatement_list
until expr_condition
end repeat [repeat_label]

7》while语句

[while_label:]while expr_condition dostatement_list
end while [while_label]

7、调用存储过程、存储函数

存储过程的调用必须使用call语句,并且存储过程和数据库相关,如果要执行其他数据库中的存储过程,需要指定数据库名称。

存储函数的调用与MySQL中定义的函数的调用方式相同。

1》调用存储过程

call sp_name([parameter[,...]])

CREATE DEFINER=`root`@`localhost` PROCEDURE `p_get_name`(in i_id int,out o_name varchar(25))
  begin
    select name into o_name from test t where t.id=i_id;
  end

-----------------------------------mysql> call p_get_name(1,@name);
Query OK, 1 row affected (0.00 sec)mysql> select @name;
+-------+
| @name |
+-------+
| Lucy  |
+-------+
1 row in set (0.00 sec)mysql>

2》调用存储函数:与MySQL内部定义的函数一样的使用方法。

CREATE DEFINER=`root`@`localhost` FUNCTION `f_get_avg`() RETURNS char(50) CHARSET utf8
beginreturn (select avg(salary) from test);
end--------------------------------------
mysql> select f_get_avg();
+-------------+
| f_get_avg() |
+-------------+
| 1180        |
+-------------+
1 row in set (0.00 sec)mysql>

8、查看存储过程和函数,方法有3种:

1》show status

//[like 'pattern']指匹配存储过程或函数的名称show {procedure | function} status [like 'pattern']

mysql> show procedure status like 'p_get_name%' \G
*************************** 1. row ***************************Db: mybatisName: p_get_nameType: PROCEDUREDefiner: root@localhostModified: 2019-09-05 00:28:04Created: 2019-09-05 00:28:04Security_type: DEFINERComment:
character_set_client: utf8
collation_connection: utf8_general_ciDatabase Collation: utf8_general_ci
1 row in set (0.00 sec)mysql>

2》show create

show create {procedure | function} sp_name

mysql> show create function f_get_avg \G
*************************** 1. row ***************************Function: f_get_avgsql_mode: STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITU
TIONCreate Function: CREATE DEFINER=`root`@`localhost` FUNCTION `f_get_avg`() R
ETURNS char(50) CHARSET utf8
beginreturn (select avg(salary) from test);
end
character_set_client: utf8
collation_connection: utf8_general_ciDatabase Collation: utf8_general_ci
1 row in set (0.00 sec)mysql>

3》从系统的information_schema数据库查询

MySQL中存储过程和存储函数的信息存储在information_schema数据库下的Routines表中。

select * from information_schema.Routines
where routine_name=' sp_name ' and routine_type='procedure | function';

mysql> select * from information_schema.routines where routine_name='p_get_name'and routine_type='procedure' \G
*************************** 1. row ***************************SPECIFIC_NAME: p_get_nameROUTINE_CATALOG: defROUTINE_SCHEMA: mybatisROUTINE_NAME: p_get_nameROUTINE_TYPE: PROCEDUREDATA_TYPE:
CHARACTER_MAXIMUM_LENGTH: NULLCHARACTER_OCTET_LENGTH: NULLNUMERIC_PRECISION: NULLNUMERIC_SCALE: NULLDATETIME_PRECISION: NULLCHARACTER_SET_NAME: NULLCOLLATION_NAME: NULLDTD_IDENTIFIER: NULLROUTINE_BODY: SQLROUTINE_DEFINITION: beginselect name into o_name from test t where t.id=i_id;
endEXTERNAL_NAME: NULLEXTERNAL_LANGUAGE: NULLPARAMETER_STYLE: SQLIS_DETERMINISTIC: NOSQL_DATA_ACCESS: CONTAINS SQLSQL_PATH: NULLSECURITY_TYPE: DEFINERCREATED: 2019-09-05 00:28:04LAST_ALTERED: 2019-09-05 00:28:04SQL_MODE: STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBS
TITUTIONROUTINE_COMMENT:DEFINER: root@localhostCHARACTER_SET_CLIENT: utf8COLLATION_CONNECTION: utf8_general_ciDATABASE_COLLATION: utf8_general_ci
1 row in set (0.00 sec)mysql>

9、修改存储过程、函数(并不是修改其中的代码)

alter {procedure | function} sp_name [characteristic ...]
characteristic指定存储过程的特性,可能的取值有:
  contains sql:表示子程序包含sql语句,但不包含读或写数据的语句。  no sql:表示子程序中不包含sql语句。  reads sql data:表示子程序中包含读数据的语句。  modifies sql data:表示子程序中包含写数据的语句。  sql security {definer | invoker}:指明谁有权限来执行。  definer:表示只有定义者自己才能够执行。  invoker:表示调用者可以执行。  comment 'string':表示注释信息。

10、删除存储过程、函数

drop {procedure | function} [if exists] sp_name

转载于:https://www.cnblogs.com/ZeroMZ/p/11461295.html

MySQL-快速入门(8)存储过程、存储函数相关推荐

  1. WebDay18 MySQL存储过程 存储函数 触发器 事务

    MySQL存储过程 存储函数 触发器 事务 一.MySQL存储过程和函数 1.存储过程和函数的概念 2.存储过程和函数的好处 3.存储过程和函数的区别 4.创建存储过程 5.调用存储过程 6.查看存储 ...

  2. Day463.视图存储过程存储函数 -mysql

    视图 1. 常见的数据库对象 对象 描述 表(TABLE) 表是存储数据的逻辑单元,以行和列的形式存在,列就是字段,行就是记录 数据字典 就是系统表,存放数据库相关信息的表.系统表的数据通常由数据库系 ...

  3. MySQL 案例实战--MySQL数据库 存储过程 存储函数

    MySQL数据库 存储过程 & 存储函数 前言 一.什么是存储过程 & 存储函数 二.存储过程的创建和调用 三.存储函数的创建和调用 前言 本环境是基于 Centos 7.8 系统构建 ...

  4. MySQL 快速入门教程

    转:MySQL快速 入门教程 目录 一.MySQL的相关概念介绍 二.Windows下MySQL的配置 配置步骤 MySQL服务的启动.停止与卸载 三.MySQL脚本的基本组成 四.MySQL中的数据 ...

  5. 阿里云rds for mysql平台介绍_阿里云RDS for MySQL 快速入门——笔记

    1初始化配置 1.1设置白名单 创建RDS实例后,需要设置RDS实例的白名单,以允许外部设备访问该RDS实例.默认的白名单只包含默认IP地址127.0.0.1,表示任何设备均无法访问该RDS实例. 设 ...

  6. mysql rds云数据库_云数据库 RDS MySQL快速入门手册

    云数据库 RDS MySQL是一款基于成熟云计算技术提供的高性能数据库服务,具有入门版.基础版.通用版.进阶版这四种,但最近有朋友表示,说自己并不会使用云数据库 RDS MySQL,为了帮助大家更好设 ...

  7. 视图存储过程存储函数

    文章目录 视图 常见数据库对象 视图概述 为什么使用视图? 视图的理解 创建视图 创建单表视图 创建多表联合视图 基于视图创建视图 查看视图 更新视图的数据 一般情况 不可更新的视图 修改.删除视图 ...

  8. Oracle学习2 视图 索引 sql编程 游标 存储过程 存储函数 触发器

    ---视图 ---视图的概念:视图就是提供一个查询的窗口,来操作数据库中的数据,不存储数据,数据在表中. ---一个由查询语句定义的虚拟表.---查询语句创建表 create table emp as ...

  9. mysql 函数 局部变量_MySQL 存储过程 存储函数 局部变量 游标 概念示例

    一个存储过程是一个可编程的函数,它可以在MySQL中创建并保存.它是由一些SQL语句和一些特殊的控制结构语句组成. 当希望在不同的应用程序或平台上执行相同的函数,或者封装特定的功能时,存储过程是一个非 ...

  10. Mysql 存储过程 / 存储函数

    目录 0 课程视频 1 基本语法 1.0 作用 ->在数据库中 封装sql语句 -> 复用 -> 减少网络交互 ->可接收参数返回数据 1.1 创建 1.2 调用 1.3 查看 ...

最新文章

  1. android支付宝插件,GitHub - DmcSDK/cordova.plugin.alipay: cordova 支付宝支付插件,支持IOS Android。...
  2. 手语识别 机器学习_机器学习入门实践,让机器识别一只猫
  3. android studio 一直在 svn performing vcs refresh
  4. Miniconda3及pip换源(conda清华源关闭)
  5. Spring Cloud构建微服务架构:消息驱动的微服务(入门)【Dalston版】
  6. 一文搞懂RSA算法原理及简单实现
  7. 酒驾、超速、加塞、路怒、拒载?来吧,我们专治各种不服
  8. HTML5 Video DOM 入门体验
  9. matlab dotchart,MATLAB中如何用对数方式显示图形坐标?
  10. 从研发到管理,这十大技巧助我提升了领导力
  11. React中受控组件和非受控组件
  12. 和jwt应用场景_一文了解web无状态会话token技术JWT
  13. (七)、Java异常类型及处理
  14. flashcs3java_Flash CS3组件开发图文教程
  15. mysql索引超出了数组接线_索引超出了数组界限如何解决?
  16. EIA/TIA 568A 568B 标准
  17. od反汇编linux,新手学习反汇编之OD寻找功能call
  18. 高级项目经理的企业需求、企业地位
  19. 2012年***名单。
  20. 2021-09-08

热门文章

  1. MACOS,应用签名后就崩溃?
  2. LINUX SHELL能不能调用桌面刷新命令,或者模拟键盘输入F5?
  3. 全网首发:deb打包时报错dh: Please specify the compatibility level in debian/compat
  4. JDK8的shenandoah GC/zgc啥时能转正?
  5. 世界首次发现?包名导致eclipse找不到包含main的类
  6. 程序员至少一半时间用于测试
  7. 解决办法:nvidia-settings:ERROR: Unable to load info from any available system
  8. 1970年代宇航员在月球上生活,如何实现电力供应
  9. SHELL下如何去掉字串里的空格(或指定字符)
  10. LINUX下使用scp命令与其他机器远程交换文件