(1)存储过程
存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。
1 存储过程语法
2 用户会话变量
3 条件结构
4 循环结构
存储过程语法
语法:
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;
DECLARE v1,v2 VARCHAR(20);
SET C= 5; //赋值
SELECT empno,empname INTO var1,v1 FROM emp WHERE empno =7499;
局部变量一般用在sql语句块中,比如存储过程的begin/end。其作用域仅限于该语句块,在该语句
块执行完毕后,局部变量就消失了。
条件结构
If语句
Case语句
1语法结构:
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 ;
2.语法结构:
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 ;
#判断学生的成绩,如果成绩大于等于90分,打印成绩优秀;成绩小于90大于等于80分,打印成绩良好;小于80分大于等于60分,打印成绩一般;否则打印不及格。
DELIMITER //
CREATE PROCEDURE asdf2(IN couse INT )
BEGIN
IF couse>=90 THEN
SELECT '优秀';
ELSEIF couse<90 AND couse>=80 THEN
SELECT '良好';
ELSEIF couse<80 AND couse>=60 THEN
SELECT '一般';
ELSE SELECT '不合格';
END IF;
END//
DELIMITER ;
#请输入两个整数a,b,比较a+b和a×b哪个大,输出判断结果。
DELIMITER //
CREATE PROCEDURE asdf4(IN a INT ,IN b INT)
BEGIN
IF
a+b>a*b THEN
SELECT 'a+b大于a*b';
ELSE SELECT 'a+b小于a*b';
END IF;
END//
DELIMITER;
#、有一张厚度为0.1毫米的纸,假设它足够大,重复将其对折,问对折多少次之后,其厚度可以抵达(再对折一次就超过)珠穆朗玛峰的高度?
DELIMITER //
CREATE PROCEDURE asdf11()
BEGIN
DECLARE test INT;
SET test=1;
WHILE POW(2,test)<=88480000 DO
SET test=test+1;
END WHILE;
SELECT test-1
END//
DELIMITER;
#2、自定义一张表,字段(id,name,phonenumber)用循环向这张表中插入10000条记录 不重复
CREATE TABLE TMPINSERT
(
id INT DEFAULT 1,
NAME VARCHAR(20),
phonenumber CHAR(11)
);
DELIMITER //
CREATE PROCEDURE protestinsert()
BEGIN
DECLARE num INT DEFAULT 1;
DECLARE name1 VARCHAR(20);
DECLARE phonenumber CHAR(11);
SET name1='Fod',phonenumber='15599869535';
WHILE(num<=100)
DO
INSERT INTO TMPINSERT VALUES(num,name1,phonenumber);
SET num=num+1, name1=CONCAT('fod',num),phonenumber=phonenumber-1;
END WHILE;
SELECT * FROM TMPINSERT;
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 ;
举例
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语句结构:
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循环格式:
[循环标签:] 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循环标签后必须以“;”结束
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 ;
案例:编写一个存储过程,完成两个正整数加法,返回计算结果
DELIMITER //
CREATE PROCEDURE pAdd(IN m INT ,IN n INT,OUT result INT )
BEGIN
SET result = m + n;
END;//
DELIMITER ;
将表中的数据以各式导出到文件夹
SELECT username
INTO OUTFILE "c:\user.dat"
LINES TERMINATED BY "\r\n"
FROM pw_members;