MySQL 存储过程

表和视图,存储过程和函数的区别

: 是真实存在的,它占存储空间

视图 : 相当于一个查询语句,不占有存储空间

------------------------------------------------------------------------------------

函数 : 只能返回一个变量, 可以嵌入SQL中使用

存储过程 : 可以返回多个变量, 用CALL命令调用,不能嵌入SQL中

函数和存储过程本质上没有区别

一个存储过程的示例

先看一个存储过程的示例,后边详细介绍

DELIMITER //    --把结束符改成//
CREATE PROCEDURE proc1()
BEGIN
	SELECT * FROM users;
	SELECT * from goods;
END//
DELIMITER ;     --把结束符改回;

  使用CALL proc1();调用该存储过程后,会把users表和goods表的所有数据展示出来

存储过程的声明

CREATE PROCEDURE 过程名() BEGIN ...... END;

1.过程名必须要加上括号(),可以用来传参

2.BEGIN......END;这一段叫做过程体,过程体中可以嵌套BEGIN...END;

嵌套BEGIN...END的示例:

DELIMITER $$
CREATE PROCEDURE proc2()
BEGIN
	SELECT * FROM users;
	BEGIN
		SELECT * FROM goods;
	END ;
END $$
DELIMITER ;

声明变量

局部变量 : DECLARE 变量名 数据类型 [ DEFAULT 默认值 ] ;

示例 : DECLARE numb INT DEFAULT 1;

用户变量 : 在变量名前加@,无需声明,在使用时给变量名前加上@即可.

示例 : SELECT @a:=1; (可以复制这句SQL运行试试)

     SET @a=@a+1;  

局部变量和用户变量比较:

  1.作用域 : 局部变量作用域在过程体内,用于变量作用域是全局

  2.生命周期 : 局部变量在执行完对应的过程体后消亡,用户变量在会话中断时消亡(用户变量的生命周期是一次会话/连接)

  3.用户变量在普通的SQL语句上也可以使用,比如 SELECT @a:=1; 会查询到a=1的结果,自己试试吧~ 在SELECT 后使用用户变量,需要用:=来赋值,SET后则=和:=都可用

示例

DELIMITER //
CREATE PROCEDURE proc3()
BEGIN
	DECLARE a INT DEFAULT 1;
	SET @z=1;
	SET @z=@z+1;
	SELECT a;
	SELECT @z;
END//
DELIMITER ;
--call proc3();后,运行结果
--a=1 , z=2
--自己试试吧

  

存储过程的参数

在存储过程的声明中我们讲过,存储过程名后必须加上括号(),这个括号就是用来传参的.

存储过程可以传3种不同的参数

  1.in : 输入参数,可以传入字面量或变量

  2.out : 输出参数,只能传入变量

  3.inout : 输入输出参数,只能传入变量

参数的定义方法是 : 存储过程名(in 参数名 数据类型)

一.in输入参数

DELIMITER //
CREATE PROCEDURE proc4(IN numb INT)
BEGIN
	SELECT numb;
	SET numb=numb+5;
	SELECT numb;
END//
DELIMITER ;
SET @a=2;
CALL proc4(@a);--也可以传入字面量,比如3
--结果1:numb=2
--结果2:numb=7

二.out输出参数

DELIMITER //
CREATE PROCEDURE proc5(OUT numb INT)
BEGIN
	SELECT numb;
	SET numb=5;
	SELECT numb;
END//
DELIMITER ;

SET @a=1; CALL proc5(@a); --此处@a用于接收输出参数的值 --执行结果如下 --结果1:numb=null 因为@a作为输出参数传入,所以这里接收不到@a的值,输出null --结果2:numb=5 SELECT @a; --结果:@a=5

三.inout输入输出参数

DELIMITER //
CREATE PROCEDURE proc6(INOUT numb INT)
BEGIN
	SELECT numb;
	SET numb=numb+5;
	SELECT numb;
END//
DELIMITER ;

SET @a=1;
CALL proc6(@a);   --用@a接收输出结果
--结果1:numb=1
--结果2:numb=6
SELECT @a;
--结果:@a=6

存储过程的控制语句

一.条件语句

  1.if - then - else语句

  格式 : if 判断 then 执行语句

       elseif 判断 then 执行语句

       else 执行语句

       end if;

DELIMITER //
CREATE PROCEDURE proc7(IN numb INT)
BEGIN
	IF numb>5 THEN SET numb=numb-5;
	ELSEIF -5<numb<0 THEN SET numb=numb+5;
	ELSE SET numb=numb+10;
	END IF;
	SELECT numb;
END//
DELIMITER ;

  2.case语句

  格式 : case 变量

       when 判断 THEN 执行语句

       else 执行语句

DELIMITER //
CREATE PROCEDURE proc8(IN numb INT)
BEGIN
	CASE numb
	WHEN 1 THEN SET numb=numb+3;
	WHEN 2 THEN SET numb=numb-6;
	ELSE SET numb=0;
	END CASE;
	SELECT numb;
END//
DELIMITER ;

二.循环语句

  1.while循环

  格式 : while 判断 do

       循环语句;

       end while;

DELIMITER //
CREATE PROCEDURE proc9(IN numb INT)
BEGIN
	WHILE numb<=0 DO
	SET numb=numb+3;
	END WHILE;
	SELECT numb;
END//
DELIMITER ;

  2.repeat循环

  格式 : repeat

       循环语句;

       until 判断 

       end repeat;

DELIMITER //
CREATE PROCEDURE proc10(IN numb INT)
BEGIN
	REPEAT
	SET numb=numb+3;
	UNTIL numb>5
	END REPEAT;
	SELECT numb;
END//
DELIMITER ;

  3.loop循环

  格式 : 标签:loop

       循环语句;

       if 判断 then leave 标签;

       end if; 

       end loop;

DELIMITER //
CREATE PROCEDURE proc11(IN numb INT)
BEGIN
	a:LOOP
	SET numb=numb+3;
	IF numb>50 THEN LEAVE a;
	END IF;
	END LOOP;
	SELECT numb;
END//
DELIMITER ;

  4.iterate : 相当于continue,结合标签使用

DELIMITER //
CREATE PROCEDURE proc12(IN numb INT)
BEGIN
	DECLARE str VARCHAR(100) DEFAULT '开始';
	loop_lable:LOOP
	SET numb=numb-1;
	IF numb>1 THEN 
		SET str=CONCAT(str, numb);
		ITERATE loop_lable;  --相当于continue,意思是从loop_lable标签处继续循环
	ELSE
	SET str=CONCAT(str, '结束');
	LEAVE loop_lable;
	END IF;
	END LOOP;
	SELECT str;
	SELECT numb;
END//
DELIMITER ;

CALL prop12(5);    --结果是str='开始432结束'

  

 

f

posted @ 2019-05-07 17:31  Kaneha  阅读(341)  评论(0编辑  收藏  举报