MySQL的存储过程 (转)

转自 http://luyongxin88.blog.163.com/blog/#m=0&t=3&c=mysql

存储过程是数据库存储的一个重要的功能,但是MySQL在5.0以前并不支持存储过程,这使得MySQL在应用上大打折扣。好在MySQL 5.0终于开始已经支持存储过程,这样即可以大大提高数据库的处理速度,同时也可以提高数据库编程的灵活性。
3.      MySQL存储过程的创建
 
(1). 格式
MySQL存储过程创建的格式:CREATE PROCEDURE 过程名 ([过程参数[,...]])
[特性 ...] 过程体
这里先举个例子:
  
   1. mysql> DELIMITER // 
   2. mysql> CREATE PROCEDURE proc1(OUT s int) 
   3.     -> BEGIN
   4.     -> SELECT COUNT(*) INTO s FROM user; 
   5.     -> END
   6.     -> // 
   7. mysql> DELIMITER ;

在工具中使用

 

 CREATE PROCEDURE proc1(OUT s int)
BEGIN                           
SELECT COUNT(*) INTO s FROM user;
END        

                   
注:
(1) 这里需要注意的是DELIMITER //和DELIMITER ;两句,DELIMITER是分割符的意思,因为MySQL默认以";"为分隔符,如果我们没有声明分割符,那么编译器会把存储过程当成SQL语句进行处 理,则存储过程的编译过程会报错,所以要事先用DELIMITER关键字申明当前段分隔符,这样MySQL才会将";"当做存储过程中的代码,不会执行这 些代码,用完了之后要把分隔符还原。
(2)存储过程根据需要可能会有输入、输出、输入输出参数,这里有一个输出参数s,类型是int型,如果有多个参数用","分割开。
(3)过程体的开始与结束使用BEGIN与END进行标识。
这样,我们的一个MySQL存储过程就完成了,是不是很容易呢?看不懂也没关系,接下来,我们详细的讲解。
 
(2). 声明分割符
其实,关于声明分割符,上面的注解已经写得很清楚,不需要多说,只是稍微要注意一点的是:如果是用MySQL的Administrator管理工具时,可以直接创建,不再需要声明。
 
(3). 参数
MySQL存储过程的参数用在存储过程的定义,共有三种参数类型,IN,OUT,INOUT,形式如:
CREATE PROCEDURE([[IN |OUT |INOUT ] 参数名 数据类形...])
IN 输入参数:表示该参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回,为默认值
OUT 输出参数:该值可在存储过程内部被改变,并可返回
INOUT 输入输出参数:调用时指定,并且可被改变和返回
Ⅰ. IN参数例子
创建:
   1. mysql > DELIMITER // 
   2. mysql > CREATE PROCEDURE demo_in_parameter(IN p_in int) 
   3. -> BEGIN  
   4. -> SELECT p_in; /*查询输入参数*/ 
   5. -> SET p_in=2; /*修改*/ 
   6. -> SELECT p_in; /*查看修改后的值*/ 
   7. -> END;  
   8. -> // 
   9. mysql > DELIMITER ;

执行结果:
   1. mysql > SET @p_in=1; 
   2. mysql > CALL demo_in_parameter(@p_in); 
   3. +------+ 
   4. | p_in | 
   5. +------+ 
   6. |   1  |  
   7. +------+ 
   8. 
   9. +------+ 
  10. | p_in | 
  11. +------+ 
  12. |   2  |  
  13. +------+ 
  14. 
  15. mysql> SELECT @p_in; 
  16. +-------+ 
  17. | @p_in | 
  18. +-------+ 
  19. |  1    | 
  20. +-------+ 

以上可以看出,p_in虽然在存储过程中被修改,但并不影响@p_id的值
 
Ⅱ.OUT参数例子
创建:
   1. mysql > DELIMITER // 
   2. mysql > CREATE PROCEDURE demo_out_parameter(OUT p_out int) 
   3. -> BEGIN
   4. -> SELECT p_out;/*查看输出参数*/ 
   5. -> SET p_out=2;/*修改参数值*/ 
   6. -> SELECT p_out;/*看看有否变化*/ 
   7. -> END; 
   8. -> // 
   9. mysql > DELIMITER ;

执行结果:
   1. mysql > SET @p_out=1; 
   2. mysql > CALL sp_demo_out_parameter(@p_out); 
   3. +-------+ 
   4. | p_out |  
   5. +-------+ 
   6. | NULL  |  
   7. +-------+ 
   8. /*未被定义,返回NULL*/ 
   9. +-------+ 
  10. | p_out | 
  11. +-------+ 
  12. |   2   |  
  13. +-------+ 
  14. 
  15. mysql> SELECT @p_out; 
  16. +-------+ 
  17. | p_out | 
  18. +-------+ 
  19. |   2   | 
  20. +-------+ 

Ⅲ. INOUT参数例子
创建:
   1. mysql > DELIMITER //  
   2. mysql > CREATE PROCEDURE demo_inout_parameter(INOUT p_inout int)  
   3. -> BEGIN
   4. -> SELECT p_inout; 
   5. -> SET p_inout=2; 
   6. -> SELECT p_inout;  
   7. -> END; 
   8. -> //  
   9. mysql > DELIMITER ;
 
 
执行结果:
   1. mysql > SET @p_inout=1; 
   2. mysql > CALL demo_inout_parameter(@p_inout) ; 
   3. +---------+ 
   4. | p_inout | 
   5. +---------+ 
   6. |    1    | 
   7. +---------+ 
   8. 
   9. +---------+ 
  10. | p_inout |  
  11. +---------+ 
  12. |    2    | 
  13. +---------+ 
  14. 
  15. mysql > SELECT @p_inout; 
  16. +----------+ 
  17. | @p_inout |  
  18. +----------+ 
  19. |    2     | 
  20. +----------+

(4). 变量
Ⅰ. 变量定义
DECLARE variable_name [,variable_name...] datatype [DEFAULT value];
其中,datatype为MySQL的数据类型,如:int, float, date, varchar(length)
例如:
   1. DECLARE l_int int unsigned default 4000000; 
   2. DECLARE l_numeric number(8,2) DEFAULT 9.95; 
   3. DECLARE l_date date DEFAULT '1999-12-31'; 
   4. DECLARE l_datetime datetime DEFAULT '1999-12-31 23:59:59'; 
   5. DECLARE l_varchar varchar(255) DEFAULT 'This will not be padded';  
 
 
Ⅱ. 变量赋值
 SET 变量名 = 表达式值 [,variable_name = expression ...]
 
Ⅲ. 用户变量
 
ⅰ. 在MySQL客户端使用用户变量
   1. mysql > SELECT 'Hello World' into @x; 
   2. mysql > SELECT @x; 
   3. +-------------+ 
   4. |   @x        | 
   5. +-------------+ 
   6. | Hello World | 
   7. +-------------+ 
   8. mysql > SET @y='Goodbye Cruel World'; 
   9. mysql > SELECT @y; 
  10. +---------------------+ 
  11. |     @y              | 
  12. +---------------------+ 
  13. | Goodbye Cruel World | 
  14. +---------------------+ 
  15. 
  16. mysql > SET @z=1+2+3; 
  17. mysql > SELECT @z; 
  18. +------+ 
  19. | @z   | 
  20. +------+ 
  21. |  6   | 
  22. +------+ 
ⅱ. 在存储过程中使用用户变量
   1. mysql > CREATE PROCEDURE GreetWorld( ) SELECT CONCAT(@greeting,' World'); 
   2. mysql > SET @greeting='Hello'; 
   3. mysql > CALL GreetWorld( ); 
   4. +----------------------------+ 
   5. | CONCAT(@greeting,' World') | 
   6. +----------------------------+ 
   7. |  Hello World               | 
   8. +----------------------------+ 
ⅲ. 在存储过程间传递全局范围的用户变量
   1. mysql> CREATE PROCEDURE p1()   SET @last_procedure='p1'; 
   2. mysql> CREATE PROCEDURE p2() SELECT CONCAT('Last procedure was ',@last_proc); 
   3. mysql> CALL p1( ); 
   4. mysql> CALL p2( ); 
   5. +-----------------------------------------------+ 
   6. | CONCAT('Last procedure was ',@last_proc  | 
   7. +-----------------------------------------------+ 
   8. | Last procedure was p1                         | 
   9. +-----------------------------------------------+ 
 
 
注意:
①用户变量名一般以@开头
②滥用用户变量会导致程序难以理解及管理
 
(5). 注释
 
MySQL存储过程可使用两种风格的注释
双模杠:--
该风格一般用于单行注释
c风格:/* 注释内容 */ 一般用于多行注释
例如:
 
   1. mysql > DELIMITER // 
   2. mysql > CREATE PROCEDURE proc1 --name存储过程名 
   3. -> (IN parameter1 INTEGER) /* parameters参数*/ 
   4. -> BEGIN /* start of block语句块头*/ 
   5. -> DECLARE variable1 CHAR(10); /* variables变量声明*/ 
   6. -> IF parameter1 = 17 THEN /* start of IF IF条件开始*/ 
   7. -> SET variable1 = 'birds'; /* assignment赋值*/ 
   8. -> ELSE
   9. -> SET variable1 = 'beasts'; /* assignment赋值*/ 
  10. -> END IF; /* end of IF IF结束*/ 
  11. -> INSERT INTO table1 VALUES (variable1);/* statement SQL语句*/ 
  12. -> END /* end of block语句块结束*/ 
  13. -> // 
  14. mysql > DELIMITER ; 
 
4.      MySQL存储过程的调用
用call和你过程名以及一个括号,括号里面根据需要,加入参数,参数包括输入参数、输出参数、输入输出参数。具体的调用方法可以参看上面的例子。
5.      MySQL存储过程的查询
我们像知道一个数据库下面有那些表,我们一般采用show tables;进行查看。那么我们要查看某个数据库下面的存储过程,是否也可以采用呢?答案是,我们可以查看某个数据库下面的存储过程,但是是令一钟方式。
我们可以用
select name from mysql.proc where db=’数据库名’;
或者
select routine_name from information_schema.routines where routine_schema='数据库名';
或者
show procedure status where db='数据库名';
进行查询。
如果我们想知道,某个存储过程的详细,那我们又该怎么做呢?是不是也可以像操作表一样用describe 表名进行查看呢?
答案是:我们可以查看存储过程的详细,但是需要用另一种方法:
SHOW CREATE PROCEDURE 数据库.存储过程名;
就可以查看当前存储过程的详细。
 
6.      MySQL存储过程的修改
ALTER PROCEDURE
更改用CREATE PROCEDURE 建立的预先指定的存储过程,其不会影响相关存储过程或存储功能。
 
7.      MySQL存储过程的删除
删除一个存储过程比较简单,和删除表一样:
DROP PROCEDURE
从MySQL的表格中删除一个或多个存储过程。
===========================================

以 上是转的,虽然看了过,也做个几个,但实际上要用的时候,自己还是不能马上上手,以至于那么公司的一个小朋友问我有关数据库的问题,我想到了mysql的 存储过程,却不能在10分钟内帮他解决,还整了我一个晚上,有点耻辱,我觉得记在这里,以示警示。尽可能不转载,转载了也要自己实际实践来用自己的话说出 来。

=====================

MySQL 存储过程

1. 创建的语法

a.在命令行中创建

 

   1. mysql> DELIMITER // 
   2. mysql> CREATE PROCEDURE proc1(OUT s int) 
   3.     -> BEGIN
   4.     -> SELECT COUNT(*) INTO s FROM user; 
   5.     -> END
   6.     -> // 
   7. mysql> DELIMITER ;

 b. 在图形工具中创建 (以下都是有Navicat工具)

 

 CREATE PROCEDURE proc1(OUT s int)
 BEGIN                           
    SELECT COUNT(*) INTO s FROM user;
END     

   以下的学习以两个表为例

  假设我们有以下2张表: student , detail_info 。

  其他detail_info的外键是name (也就是说detail_tail 中name的值要在student中有)

MySQL的存储过程 (转) - 流口水的小猪 - 轨迹
MySQL的存储过程 (转) - 流口水的小猪 - 轨迹
2.  IN参数的例子
MySQL的存储过程 (转) - 流口水的小猪 - 轨迹
 create PROCEDURE pro_in(in i int)
Begin
  select name from student where id=i;
end
(in参数的标志 in是可以省略的)
 调用执行
MySQL的存储过程 (转) - 流口水的小猪 - 轨迹
 
3. OUT参数的例子
create PROCEDURE pro_out(out i int)
Begin
  select id into i from student where name='Bill';
end
   调用执行
MySQL的存储过程 (转) - 流口水的小猪 - 轨迹
 这里涉及到存储过程的Out参数的使用。当我们调用一个具有Out参数的存储过程后,我们可以直接使用Out返回的值
  
4  INOUT参数的例子
create PROCEDURE pro_inout(inout i int)
Begin
  select age into i from student where id=i;
end
   调用执行
MySQL的存储过程 (转) - 流口水的小猪 - 轨迹
我所认为的,INOUT参数就是既可以当输入,有可以当输出。不过我觉得这不是好方法,容易造成混淆,不宜多用。
 
MySQl存储过程中可以使用的循环:WHILE循环,LOOP循环以及REPEAT循环。还有一种非标准的循环方式:GO TO (建议不用)
另外,我个人觉得,之前了解while循环循环就足矣解决大部分的问题了
5. While循环的例子
 create PROCEDURE pro_where()
Begin
  declare j INT;
  set j=1;
  while j<4 do
    update student set sex='female' where id=j;
    set j=j+1; 
  end while;
end
  调用执行
MySQL的存储过程 (转) - 流口水的小猪 - 轨迹
  
 6. IF ....end if 例子
 create PROCEDURE pro_if(in n int)
Begin
  declare j INT;   /*  获得总行数 */
  select count(*) into j from student;
  if n<j then
    select * from student where id=n;
  else 
    SELECT j;
  end if;
end
(如果输入的值大于了表中的行,即表中没有,就输入表的行数,如果有,就把该行记录选择出来)
调用执行
MySQL的存储过程 (转) - 流口水的小猪 - 轨迹
MySQL的存储过程 (转) - 流口水的小猪 - 轨迹
 
7. Mysql 存储过程的一些特点(与Oracle相比较)
 A. MySQL 存储过程参数如果不显式指定“in”、“out”、“inout”,则默认为“in”。习惯上,对于是“in” 的参数,我们都不会显式指定。
 B. MySQL 存储过程参数,不能在参数名称前加“@”
 C. MySQL 存储过程不需要在 procedure body 前面加 “as”。
 D. MySQL 存储过程中的每条语句的末尾,都要加上分号 “;”
 E. 调用 MySQL 存储过程时候,需要在过程名字后面加“()”,即使没有一个参数,也需要“()”
 F. MySQL 存储过程创建时没有 create or replace 的用法,如果存储过程存在,需要先删除才能再创建。

posted on 2013-05-22 16:18  ibelieve  阅读(474)  评论(0)    收藏  举报

导航