存储过程和存储函数是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] <存储函数名>
在删除之前,需要确认该存储函数没有任何依赖关系
|