优化:
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;