您的位置:首页 > 数据库

函数和存储过程的区别

2017-09-30 13:30 232 查看
下面只是很简单的初步了解一下存储过程,能够对存储过程有一个初步的认知,举的几个也都是极其简单的例子。

简介

首先要搞明白什么是存储过程?

存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。

为什么要用存储过程呢?

存储过程真的那么重要吗,它到底有什么好处呢?

存储过程说白了就是一堆 SQL 的合并。中间加了点逻辑控制。但是存储过程处理比较复杂的业务时比较实用。

比如说,一个复杂的数据操作。如果你在前台处理的话。可能会涉及到多次数据库连接。但如果你用存储过程的话。就只有一次。从响应时间上来说有优势。也就是说存储过程可以给我们带来运行效率提高的好处。另外,程序容易出现 BUG 不稳定,而存储过程,只要数据库不出现问题,基本上是不会出现什么问题的。也就是说从安全上讲,使用了存储过程的系统更加稳定。

数据量小的,或者和钱没关系的项目不用存储过程也可以正常运作。mysql 的存储过程还有待实际测试。如果是正式项目,建议你用 sql server 或 oracle 的存储过程。数据与数据之间打交道的话,过程会比程序来的快的多。

那么什么时候才可以用存储?对于数据量不是很大以及业务处理不是很复杂的小项目就无需要了么?错!存储过程不仅仅适用于大型项目,对于中小型项目,使用存储过程也是非常有必要的。其威力和优势主要体现在:

存储过程只在创造时进行编译,以后每次执行存储过程都不需再重新编译,而一般 SQL语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。

当对数据库进行复杂操作时(如对多个表进行Update,Insert,Query,Delete时),可将此复杂操作用存储过程封装起来与数据库提供的事务处理结合一起使用。这些操作,如果用程序来完成,就变成了一条条的

SQL 语句,可能要多次连接数据库。而换成存储,只需要连接一次数据库就可以了。

存储过程可以重复使用,可减少数据库开发人员的工作量。

安全性高,可设定只有某此用户才具有对指定存储过程的使用权。

更强的适应性:由于存储过程对数据库的访问是通过存储过程来进行的,因此数据库开发人员可以在不改动存储过程接口的情况下对数据库进行任何改动,而这些改动不会对应用程序造成影响。

布式工作:应用程序和数据库的编码工作可以分别独立进行,而不会相互压制。

一般来说,存储过程的编写比基本SQL语句复杂,编写存储过程需要更高的技能,更丰富的经验。经简单测试,一个有着十万条记录的表,通过PHP调用存储过程比通过PHP执行sql语句获取所有记录的时间,平均快0.4秒左右

先写一个简单的存储过程

以下所有的存储过程的测试环境是:Oracle客户端版本[11.2.0.1],Oracle服务器版本[11.2.0.4]、PL/SQL工具

create or replace procedure testproc   --test是存储过程名
is
id number;                             --声明变量,注意一定要有';'
begin
id:= 1;                              --存储过程的主体
end testproc;                          --end 存储过程名


解释一下create or replace:如果原来没有存储过程test,则在此创建一个存储过程,否则会用现在的这个存储过程覆盖原来的存储过程

传入参数

先创建一张表,执行的SQL如下

CREATE TABLE testtable
(
id number(10),
username varchar2(10)
);


下面实现一个给表插入记录的存储过程(注意参数的关键字in)

create or replace procedure test_insert(v_id in number,v_username in varchar2)
as     --as 和 is的区别见下面的解释
begin
insert into testtable values (v_id, v_username);
end test_insert;


解释一下is和as

在存储过程(PROCEDURE)和函数(FUNCTION)中没有区别;

在视图(VIEW)中只能用AS不能用IS;

在游标(CURSOR)中只能用IS不能用AS。

比如,这样调用就可以向数据表中插入记录了:

call test_insert(1, 'a_name');


–或者

declare
i_id number;
c_name varchar2(10);
begin
i_id:= 2;
c_name := 'test_name';
test_insert(i_id, c_name);
end;


传出参数

创建一个带输出参数的存储过程(注意参数的关键字out)

create or replace procedure test_select(v_id in number,v_username out varchar2)
as
begin   select username into v_username from testtable where id = v_id; --变量赋值
exception when no_data_found then  raise_application_error(-20001,'ID不存在!');
end test_select;


注意使用select语句时候要用select into

怎么测试呢?在PLSQL中打开一个Command Window,然后按照下面的顺序输入命令执行看效果

SQL>
4000
var c_name varchar2;

SQL> call test_select(1, :c_name); SQL>

print c_name;

注意,在这里call test_select(1, :c_name);时候的输出参数需要使用冒号:,c_name会存储输出的值

带判断的存储过程

判断一个数是不是偶数,代码如下:

create or replace procedure test_iseven(n in number, isEven out varchar2)
is
begin
isEven:='false';
if n mod 2 = 0 then         --特别注意,判断是不是等于的时候使用=而不是==
begin
isEven:='true';
end;
end if;
end test_iseven;


在Command Window里面进行测试

SQL> var b varchar2;
SQL> call test_iseven(10, :b);
//结果如下
Method called
b
---------
true


SQL> call test_iseven(11, :b);
//结果如下
Method called
b
---------
false


带循环的存储过程

一个计算从1开始累加的存储过程

create or replace procedure test_loop(endnum in number, loop_result out number)
is
i number:= 1;
begin
loop_result:= 0;
while i<= endnum loop
begin
loop_result:= loop_result + i;
i:= i + 1;
end;
end loop;
end test_loop;


在Command Window测试一下

SQL> var loop_result number;
SQL> call test_loop(10, :loop_result);
//结果如下
Method called
loop_result
---------
55


SQL> print loop_result;
//结果如下
loop_result
---------
55
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据库