看完了两天了,却因为各种事情到现在才有时间来写博客,方便日后查看了……
PL/SQL的子程序有两种形式,即过程和函数,过程与函数的区别在于函数有返回值,可以向调用者返回执行结果,而过程没有返回值。
一、存储过程
存储过程是一段存储在数据库中执行某功能的程序。是将一些固定的操作集中起来由Oracle数据库服务器来完成,以实现某个任务,是Oracle开发者在数据转换或查询报表时经常使用的方式。
存储过程可以把需要执行的多条sql语句封装到一个独立单元,用户只需调用这个单元就可以达到目的。
存储过程可以接收和输出参数,返回执行存储过程的状态值,还可以嵌套调用。
(一)、无参数存储过程(一般在数据转换/数据改,查,删 时使用)
1、创建无参存储过程
create or replace procedure 存储过程名称 as
begin
存储过程定义(sql语句)
end 存储过程名;
可以通过数据字典(视图)user_objects,user_source/all_source(所有存储过程),查看存储过程(脚本)从视图中查询过程时,需要把铝管名称大写。
select object_name,object_type,status from user_objects where object_name=upper('pro_print'); -----pro-print 是存储过程名
2、查看存储过程中具体的错误提示:
select * from user_errors where name=upper('pro-print');
3、调用和执行存储过程pro-print;
a、begin
pro-print;
end;
b、execute pro-print;
(二)、有参数的存储过程
1、参数的三种类型:
in:输入类型(只进不出)
out:输出类型(只出不进)
in out:输入输出类型
2、参数的定义形式:
参数名(必须) 参数传递模式(in、out、in out 默认的传递模式为in ,调用者向过程传递一个实际参数) [数据类型(必须) := 默认值]
v_name in varchar2(20) := 'cxx' ;
in传递模式下的参数,不能在存储过程内部进行修改。
在调用过程时,若过程是有参数的,则需要为过程中的传递模式参数提供实际参数(有默认值的可以不提供),它们在顺序上也要与参数对应。
create or replace procedure pro_credit(inc_credit in number,cus_id in integer:=0)
as
begin]
if cus_id =0 then
update customernew set credit_limi = credit_limit+inc_credit;
else
update customernew set credit_limit = credit_limit + inc_credit where customer_id=cus_id;
end if;
end pro_credit;
执行:
exec pro_credit(1000);
exec pro_credit(1000,101);
3、重新编译存储过程 : alter procedure 存储过程名 compile;
4、删除存储过程 : drop procedure 存储过程名;
二、函数
在oracle数据库中,用户自定义函数与存储过程相似,只能返回单一值或表,自定义/存储函数,创建后便存在数据库中,用户可以直接调用。
函数般用于计算和返回一个值,可以将经常需要进行的计算写成函数,函数主要由以下3部分组成:
输入部分:函数允许有输入参数,有入参时,调用函数就要这给这些参数赋值。
输出部分:函数需要有输出数据,也就是返回值。
函数体:函数中可以进行算术表达式运算,也允许调用SQL内置函数或其他自定义函数。
1、创建函数
create or replace function 函数名 return 返回值类型 as
begin
函数定义(在sql语句后,加上一条return 语句)
end 函数名;
create or replace function getCusCount return number as
begin
declare cus_count number;
begin
select count(1) into cus_count from customernew;
return cus_count;
end;
end getCusCount;
2、在数据字典中查看自定义函数的信息与之相关的视图有:user_objects,user_procedures,(查看关于函数的信息)user_source(查看其源脚本),
select object_name,object_type,status from user_objects where object_name=uppper('getCusCount');
3、调用自定义函数
begin
dbms_output.put_line('表customernew中总计为:'||getCusCount());
end;
4、带参的函数
create or replace function table_con(table_name varchar2) return number as
begin
declare
t_count number;
query_sql varchar2(200);
begin
query_sql='select count(1) from '|| table_name;
execute immediate query_sql into t_count;
return t_count;
end;
end table_con;
5、调用带参函数:
declare table_name varchar2(50);
begin
table_name='customernew';
dbms_output.put_line('表'||table_name||'总记录数为:'||table_com(table_name);
ends;
6、应用动态弱类型游标,将查出的单列多行数据转为一行数据:
create or replace function rowname(sqlStr varchar2) return varchar2 as
begin
declare
type ca_type is ref cursor;
ca_cursor ca_type;
ca_row varchar2(20);
ca_result varchar2(500);
begin
open ca_cursor for sqlStr;
fetch ca_cursor into ca_row;
while ca_cursor%found loop
ca_result:=ca_result||ca_row||',';
fetch ca_cursor into ca_row;
end loop;
return rtrim(ca_result,',');
end;
end rowname;
7、重新编译函数:alter function 函数名 compile;
8、删除函数:drop function 函数名;
三、程序包
程序包是一种oracle数据库对象,它是一组逻辑上相关的数据类型,变量,过程,函数和游标等的集合,程序包被创建后,存储在数据库中。
程序包有两种形式:a,用户根据需要创建的程序包,b,系统预定义的程序包
一个程序包由有两部分组成:程序包说明和包体。
包说明相当于一个包的头部,用来定义类型、变量、异常、声明游标,声明过程,声明函数,它的作用相当于程序包的接口。
包体中可以利用头部的类型定义变量,定义过程、游标和函数代码。
在创建程序包时,头部和包体是分别创建的,并且头部必须在包体之前创建,若要对程序包的功能修改,修改包体代码即可。
1、创建包说明:
create or replace package 包名 as
变量名1 数据类型;
变量名2 数据类型;
.
.
.
function 函数名1(参数列表) return 数据类型1;
function 函数名2(参数列表) return 数据类型2;
.
.
procedure 存储过程名1(参数列表);
end 包名;
eg: create or replace package pkg_cus as
function getCusCount return number;
procedure pro_print;
procedure pro_creidt(inc_credit in number,cus_id in integer:=0);
end pdk_cus;
2、在数据字典中查看包说明的信息
select object_name,object_type,status from user_objects where lower(OBJECT_NAME)='pck_cus';
select * from user_source where lower(name)='pck_cus';
3、程序包主体:
create or replace package body 包名 as
游标、函数、过程的具体定义;
end 包名;
create or replace package body pkg_cus as
function getCusCount return number as
begin
declare
cus_count number;
begin
select count(1) into cus_count from customernew;
return cus_count;
end;
end getCusCount;
procedure pro_print as
begin
dbms_output.put_line('不进则退‘)
end pro_print;
procedure pro_credit(inc_credit in number,cus_id in integer:=0) as
begin
if cus_id=0 then
update custormernew set credit_limit=credit_limit+inc_credit;
else
update custormernew set credit_limit=credit_limit+inc_credit where customer_id=cus_id;
end if;
end pro_credit;
end pkg_cus;
4、调用程序包中的函数/存储过程
execute pkg_cus.pro_print;
5、删除程序包
drop package pkg_cus;