存储过程
存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。
语法:
CREATE PROCEDURE 过程名 ([[IN|OUT|INOUT] 参数名 数据类型
[,[IN|OUT|INOUT] 参数名 数据类型…]])
BEGIN
过程体
END;
举例:
DELIMITER //
CREATE PROCEDURE myproc(OUT s int)
BEGIN
SELECT COUNT(*) INTO s FROM students;
END;
//DELIMITER ;
说明:
分隔符
MySQL默认以";"为分隔符,如果没有声明分割符,则编译器会把存储过程当成SQL语句进行处理,因此编译过程会报错,所以要事先用“DELIMITER //”声明当前段分隔符,让编译器把两个"//"之间的内容当做存储过程的代码,不会执行这些代码;“DELIMITER ;”的意为把分隔符还原。
参数
存储过程根据需要可能会有输入、输出、输入输出参数,如果有多个参数用","分割开。MySQL存储过程的参数用在存储过程的定义,共有三种参数类型,IN,OUT,INOUT:
IN参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回,为默认值 OUT:该值可在存储过程内部被改变,并可返回 INOUT:调用时指定,并且可被改变和返回。
过程体
过程体的开始与结束使用BEGIN与END进行标识。
存储过程是一组SQL语句
增强SQL语言的功能和灵活性:
存储过程可以用控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。
提升复用程度 :
存储过程被创建后,可以在程序中被多次调用,而不必重新编写该存储过程的SQL语句。
较快的执行速度:
存储过程是预编译的。而批处理的SQL语句在每次运行时都要进行编译和优化,速度相对要慢一些。
减少网络流量:
针对同一个数据库对象的操作,如果操作的SQL语句写在存储过程,当在客户计算机上调用该存储过程时,网络中传送的只是该调用语句,从而大大减少网络流量并降低了网络负载
调用存储过程
语法:
CALL precedure_name([param1,param2]…..)
举例:
CALL pr_add(10, 20);
用户定义变量
MySQL存储过程中,定义变量有两种方式:
用户变量:
使用SET或SELECT直接赋值,变量名以 @ 开头.
例如: SET @var=1;
SELECT @var:=5;
SELECT empno,ename INTO @var,@name FROM EMP WHERE empno =7499 ;
可以在一个会话的任何地方声明,用户变量可以作用于当前整个连接,但是当前连接断开后,其所定义的用户变量都会消失称为用户变量。
局部变量:
DECLARE 关键字声明的变量,只能在存储过程中使用,称为存储过程变量,
格式:
DECLARE varname1[,varname2] …… datatype [DEFAULT VALUE]
例如:
DECLARE var1 INT DEFAULT 0;
DECLAR v1,v2 VARCHAR(20);
SET C= 5; //赋值
SELECT empno,empname INTO var1,v1 FROM emp WHERE empno =7499;
局部变量一般用在sql语句块中,比如存储过程的begin/end。其作用域仅限于该语句块,在该语句块执行完毕后,局部变量就消失了。
条件结构
If语句
①语法结构:
if 条件表达式1 then
语句块1;
end if;
说明:end if后必须以“;”结束
举例:
DELIMITER //
CREATE PROCEDURE pTest()
BEGIN
DECLARE vHour INT;
SET vHour =10;
IF vHour>40 THEN
SELECT '加班了';
END IF;
END//
DELIMITER
②语法结构:
if 条件表达式1 then
语句块;
else
语句块;
end if;
说明:end if后必须以“;”结束
举例:
DELIMITER //
CREATE PROCEDURE pTest()
BEGIN
DECLARE vHour INT;
SET vHour =10;
IF vHour>40 THEN
SELECT '加班了';
ELSE
SELECT '没加班';
END IF;
END//
DELIMITER
③语法结构:
if 条件表达式1 then
语句块1;
[elseif 条件表达式2 then
语句块2] ...
[else 语句块n]
end if;
说明:end if后必须以“;”结束
举例:
DELIMITER $$
CREATE PROCEDURE pTest()
BEGIN
DECLARE vHour INT;
SET vHour =60;
IF vHour>70 THEN
SELECT '加班超多';
ELSEIF vHour> 50 AND vHour<=70 THEN
SELECT '加班多';
ELSEIF vHour >40 AND vHour<=50 THEN
SELECT '有加班';
ELSE
SELECT '没加班';
END IF;
END$$
DELIMITER ;
case语句
①语法结构:
case 表达式
when value1 then 语句块1;
when value2 then 语句块2;
…
else 语句块n;
end case;
举例:
DELIMITER //
CREATE PROCEDURE pCase()
BEGIN
DECLARE job CHAR(50);
SET job ='a';
CASE job
WHEN 'a' THEN SELECT '工作是经理';
WHEN 'b' THEN SELECT '工作是财务';
WHEN 'c' THEN SELECT '工作是人事';
WHEN 'd' THEN SELECT '工作是行政';
ELSE SELECT '是其它工作';
END CASE;
END;//
DELIMITER
②语法结构:
case 表达式
when value1 then 语句块1;
when value2 then 语句块2;
…
else 语句块n;
end case;
举例:
DELIMITER //
CREATE PROCEDURE pCase()
BEGIN
DECLARE job CHAR(50);
SET job ='a';
CASE job
WHEN 'a' THEN SELECT '工作是经理';
WHEN 'b' THEN SELECT '工作是财务';
WHEN 'c' THEN SELECT '工作是人事';
WHEN 'd' THEN SELECT '工作是行政';
ELSE SELECT '是其它工作';
END CASE;
END;//
DELIMITER ;
③语法结构:
case
when 表达式1 then 语句块1;
when 表达式2 then 语句块2;
…
else 语句块n;
end case;
举例:
DELIMITER //
CREATE PROCEDURE pCase2()
BEGIN
DECLARE vNum CHAR(20);
SET vNum = 80;
CASE
WHEN vNum IS NULL THEN SELECT '没有分数';
WHEN vNum>90 THEN SELECT '成绩优异';
WHEN vNum<90 AND vNum>=60 THEN SELECT '成绩良';
ELSE SELECT '没有及格';
END CASE;
END;//
DELIMITER ;
循环结构
MySQL提供了三种循环语句:
While
Loop
Repeat
除此以外,MySQL还提供了iterate语句以及leave语句用于循环的控制。
while语句结构:
while 条件表达式 do
循环体;
end while ;
说明:
1)end while后必须以“;”结束
2)当条件表达式的值为true时,反复执行循环体
,直到条件表达式的值为false
语法结构:
DELIMITER //
CREATE PROCEDURE pWhile()
BEGIN
DECLARE vNum INT;
SET vNum = 0;
WHILE vNum<20 DO
SET vNum= vNum + 1;
END WHILE;
SELECT vNum;
END;//
DELIMITER ;
Loop循环格式:
[循环标签:] loop
循环体;
if 条件表达式 then
leave [循环标签];
end if;
end loop;
说明:end loop后必须以“;”结束
DELIMITER //
CREATE PROCEDURE pLoop()
BEGIN
DECLARE vNum INT;
SET vNum = 0;
addLoop:LOOP
IF vNum>20 THEN
LEAVE addLoop;
END IF;
SET vNum= vNum + 1;
END LOOP addloop;
SELECT vNum;
END;//
DELIMITER ;
Leave关键字:用于跳出当前的循环语句(例如while语句)
语法格式如下:
leave 循环标签;
说明:leave 循环标签后必须以“;”结束
Iterate关键字:用于跳出本次循环,继而进行下次循环。
语法格式:
Iterate 循环标签;
说明:iterate循环标签后必须以“;”结束
Iterate语句:
DELIMITER //
CREATE PROCEDURE piterate()
BEGIN
DECLARE vNum INT;
SET vNum = 0;
addLoop:LOOP
SET vNum= vNum + 1;
IF vNum<10 THEN ITERATE addloop;
ELSEIF vNum>20 THEN LEAVE addloop;
END IF;
SELECT 'vnum <=0 and vnum >=10';
END LOOP addloop;
SELECT vNum;
END;//
DELIMITER ;
repeat语句:
当条件表达式的值为false时,反复执行循环,
直到条件表达式的值为true
[循环标签:]repeat
循环体;
until 条件表达式
end repeat [循环标签];
说明:end repeat后必须以“;”结束
DELIMITER //
CREATE PROCEDURE prepeat()
BEGIN
DECLARE vNum INT;
SET vNum = 0;
addrepeat:REPEAT
SET vNum= vNum + 1;
UNTIL vNum>20
END REPEAT addrepeat;
SELECT vNum;
END;//
DELIMITER ;