| 存储过程和存储函数是mysql支持的过程式数据库对象。可以提高数据库的处理速度,提高数据库编程的灵活性。
 一、存储过程1、概述一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程有参数)来调用执行它。  
 封装性。被创建后,可以被多次调用,即使对存储过程进行修改,不会直接影响到调用它的应用程序;增加sql语句的功能与灵活性。可以用流控制语句编写,完成复杂的判断和较复杂的运算;
 减少网络流量。在服务器端运行,执行速度快;
 高性能。执行过一次后,产生的二进制代码就可以驻留在缓冲区;
 提高数据库安全性和数据完整性。存储过程可以完成所有数据库操作,并通过编程方式控制数据库信息访问的权限
 2、存储过程可以使用create procedure语句创建存储过程语法格式:
 create procedure <过程名> ([过程参数[,...]]) <过程体>
[过程参数[,...]]格式
[in|out|input] <参数名> <类型>
 参数说明:  
 <过程名> 存储过程的名称[过程参数[,…]]存储过程的参数列表
 [过程体]存储过程的主体部分,以Begin开始,End结束
 在mysql中,服务器处理sql默认是以分号作为语句结束标志,为解决这个问题,需要使用delimiter命令将结束命令修改城其他字符。语法格式:delimiter ??
 实例:在数据库mytest中,创建一个存储过程,存储的功能是依据学生的id,修改studentes的姓名。
 use mytest;
delimiter ??
create procedure update_name(in cid int,in cname char(50))
Begin
 update students set student_name=cname where student_id=cid;
End ??
  
 在创建存储函数时,用户必须具有create routine权限;使用如下命令,查询有哪些存储过程:
 
 show procedure status;查询某个具体存储过程:
 
 show create procedure <存储过程名> 3、存储过程体可以使用各种sql语句与过程式语句的结合。对数据库应用中的复杂业务逻辑和处理规则进行封装。 3.1 局部变量在存储过程体中可以声明局部变量,用来存放产生的临时结果。语法格式:
 declare <变量名>[,...]<类型> [default<默认值>]
 实例:声明一个字符型局部变量xname,默认值为李明
 declare xname varchar(5) default '李明';
 使用说明: 局部变量只能在存储过程体begin...end 语句中声明
局部变量在存储过程体开头处声明
 3.2 set语句变量声明后,可以使用set语句为局部变量赋值 举例:为已声明的变量xname赋值为"王杰"; set xname='王杰';
 3.3 select…into…语句将选定列的值直接存储到局部变量中,存储过程体中的select…into只能返回一行数据。 语法格式: select <列名>[,...] into <变量名>[,...] <其他>
 实例:给局部变量x,y分别赋数据库test中表t1的id,data值
 select id,data into x,y from test.t1 limit 1;
 3.4流程控制语句在存储过程体中使用以下五种控制语句流程的过程式sql语句(1)条件判断句
 if <判断语句> then <语句>
[else <判断条件> then <语句>]
[else <语句>]
end if
 (2)条件判断句case case <参数>
when <参数> then <语句>
[when <参数> then <语句>]
[else 语句]
end case
 或 case
when <判断条件> then 语句
[when <判断条件> then <语句> eles <语句>]
end case
 (3)循环语句loop <标签> loop
<语句>
end loop [标签]
  
 <标签>是loop语句中的标注,必须使用相同的名字,并成对出现在循环体<语句>中,语句会一直重复直到出现leave语句退出
 (4)循环语句while <标签> while <判断条件> do
<语句>
end while <标签>
 (5)循环语句repeat <标签> repeat
<语句>
until <判断条件>
end repeat <标签>
 3.5 游标是一个被select语句检索出来的结果集,在存储了游标后,应用程序或用户就可以根据需要滚动或浏览其中的数据  
 select…into语句成功执行后,会返回带有值得一行数据,这行数据可以被读取到存储过程中进行处理。但是在是使用select语句进行数据检索时,如果成功被执行,会返回一组称为结果集的数据行,如果结果集拥有多行数据,需要游标对其处理 (1)声明 declare <游标名> cursor for <select语句>
 指定一个select语句,会返回一行或多行数据这里的select语句不能有into语句
 (2)打开游标将游标连接到由select语句返回的结果集中。
 open <游标名>
 (3)读取数据使用fetch…into语句从游标中读取数据。fetch语句是将游标指向的一行数据赋给一些变量,这些变量的数目必须等于声明游标时select子句中选择列的数目。游标相当于一个指针,指向当前的一行数据。
 fetch <游标名> into <变量名1>[变量名2]...
 (4)关闭游标使用close语句关闭游标
 close <游标名>
 4、调用存储过程使用call语句在程序、触发器或者其他存储过程中调用它 call <过程名>[(参数,...)]
 5、删除存储过程在被创建后,保存在数据库服务器中 drop procedure <过程名>
 二、存储函数由sql语句和过程式语句组成的代码片段,并且可以被应用程序和其他sql语句调用。  
 存储函数不能有输出参数,它本身就是输出参数必须包含一条return语句
 直接对存储函数进行调用不需要使用calll语句
 1、创建存储函数语法格式: create function <函数名>(<参数1><类型1>[,...])
return <类型>
<函数主体>
 实例:根据给定的student_id查找学生并返回该学生的姓名,如果没有则返回“没有该学生” use test;
delimiter ??
CREATE FUNCTION fn_search ( cid INT ) RETURNS CHAR ( 50 ) DETERMINISTIC BEGIN
	DECLARE NAME CHAR ( 50 );
	SELECT student_name INTO NAME FROM students WHERE student_id = cid;
	IF NAME IS NULL THEN 
	RETURN (
			SELECT('没有该学生' ));
		else RETURN ( NAME );		
	END IF;
END ??
 2、调用存储函数如同调用系统内置函数一样,使用关键字select。 语法格式: select <存储函数名>([<参数>[....]])
 实例:调用fn_search,查询student_id为1的学生,并返回学生姓名 select fn_search(1);
 3、删除存储函数语法格式: drop function [if exists] <存储函数名>
  
 在删除之前,需要确认该存储函数没有任何依赖关系 |