MySQL 5.0 版本开始支持存储过程。

存储过程(Stored Procedure)是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象。

存储过程是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数(需要时)来调用执行。

存储过程思想上很简单,就是数据库 SQL 语言层面的代码封装与重用。

一、存储过程的创建和调用

  • 存储过程就是具有名字的一段代码,用来完成一个特定的功能。
  • 创建的存储过程保存在数据库的数据字典中。

  MYSQL 存储过程中的关键语法

  声明语句结束符,可以自定义:

  DELIMITER $$
  或
  DELIMITER //

声明存储过程:

CREATE PROCEDURE demo_in_parameter(IN p_in int)

存储过程开始和结束符号:

BEGIN .... END

变量赋值:

SET @p_in=1

变量定义:

DECLARE l_int int unsigned default 4000000;

创建mysql存储过程、存储函数:

create procedure 存储过程名(参数)

存储过程体:

create function 存储函数名(参数)

实例

创建数据库,备份数据表用于示例操作:

mysql> create database db1; mysql> use db1; mysql> create table PLAYERS as select * from TENNIS.PLAYERS; mysql> create table MATCHES as select * from TENNIS.MATCHES;

下面是存储过程的例子,删除给定球员参加的所有比赛:

mysql> delimiter $$  #将语句的结束符号从分号;临时改为两个$$(可以是自定义) mysql> CREATE PROCEDURE delete_matches(IN p_playerno INTEGER) -> BEGIN ->   DELETE FROM MATCHES -> WHERE playerno = p_playerno; -> END$$ Query OK, 0 rows affected (0.01 sec) mysql> delimiter;  #将语句的结束符号恢复为分号

解析:默认情况下,存储过程和默认数据库相关联,如果想指定存储过程创建在某个特定的数据库下,那么在过程名前面加数据库名做前缀。 在定义过程时,使用 DELIMITER $$ 命令将语句的结束符号从分号 ; 临时改为两个 $$,使得过程体中使用的分号被直接传递到服务器,而不会被客户端(如mysql)解释。

调用存储过程:

call sp_name[(传参)];

二、存储过程的参数

MySQL存储过程的参数用在存储过程的定义,共有三种参数类型,IN,OUT,INOUT,形式如:

CREATEPROCEDURE 存储过程名([[IN |OUT |INOUT ] 参数名 数据类形...])
  • IN 输入参数:表示调用者向过程传入值(传入值可以是字面量或变量)
  • OUT 输出参数:表示过程向调用者传出值(可以返回多个值)(传出值只能是变量)
  • INOUT 输入输出参数:既表示调用者向过程传入值,又表示过程向调用者传出值(值只能是变量)
mysql> create procedure in_param(in p_in int)
-> begin
->   select p_in;
->   set p_in=2;
-> select P_in;
-> end$$
mysql> delimiter ;
mysql> set @p_out=1;
mysql> call out_param(@p_out); #调用存储过程

2、out输出参数

mmysql> delimiter // mysql> create procedure out_param(out p_out int) -> begin -> select p_out; -> set p_out=2; -> select p_out; -> end -> //

3、inout输入参数

mysql> delimiter $$
mysql> create procedure inout_param(inout p_inout int)
-> begin
-> select p_inout;
-> set p_inout=2;
-> select p_inout;
-> end
-> $$
mysql> delimiter ; mysql> set @p_inout=1; mysql> call inout_param(@p_inout);
mysql> select @p_inout;

#调用了inout_param存储过程,接受了输入的参数,也输出参数,改变了变量

注意:

1、如果过程没有参数,也必须在过程名后面写上小括号例:

CREATE PROCEDURE sp_name ([proc_parameter[,...]]) ……

2、确保参数的名字不等于列的名字,否则在过程体中,参数名被当做列名来处理

三、变量

1. 变量定义

局部变量声明一定要放在存储过程体的开始:

DECLARE variable_name [,variable_name...] datatype [DEFAULT value];

2. 变量赋值

SET 变量名 = 表达式值 [,variable_name = expression ...]

3. 用户变量

在MySQL客户端使用用户变量:

mysql > SELECT 'Hello World' into @x;
mysql > SELECT @x;
+-------------+
| @x |
+-------------+
| Hello World |
+-------------+
mysql > SET @y='Goodbye Cruel World';
mysql > SELECT @y;

在存储过程中使用用户变量

ysql > CREATE PROCEDURE GreetWorld( ) SELECT CONCAT(@greeting,' World');
mysql > SET @greeting='Hello';
mysql > CALL GreetWorld( );

在存储过程间传递全局范围的用户变量

mysql> CREATE PROCEDURE p1()   SET @last_procedure='p1';
mysql> CREATE PROCEDURE p2() SELECT CONCAT('Last procedure was ',@last_procedure);
mysql> CALL p1( );
mysql> CALL p2( );

MySQL存储过程的调用

用call和你过程名以及一个括号,括号里面根据需要,加入参数,参数包括输入参数、输出参数、输入输出参数。具体的调用方法可以参看上面的例子。

示例:
CREATE DEFINER=`root`@`%` PROCEDURE `p_asset_setItManager`(`uuid` varchar(50),`user_id_par` varchar(20),`apply_no_par` varchar(20), `table_name` varchar(50))
BEGIN
--CREATE DEFINER=`root`@`%` PROCEDURE 定义用户权限 DECLARE s int DEFAULT 0; DECLARE num int DEFAULT 1;
DECLARE asset_user_city_par varchar(20);
DECLARE it_user_id varchar(50);
DECLARE executeSql varchar(1000); --DECLARE 声明变量
DECLARE itUserIdList CURSOR FOR select user_id from t_fin_it_city where manage_city = (select belong_city from t_fin_user_city where user_id = `user_id_par`); --CURSOR FOR 游标 查询的结果集
DECLARE CONTINUE HANDLER FOR NOT FOUND SET s=1; open itUserIdList; --打开游标 FETCH NEXT FROM itUserIdList INTO it_user_id; while s<>1 do
set executeSql = CONCAT("update ", `table_name`," set approve_asset_user_it",num,"= '",it_user_id,"' where id = '",`apply_no_par`,"'");
set @sql = executeSql; --变量赋值
PREPARE stmt FROM @sql;
EXECUTE stmt ;
deallocate prepare stmt;
if `table_name` = 't_fin_fixed_asset_apply' then
-- 资产领用-it资产管理员审批提醒
insert into c_email_message (apply_no,receive_user_id,temp_code,send_flag,retry_num) select `apply_no_par`,it_user_id,'1002','0',0 from dual;
end if;
if `table_name` = 't_fin_fixed_asset_transfer_apply' then
-- 资产转移-it资产管理员审批提醒
insert into c_email_message (apply_no,receive_user_id,temp_code,send_flag,retry_num) select `apply_no_par`,it_user_id,'2003','0',0 from dual;
end if;
set num = num+1; FETCH NEXT FROM itUserIdList INTO it_user_id; end while; close itUserIdList;
END

最新文章

  1. ios 判断相册文件图片大小的方法
  2. DATA GUARD架构(一)
  3. 参考:iPhone OS 3.0中的字体列表
  4. Java IO学习笔记(三)转换流、数据流、字节数组流
  5. 团队作业9——Beta版本展示博客
  6. cocos2dx - android环境配置及编译
  7. SpringBoot入门教程(十七)@Service、@Controller、@Repository、@Component
  8. PHP 匿名函数使用技巧
  9. 日志学习系列(四)——NLog实例
  10. node环境
  11. 虚拟机 安装centos
  12. PHP的内存限制 Allowed memory size of 134217728 bytes exhausted (tried to allocate 1099 bytes) in
  13. sublime使用经验汇总
  14. (10)MySQL触发器(同时操作两张表)
  15. 3.window窗口
  16. 记录一次错误处理 (xml序列化和反序列化相关)
  17. 使用MyEclipse开发Java EE应用:企业级应用程序项目(下)
  18. K2 BPM介绍(1)
  19. 随手练——洛谷-P1008 / P1618 三连击(暴力搜索)
  20. MUI实现上拉加载和下拉刷新

热门文章

  1. Nginxre quest_time 和upstream_response_time
  2. Raft成员变化(Membership Change)
  3. windows下php安装redis扩展
  4. 缓存Bigkey坚决不要用,拆分是王道
  5. dart系列之:dart优秀的秘诀-隔离机制
  6. 【经验】 Java BigInteger类以及其在算法题中的应用
  7. 【九度OJ】题目1024:畅通工程 解题报告
  8. 【LeetCode】558. Quad Tree Intersection 解题报告(Python)
  9. The Longest Straight(FZUoj2216)
  10. Interval Bound Propagation (IBP)