存储过程(Stored Procedure )是一组为了完成特定功能的SQL 语句集,经编译后存储在数据库中。用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象,任何一个设计良好的数据库应用程序都应该用到存储过程。存储过程是由流控制和SQL 语句书写的过程,这个过程经编译和优化后存储在数据库服务器中,应用程序使用时只要调用即可。在Oracle 中,若干个有联系的过程可以组合在一起构成程序包。
优点:
缺点:
(在以下代码中,所有被 “[ ]” 包裹起来的均为选填项。)
create [or replace] procedure
存储过程名 [(参数1 类型,参数2 out 类型……)]
as/is
变量名 类型;
begin
程序代码体
end;
注:
运用以上语法我们可以创建一个存储过程。对于oracle的存储过程而言,只能创建(create)、删除(drop)、替换(replace)它。
as/is这两种不同的用法,严格来说在存储过程中二者没有什么显著的差别,它们是同义词,但使用as的情况居多。值得注意的是,在创建视图的时候我们只能用as,而在声明游标的时候只能用is。
begin与end表示PL-SQL语句块的开始和结束,所有需要执行的语句都写在此处。
create or replace procedure p1
-- or replace代表创建该存储过程时,若存储名存在,则替换原存储过程,重新创建
-- 无参数列表时,不需要写()
as
begin
dbms_output.put_line('hello');
end;
create or replace procedure
p2 (name in varchar2, age int, msg out varchar2)
--参数列表中,声明变量类型时切记不能写大小,只写类型名即可,例如参数列表中的name变量的声明
--参数列表中,输入参数用in表示,输出参数用out表示,不写时默认为输入参数。
--输入参数不能携带值出去,输出参数不能携带值进来,当既想携带值进来,又想携带值出去,可以用in out
as
begin
msg:='姓名'||name||',年龄'||age;
--赋值时除了可以使用:=,还可以用into来实现
--上面子句等价于select '姓名'||name||',年龄'||age into msg from dual;
end;
1、 begin
存储过程名();
end;
2、execute 存储过程名称();
3、call 存储过程名称();
create [ or replace ] procedure p3
as
[ var_1 var_type (var_size); ]
begin
-- PL-SQL blocks
end;
以上是声明变量的语法,其中,var_1表示变量名,var_type表示变量的类型,var_size表示取值范围(变量大小),当我们要声明一个变量的时候,这三个元素缺一不可。
变量类型则有多种不同的分类:标量类型、复合变量类型、参照类型、大型数据对象。
标量类型既包括了系统中的标准数据类型,诸如varchar、number等;亦包括了一些比较少用的类型,比如BINARY_INTEGER、boolean等。这些类型使用广泛、声明简单,是变量类型中的基础。
create or replace procedure p4
as
v_id number(4);
v_name varchar(20);
v_sex varchar(10);
begin
select id, name, sex
into v_id, v_name, v_sex
from aaa
where id = '6';
end p4;
还有一种变量类型叫做 “%TYPE” ,你可以把它看做是一种动态数据类型,它由一个已经定义了的变量调用,并返回该变量的类型。比如说:
v_msg varchar(20);
v_msg_back v_msg%TYPE;
-- 在这里,v_msg 和 v_msg_back 的类型都是 varchar(20)
与之相似的还有 “%ROWTYPE” ,顾名思义,它能保存一个表格中所有列的类型,你可以直接将它看做是一条行记录。
v_msg_back aaa%ROWTYPE;
-- 在这里,aaa可以是表或视图
create or replace procedure p4
as
v_msg_back aaa%ROWTYPE;
begin
select *
into v_msg_back
from aaa
where id = '6';
end p4;
复合记录类型:声明一种record类型的变量,该变量内含有多个标量类型的变量,随后声明该record类型的“对象”。
type record_type_name is record (
var_name var_type(var_size)
[, var_name var_type(var_size)]
);
var_record_type record_type_name;
该语法声明了一个叫做 “record_type_name” 的记录类型,里面含有复数个变量(单个变量没有声明成记录的必要)。随后,我们声明了一个名为 “var_record_type” 的 “record_type_name” 类型的变量。
复合表类型(关联数组):索引表(关联数组)是一种更为复杂的记录类型,尽管在声明的时候我们会用到 “is table of” ,
但本质上来讲它更接近数组,索引表通过指定类型的索引确定其元素所在位置。下面是声明索引表的语法:
type table_type_name is table of type_name index by index_type;
var_table table_type_name;
在这里,table_type_name 即是我们所声明的索引表的名字;type_name 是索引号的类型,它可以是标量类型,也可以是我们自己声明的记录类型