【mysql的编程专题④】存储过程
类似函数,但是没有返回值,把sql进行封装,便于多次使用或多种应用程序共享使用.不能用在SQL语句中,只能使用CALL调用;
创建存储过程
语法
CREATE PROCEDURE sp_name ([proc_parameter[,...]])
[characteristic ...] routine_body
sp_name是存储过程的名称;proc_parameter表示存储过程的参数列表;characteristic指定存储过程的特性;routine_body参数是SQL代码的内容,多条sql以;隔开,可以用BEGIN…END来标志SQL代码的开始和结束。
参数
proc_parameter中的每个参数由3部分组成。这3部分分别是输入输出类型、参数名称和参数类型。
[ IN | OUT | INOUT ] param_name type
IN表示输入参数(可以看做声明参数为函数的局部变量,内部做改变外部不被影响);OUT表示输出参数(调用结束后外部可以访问到这个变量,内部能改变外部的变量); INOUT表示既可以是输入,也可以是输出;
CREATE PROCEDURE pr_param_in(in id int)
BEGIN
IF id is not null THEN
set id = id + 1;
END IF;
SELECT id as id_inner;
END //
mysql> call pr_param_in(10); -- 如果存储过程的输出类型为in的话,不会报错;
+----------+
| id_inner |
+----------+
| 11 |
+----------+
mysql> call pr_param_in(@id);
+----------+
| id_inner |
+----------+
| 101 |
+----------+
1 row in set
Query OK, 0 rows affected
mysql> select @id as id_out; -- in是不会影响外部的变量的;
+--------+
| id_out |
+--------+
| 100 |
+--------+
1 row in set
CREATE PROCEDURE pr_param_out (OUT id INT)
BEGIN
SELECT id AS id_inner_1; -- 如果参数的输出类型为out的话,那外面的int必须是一个变量,并且无论传什么参数进来都为null。
IF id IS NOT NULL THEN
SET id = id + 1;
SELECT id AS id_inner_2;
ELSE
SELECT 1 INTO id;
END IF;
SELECT id as id_inner_3;
END //
call pr_param_out(10); -- 1411错误:子程序%s的OUT或INOUT参量不是变量。
1414 - OUT or INOUT argument 1 for routine test.pr_param_out is not a variable or NEW pseudo-variable in BEFORE trigger
mysql> set @var = 10;
Query OK, 0 rows affected
mysql> call pr_param_out(@var);
+------------+
| id_inner_1 |
+------------+
| NULL |
+------------+
1 row in set
+------------+
| id_inner_3 |
+------------+
| 1 |
+------------+
1 row in set
mysql> select @var as id_out; -- 如果参数的输出类型为out的话,传入什么值都会变为NULL,然后在内部都会改变外部变量的值;
+--------+
| id_out |
+--------+
| 1 |
+--------+
1 row in set
CREATE PROCEDURE pr_param_inout (INOUT id INT)
BEGIN
SELECT id AS id_inner_1; -- 如果参数的输出类型为inout的话,那外面的int必须是一个变量。外面传的变量是能够进来的;
IF id IS NOT NULL THEN
SET id = id + 1;
SELECT id AS id_inner_2;
ELSE
SELECT 1 INTO id;
END IF;
SELECT id as id_inner_3;
END //
mysql> set @var = 100;
mysql> call pr_param_inout(@var);
+------------+
| id_inner_1 |
+------------+
| 100 |
+------------+
1 row in set
+------------+
| id_inner_2 |
+------------+
| 101 |
+------------+
1 row in set
+------------+
| id_inner_3 |
+------------+
| 101 |
+------------+
1 row in set
mysql> select @var; -- 能够被改变;
+------+
| @var |
+------+
| 101 |
+------+
- type参数指定存储过程的参数类型,该类型可以是MySQL数据库的任意数据类型;
- 参数是可有可无;
- 参数名和字段名最好不要一样;
DELIMITER //
CREATE PROCEDURE p1() SELECT * FROM t;// -- 如果只有一句sql的话,可以不用写begin和end;
存储过程的特性
characteristic参数有多个取值。其取值说明如下:
- LANGUAGE SQL:说明routine_body部分是由SQL语言的语句组成,这也是数据库系统默认的语言。
- [NOT] DETERMINISTIC:指明存储过程的执行结果是否是确定的。DETERMINISTIC表示结果是确定的。每次执行存储过程时,相同的输入会得到相同的输出。NOT DETERMINISTIC表示结果是非确定的,相同的输入可能得到不同的输出。默认情况下,结果是非确定的。
- { 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。
- SQL SECURITY { DEFINER | INVOKER }:指明谁有权限来执行。DEFINER表示只有定义者自己才能够执行;INVOKER表示调用者可以执行。默认情况下,系统指定的权限是DEFINER。
- COMMENT 'string':注释信息。
技巧:创建存储过程时,系统默认指定CONTAINS SQL,表示存储过程中使用了SQL语句。但是,如果存储过程中没有使用SQL语句,最好设置为NO SQL。而且,存储过程中最好在COMMENT部分对存储过程进行简单的注释,以便以后在阅读存储过程的代码时更加方便。
Example1
CREATE PROCEDURE num_from_employee (IN emp_id INT, OUT count_num INT )
READS SQL DATA
COMMENT 'this is a test_pro'
BEGIN
SELECT COUNT(*) INTO count_num
FROM employee
WHERE d_id=emp_id ;
END
上述代码中,存储过程名称为num_from_employee;输入变量为emp_id;输出变量为count_num。SELECT语句从employee表查询d_id值等于emp_id的记录,并用COUNT(*)计算d_id值相同的记录的条数,最后将计算结果存入count_num中,comment为注释;
更多的例子请看流程控制
查看存储过程
SHOW PROCEDURE STATUS\G
*************************** 1. row ***************************
Db: test
Name: p1
Type: PROCEDURE
Definer: root@localhost
Modified: 2015-05-01 09:49:20
Created: 2015-05-01 09:49:20
Security_type: DEFINER
Comment:
character_set_client: utf8
collation_connection: utf8_general_ci
Database Collation: latin1_swedish_ci
删除存储过程
mysql> drop procedure p1; -- p1 存储过程的名称
Query OK, 0 rows affected
【mysql的编程专题④】存储过程的更多相关文章
- 【mysql的编程专题①】流程控制与其他语法
流程控制与内置函数,一般用在select的field字段上,或者用在函数,存储过程,触发器中; 如果用在select上就会随着query出来的row来隐式迭代; 注释与语句结束符 语句结束符 默认有两 ...
- 【mysql的编程专题⑤】自定义函数
用户自定义函数(user-defined function,UDF) 是一种对mysql的扩展途径,其用法与内置函数相同 创建自定义函数 语法 create function function_nam ...
- 【mysql的编程专题③】内置函数
数学函数 常用 abs(x) 返回x的绝对值 floor(x) 返回小于x的最大整数值 mod(x,y) 返回x/y的模(余数) rand() 返回0到1内的随机值,可以通过提供一个参数(种子)使ra ...
- 【mysql的编程专题】触发器
类似tp里面的数据模型回调接口,在数据表增删改的前或后触发执行其他的预订的sql; 一个触发器要具备4要素: 1.监视地点 -- 要执行触发器的表 2.监视事件 -- 由什么DML事件来牵引 3.触发 ...
- 【mysql的编程专题⑥】视图
视图是表的一个映射,是一张虚表,在结构上视图和普通的表没什么区别,一样可以用sql语句来增删改查; 视图创建后是一直存在数据库内 操作 创建视图 语法 CREATE [ALGORITHM]={UNDE ...
- MySql学习笔记(五) —— 存储过程
存储过程是MySql 5支持的特性,它是一组为了完成特定功能的SQL语句集,经过编译之后存储在数据库中,当需要使用该组SQL语句时用户只需要通过指定储存过程的名字并给定参数就可以调用执行它了,简而言之 ...
- 【转】图解MySql命令行创建存储过程
一 操作实例 首先登录mysql: 使用source命令,从命令行执行sql脚本,创建表: 创建第一个存储过程: 事先用DELIMITER关键字申明当前段分隔符,这样MySQL才会将";&q ...
- mysql创建定时执行存储过程任务
sql语法很多,是一门完整语言.这里仅仅实现一个功能,不做深入研究. 目标:定时更新表或者清空表. 案例:曾经做过定时清空位置信息表的任务.(然而,当时并未考虑服务器挂掉后的情况) 本次测试:每5s更 ...
- mysql开发中使用存储过程
在mysql开发中使用存储过程的理由: 当希望在不同的应用程序或平台上执行相同的函数,或者封装特定功能时,存储过程是非常有用的 mysql 执行语句是要先编译,然后再执行的.这样如果查询并发大的时候. ...
随机推荐
- [转]Android在eclipse中的快捷键
1.选中你要加注释的区域,用ctrl+shift+C 会加上//注释2.先把你要注释的东西选中,用shit+ctrl+/ 会加上/* */注释3.要修改在eclispe中的命令的快捷键方式我们只 ...
- IOS_设置启动图片若干问题
在做项目时, 发现设置了LaunchImage时发现一些问题: 1. 启动图片的设置可以通过两种方法: 1) 通过在LaunchScreen里放入ImageView 并设置图片, 这种方法的好处在于不 ...
- Java基础(二)
下面来实现一个小程序,要求如下: 从键盘接收一个字符串,程序对其中所有的字符进行排序,例如键盘输入:helloitcast程序打印acehillostt 步骤分析: 1.键盘录入字符串,Scanner ...
- Android Error:You must supply a layout_width attribute……
出现这种情况的可能原因目前本人碰到的有: 1:在xml文件中某个属性名或者属性值写错,请务必仔细检查你有没有写错某个拼写. 2:当你在,比如TextView中,没有声明layout_width,经测试 ...
- eclipse插件 代码提示和着色
插件一:Eclipse HTML Editor,用于编辑一些页面文件,例如JSP,HTML,JS等 Eclipse HTML编辑器插件主要提供以下功能:- HTML/JSP/XML/CSS/DTD/J ...
- linux c 实现大数相乘
#include <stdio.h> #include <string.h> #include <math.h> #include <stdbool.h& ...
- 数据的增量更新之EXISTS
有时候需要实现是数据的增量更新,因为更新全量会带来时间跟数据库资源的浪费,还有可能是数据出现冗余,所以需要使用增量数据同步,下面是一个数据增量同步的小实例. ---drop table A CREAT ...
- C/C++ 内联函数
内联函数具备一般函数的性质,但是不需要调用,而是在编译阶段,会用函数体替换函数名被调用的地方.可以节省调用时间(进出栈.保存上下文). 在编译层面和宏的作用相同.内联函数的展开在编译阶段,宏展开在预处 ...
- 微信消息处理JAXP-sax解析
package cn.zhaokai.sax; import java.io.IOException; import java.io.InputStream; import java.io.Print ...
- jquery-2.0.3.js和jquery-2.0.3.min.js的区别
两个文件的作用是完全一样的. jquery-2.0.3.js里的代码是没有进行处理的原代码,适合于人们阅读与研究. jquery-2.0.3.min.js里的代码进行过特殊的处理, 如变量的名称基本都 ...