MySQL 存储过程

存储过程中的控制语句
http://blog.csdn.net/J080624/article/details/72353508

不同类型参数存储过程示例
http://blog.csdn.net/j080624/article/details/55096307

MyBatis调用存储过程
http://blog.csdn.net/J080624/article/details/53435479

 参考https://blog.csdn.net/J080624/article/details/72331013


 

 

 

【1】存储过程简介

  我们常用的操作数据库语言SQL语句在执行的时候需要要先编译,然后执行,而存储过程(StoredProcedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它。

一个存储过程是一个可编程的函数(存储过程无返回值),它在数据库中创建并保存。它由SQL语句和一些特殊的控制结构组成。

 

【2】存储过程的优点

(1)存储过程增强了SQL语言的功能和灵活性。

存储过程可以用流控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。

(2)存储过程允许标准组件是编程。

存储过程被创建后,可以在程序中被多次调用,而不必重新编写该存储过程的SQL语句。
而且数据库专业人员可以随时对存储过程进行修改,对应用程序源代码毫无影响。

(3)存储过程能实现较快的执行速度。

如果某一操作包含大量的Transaction-SQL代码或分别被多次执行,那么存储过程要比批处理的执行速度快很多。

因为存储过程是预编译的。在首次运行一个存储过程时查询,优化器对其进行分析优化,并且给出最终被存储在系统表中的执行计划。

而批处理的Transaction-SQL语句在每次运行时都要进行编译和优化,速度相对要慢一些。

(4)存储过程能过减少网络流量。

针对同一个数据库对象的操作(如查询、修改),如果这一操作所涉及的Transaction-SQL语句被组织程存储过程。
那么当在客户计算机上调用该存储过程时,网络中传送的只是该调用语句,从而大大增加了网络流量并降低了网络负载。

(5)存储过程可被作为一种安全机制来充分利用。

系统管理员通过执行某一存储过程的权限进行限制,能够实现对相应的数据的访问权限的限制,避免了非授权用户对数据的访问,保证了数据的安全。 

 

【3】MySQL存储过程的创建

1)语法格式

MySQL存储过程创建的格式:CREATE PROCEDURE 过程名([过程参数[,…]])[特性 …]过程体;

  • //为自定义符号,你可以换成其他,如$$
mysql> DELIMITER //   
    mysql> CREATE PROCEDURE proc1(OUT s int)   
    -> BEGIN   
    -> SELECT COUNT(*) INTO s FROM user;   
    -> END   
    -> //   
   mysql> DELIMITER ;   

注:

(1)这里需要注意的是DELIMITER //DELIMITER ;两句【一定注意delimiter与// 或者 ; 之间有空格!】,DELIMITER是分割符的意思,因为MySQL默认以”;”为分隔符,如果我们没有声明分割符,那么编译器会把存储过程当成SQL语句进行处理,则存储过程的编译过程会报错。

所以要事先用DELIMITER关键字申明当前段分隔符,这样MySQL才会将”;”当做存储过程中的代码,不会执行这些代码,用完了之后要把分隔符还原。 delimiter ; 

(2)存储过程根据需要可能会有输入、输出、输入输出参数,这里有一个输出参数s,类型是int型,如果有多个参数用”,”分割开。

(3)过程体的开始与结束使用BEGINEND进行标识。

 

这样,我们的一个MySQL存储过程就完成了,是不是很容易呢?看不懂也没关系,接下来,我们详细的讲解。

2)声明分割符

其实,关于声明分割符,上面的注解已经写得很清楚,不需要多说,只是稍微要注意一点的是:如果是用MySQL的管理工具(如navicat for mysql or sqlyog)时,可以直接创建,不再需要声明。

如下,在navicat 创建 存储过程:

CREATE  PROCEDURE `pinout`(INOUT `pinout` int)
BEGIN
    #Routine body goes here...
  IF pinout = 0 THEN
      SELECT COUNT(*) FROM c_user  into pinout;
  ELSE
      set pinout = -1;
  END IF;
END

3) 参数

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

CREATE PROCEDURE([[IN |OUT |INOUT ]参数名数据类形…])

IN-输入参数:表示该参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回,为默认值;

OUT-输出参数:该值可在存储过程内部被改变,并可返回;

INOUT-输入输出参数:调用时指定,并且可被改变和返回 。

具体参数示例点击查看存储过程示例

http://blog.csdn.net/j080624/article/details/55096307

 

Ⅰ. IN参数例子

创建:

mysql > DELIMITER // 
mysql > CREATE PROCEDURE demo_in_parameter(IN p_in int) 
-> BEGIN 
-> SELECT p_in; 
-> SET p_in=2; 
-> SELECT p_in; 
-> END; 
-> // 
mysql > DELIMITER ; 

执行结果: mysql
> SET @p_in=1; mysql > CALL demo_in_parameter(@p_in); +------+ | p_in | +------+ | 1 | +------+ +------+ | p_in | +------+ | 2 | +------+ mysql> SELECT @p_in; +-------+ | @p_in | +-------+ | 1 | +-------+ 以上可以看出,p_in虽然在存储过程中被修改,但并不影响@p_id的值

Ⅱ.OUT参数例子

创建:

mysql > DELIMITER // 
mysql > CREATE PROCEDURE demo_out_parameter(OUT p_out int) 
-> BEGIN 
-> SELECT p_out; 
-> SET p_out=2; 
-> SELECT p_out; 
-> END; 
-> // 
mysql > DELIMITER ; 
执行结果:

mysql > SET @p_out=1; 
mysql > CALL sp_demo_out_parameter(@p_out); 
+-------+ 
| p_out | 
+-------+ 
| NULL | 
+-------+ 
+-------+ 
| p_out | 
+-------+ 
| 2 | 
+-------+ 
mysql> SELECT @p_out; 
+-------+ 
| p_out | 
+-------+ 
| 2 | 
+-------+ 

Ⅲ. INOUT参数例子

创建:

mysql > DELIMITER // 
mysql > CREATE PROCEDURE demo_inout_parameter(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 demo_inout_parameter(@p_inout) ; 
+---------+ 
| p_inout | 
+---------+ 
| 1 | 
+---------+ 
+---------+ 
| p_inout | 
+---------+ 
| 2 | 
+---------+ 
mysql > SELECT @p_inout; 
+----------+ 
| @p_inout | 
+----------+ 
| 2 | 
+----------+ 

4)变量

Ⅰ. 变量定义

  • 需在过程体前声明局部变量;
  • 作用范围在begin end 之间;
DECLARE  variable_name [,variable_name...]  datatype  [DEFAULT value];

其中,datatype为MySQL的数据类型,如:int, float, date,varchar(length)

例如:

DECLARE l_int int unsigned default 4000000;
DECLARE l_numeric number(8,2) DEFAULT 9.95;
DECLARE l_date date DEFAULT '1999-12-31';
DECLARE l_datetime datetime DEFAULT '1999-12-31 23:59:59';
DECLARE l_varchar varchar(255) DEFAULT 'This will not be padded';

Ⅱ. 变量赋值

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

示例如下:

【存储过程中】

//存储过程中
begin
    ...//
    set number = 10; -- 为变量赋值
    select number; -- 获取变量值
end

Ⅲ.用户变量

①用户变量名一般以@开头 ;
②用户变量作用域范围为当前客户端;

即,可在存储过程外部查看该用户变量。

//navicat for mysql 工具中
set @number =10; -- 为变量赋值

select @number; -- 获取变量值

-- 或者

select 'hello' into @A;

select @A;

mysql> SET @number = 10;
Query OK, 0 rows affected (0.09 sec)

mysql> SELECT @number;
+---------+
| @number |
+---------+
|      10 |
+---------+
1 row in set (0.04 sec)

mysql> 
mysql> 
mysql> SELECT 'hello' INTO @A;
Query OK, 1 row affected (0.00 sec)

mysql> SELECT @A;
+-------+
| @A    |
+-------+
| hello |
+-------+
1 row in set (0.04 sec)

 

也可以在存储过程中使用用户变量:

  • 用户变量为会话级别,当次连接有效;
CREATE PROCEDURE GreetWorld( ) 
begin
SELECT CONCAT(@greeting,' World');
end 

--- 测试如下

SET @greeting='Hello';
CALL GreetWorld(); 

需要注意的是,用户变量尽量提前赋值(默认为null),且在本次链接中有效(一般不在存储过程中使用用户变量,而是使用参数传入)。

 

 

【注意】

存储过程内部使用变量,无论是局部变量或用户变量,尽量赋初值。

mysql中,对null进行任何运算,结果为null!!

 

 如果对''进行运算,效果如下:

 

 

【4】存储过程查看

查看数据库中创建的存储过程,有如下几种方式:

① show procedure status where db='数据库名';

② select routine_name from information_schema.routines where routine_schema='数据库名';

③ select name from mysql.proc where db=’数据库名’;

④  show procedure status; --查看所有存储过程

⑤ show procedure status like pattern;--模糊查询

【查看存储过程创建语句】

可以像查看表创建语句一样查看存储过程创建详细:

SHOW CREATE PROCEDURE [数据库.]存储过程名; 
-- 当前数据库下查询不需要数据库名

 

【5】修改存储过程

使用ALTER语句可以修改存储过程或函数的特性,只能修改特性,如果想修改过程体只能删除存储过程再重新创建。

MySQL中修改存储过程和函数的语句的语法形式如下:

ALTER {PROCEDURE | FUNCTION} sp_name [characteristic ...] 

characteristic: 

{ CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA } 
| SQL SECURITY { DEFINER | INVOKER } 
| COMMENT 'string'

其中释义如下:

① sp_name参数表示存储过程或函数的名称;

② characteristic参数指定存储函数的特性。

③ CONTAINS SQL表示子程序包含SQL语句,但不包含读或写数据的语句;

④ NO SQL表示子程序中不包含SQL语句;

⑤ READS SQL DATA表示子程序中包含读数据的语句;

⑥ MODIFIES SQL DATA表示子程序中包含写数据的语句。

⑦ SQL SECURITY { DEFINER | INVOKER }指明谁有权限来执行。

⑧ DEFINER表示只有定义者自己才能够执行;

⑨ INVOKER表示调用者可以执行;

⑩ COMMENT ‘string’是注释信息。

说明:修改存储过程使用ALTER PROCEDURE语句,修改存储函数使用ALTER FUNCTION语句。

但是,这两个语句的结构是一样的,语句中的所有参赛都是一样的。而且,它们与创建存储过程或函数的语句中的参数也是基本一样的。

测试如下:

ALTER PROCEDURE proc1 
SQL SECURITY INVOKER;
-- 指明调用者可以执行

查询结果状态:

SELECT SPECIFIC_NAME,SQL_DATA_ACCESS,
SECURITY_TYPE FROM 
information_schema.Routines WHERE ROUTINE_NAME='proc1' ;

 

【6】删除存储过程

删除一个存储过程比较简单,和删除表一样:

 

DROP PROCEDURE procName ;-- 删除存储过程
drop table table_name;-- 删除表
drop view view_name; -- 删除视图
drop database name;-- 删除数据库
drop function name;-- 删除函数
drop trigger name;-- 删除触发器

 

posted @ 2020-11-22 11:15  可樂Star  阅读(61)  评论(0编辑  收藏  举报