mysql数据库存储过程

2018-7-19    分类: php学习,网络安全

优化:

1,将一些业务逻辑放在数据库里判断,执行效率快。

2,程序语言的移植也方便。例如php转java,等等。

3,避免sql注入的破坏。

 

 

缺点:

1,给服务器造成压力

2,过多业务逻辑放在数据库里判断,不好维护,修改也不方便。往往都要删除了在重新声明存储过程。

3,换数据库之后,存储过程的逻辑要重写。

4,不好调试

 

 

在创建mysql存储过程之前,要先聊一些基础,不然后面学习会痛苦:

DELIMITER // 要先输入,说明以下代码是存储过程
CEATE PROCEDURE demo_in_parameter(IN p_in int) 声明存储过程名为demo_in_parameter,参数名p_in,输入参数,整数类型

IN //接收外来值,外来值不会变。在存储过程中改变的值不会去修改全局环境的值 (最好看例子)
OUT //不接收外来值,但可以直接修改外来值。在存储过程中可以修改覆盖全局的变量(最好看例子)
INOUT //接收外来值,值也会被覆盖。(最好看例子)
 
BEGIN ... END 存储过程开始和结束符号 
SET @p_in=1 SET可以在全局环境中声明变量,也可以在存储过程中修改变量。存储过中不需要@
DECLARE l_int int unsigned default 4000000; 只能在存储过程里面声明变量

 

 

IN参数例子:

mysql > DELIMITER // 
mysql > CREATE PROCEDURE demo_in_parameter(IN p_in int) 
     -> BEGIN 
     -> SELECT p_in;  --接收并输出外来变量
     -> SET p_in=2; 
     -> SELECT p_in;  --输出修改后的p_in值,但是不会影响全局变量中的p_in值
     -> END; 
     -> // 
mysql > DELIMITER ;

 

结果:

1. mysql > SET @p_in=1; --外来的全局变量
2. mysql > CALL demo_in_parameter(@p_in); --传入外来变量
3. +------+ 
4. | p_in | 
5. +------+ 
6. | 1 |      --IN的参数接收外来变量,并输出
7. +------+ 
8. 
9. +------+ 
10.| p_in | 
11.+------+ 
12.| 2 |      --在存储过程可以修改外来变量值,仅仅在存储过程有效
13.+------+ 
14. 
15.mysql> SELECT @p_in; 
16.+-------+ 
17.| @p_in | 
18.+-------+ 
19.| 1 |      --IN的参数,在存储过程里面修改不会影响到全局中的原来值
20.+-------+

 

 

OUT参数例子:

mysql > DELIMITER // 
mysql > CREATE PROCEDURE demo_out_parameter(OUT p_out int) 
     -> BEGIN 
     -> SELECT p_out;  --OUT的参数,不接收外面传来的参数返回一个NULL
     -> SET p_out=2;   --但可以在内部彻底修改外面全局变量的值
     -> SELECT p_out;  --被修改外面全局变量的值会被影响覆盖
     -> END; 
     -> // 
mysql > DELIMITER ;

 

结果:

1. mysql > SET @p_out=1; 
2. mysql > CALL demo_out_parameter(@p_out); 
3. +-------+ 
4. | p_out | 
5. +-------+ 
6. | NULL |   --OUT参数不会接收和输出外来变量的值
7. +-------+ 
8. 
9. +-------+ 
10.| p_out | 
11.+-------+ 
12.| 2 |      --但可以修改影响全局变量的值
13.+-------+ 
14. 
15.mysql> SELECT @p_out; 
16.+-------+ 
17.| p_out | 
18.+-------+ 
19.| 2 |      --OUT参数可以直接影响全局变量的值
20.+-------+

 

 

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 ;

 

结果:

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.+----------+

 

 

 

综合案例:

 

DELIMITER // --说明开始写存储过程
CREATE PROCEDURE proc2(IN parameter1 INTEGER) --声明存储过程名为proc2,参数名parameter1,类型INTEGER,参数类型IN
BEGIN --开始写逻辑
DECLARE variable1 CHAR(10); --声明存储过程里面的内部变量名为variable1,注意加分号;
IF parameter1 = 17 THEN --if条件判断
SET variable1 = 'birds'; --为之前的变量赋值,可以使用SET
ELSE
SET variable1 = 'beasts';
END IF; --if条件结束,加分号;
insert into liuyan_user(liuyan_username) values (variable1);
END; --逻辑结束
//
DELIMITER ; --存储过程结束

set @xx1=17; --声明全局变量,也可以在存储过程里面声明但不需要加@
CALL proc2(@xx1); --调用存储过程

 

结果:

 

 

 

一些简单案例:(主要学习声明存储过程还有哪些方式)

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

 

 

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( ); 
 +-----------------------------------------------+ 
 | CONCAT('Last procedure was ',@last_proc | 
 +-----------------------------------------------+ 
 | Last procedure was p1 | 
 +-----------------------------------------------+

 

 

 

存储过程局部变量:(只能在存储过程中声明)

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';

 

 

条件:

-> if parameter=0 then 
-> ...
-> else 
-> ...
-> end if;

 

 

循环:

while

 -> declare var int; 
 -> set var=0; 
 -> while var<6 do --没分号
 -> insert into t values(var); 
 -> set var=var+1; 
 -> end while;

 

repeat...until

 -> declare v int; 
 -> set v=0; 
 -> repeat  --没分号
 -> insert into t values(v); 
 -> set v=v+1; 
 -> until v>=5  --没分号
 -> end repeat;

 

loop ·····endloop

这个循环的好处就是有类似于contiune和break的功能。

 ->declare v int; 
 -> set v=0; 
 -> LOOP_LABLE:loop 
 -> insert into t values(v); 
 -> set v=v+1; 
 -> if v >=5 then 
 -> leave LOOP_LABLE; --只有v >=5就退出循环,类似于break
 -> end if; 
 -> end loop;

 

 -> declare v int; 
 -> set v=0; 
 -> LOOP_LABLE:loop 
 -> if v=3 then 
 -> set v=v+1; 
 -> ITERATE LOOP_LABLE;  --跳过v=3的步骤,类似contiune
 -> end if; 
 -> insert into t values(v); 
 -> set v=v+1; 
 -> if v>=5 then 
 -> leave LOOP_LABLE; 
 -> end if; 
 -> end loop;

 

https://blog.csdn.net/a__yes/article/details/52795793