Mysql的存储过程摘要

 

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

 

posted @ 2020-10-13 16:09  随心的风  阅读(120)  评论(0编辑  收藏  举报