包可将一些有联系的对象放在其内部。任何能在块定义部分出现的对象都可以在包中出现。这些对象包括存储过程、函数、游标、自定义的类型(例如PL/SQL表和记录)和变量。我们可以在其它的PL/SQL块中引用包中的这些对象。也就是说,包为PL/SQL提供了全局变量。1、包的定义一个包由两个独立的部分组成---包头和包体。各部分被单独地存放在数据字典中。定义一个包,要分别定义包头和包体。(1)定义包头存储过程或函数必须在包头中预定义。也就是说,在包头中仅定义存储过程名或函数名以及它们的参数。存储过程或函数的执行代码将在包体中定义。这不同于无名块中定义存储过程和函数。
create or replace package authspack as
--获得auths表中作家的工资。
procedure querysalary(p_code auths.author_code%type,p_salary out auths.salary%type);
--向auths表插入记录。
procedure insertauthor( p_code auths.authr_code%type,
p_name auths.name%type,
p_sex auths.sex%type,
p_birthdate auths.birthdate%type,
p_entry_date_time auths.entry_date_time%type);
end authspack;
(2)定义包体
包体是一个数据字典对象。只有在包头成功编译后,包体才能被编译。包体只包含包头中已预定义的子程序的代码。在包头中定义(不是预定义)的对象可以直接在包体中使用,不必再在包体中定义。
下面是authspack包的包体:
create or replace package body authspack is
--获得auths表中作家的工资。
procedure querysalary(p_code auths.author_code%type,p_salary out auths.salary%type) as
begin
select salary into p_salaary from auths where author_code=p_code;
end querysalary;
--向auths表插入记录。
procedure insertauthor( p_code auths.authr_code%type,
p_name auths.name%type,
p_sex auths.sex%type,
p_birthdate auths.birthdate%type,
p_entry_date_time auths.entry_date_time%type) as
begin
insert into auths(author_code,name,sex,birthdate,entry_date_time)
values(p_code,p_name,p_sex,p_birthdate,p_entry_date_time);
end insertauthor;
end authspack;
如果包头不包含存储过程和函数,则不必定义包体。如果包头中有预定义的子程序,则在包体中必须编写其子程序代码,而且包头和包体两部分指定的子程序必须一致,这包括相同的子程序、参数名和参数类型。
(3)包的初始化
包可被初始化,只是初始化部分在包体的最后部分被定义。
create or replace package authorinfopack as
v_auths_sex varchar2(2);
procedure author_sex(p_author_code auths.author_code%type,
p_sex out varchar2);
end authorinfopack;
--定义包体
create or replace package body authorinfopack as
procedure author_sex(p_author_code auths.author_code%type,p_sex out varchar2) as
v_sex number;
begin
select sex into v_sex from auths where author_code=p_author_code;
if v_sex=0 then
p_sex:='女';
else
p_sex:='男';
end if;
end author_sex;
--初始化部分。
begin
author_sex('A00001',v_auths_sex);
end authorinfopack;
2、包的使用
(1)包中对象的引用
在包中定义的任意对象都可在包外使用,只是在引用该对象前用包名做前缀。
例如,我们可通过如下PL/SQL语句调用authspack包中的存储过程querysalary:
--设置存储缓冲区的大小。
set serveroutput on size 100000
declare
v_salary auths.salary%type;
begin
authspack.querysalary('A00010',v_salary);
--显示过程querysalary的查询结果。
dbms_output.put_line('A00010作家的工资为:');
dbms_output.put_line(v_salary);
end;
(2)重载包中的子程序
在包的内部,存储过程和函数都可被重载,这意味着有多个存储过程或函数可以使用同一个名称,但是参数不能相同。这样就允许用不同的参数调用同一个名字的过程或函数。
重载是非常有用的技术,但是,它也有一些约束,这些约束如下所示:
A.当仅仅参数名不同或者是模式(in、out、in out)不同时,不能重载子程序。例如:
procedure overload(p_par in char); procedure overload(p_par out char); 不能这样重载。
B.不能对仅有返回类型的函数进行重载。例如,下面这样是不能重载的:
function overload fun return char; function overload fun return binary_integer;
C.重载函数的参数必须是数据类型不同或其类型间不可自动转换。例如,由于char和varchar2的变量可以自动转换,因此不能重载下面的存储过程:
procedure overloadchar(p_theparameter in char); procedure overloadchar(p_theparameter in varchar2);
尽管在定义包含违反上述限制的子程序的包时不会报编译错误。但是,运行时PL/SQL引擎不能调用该子程序,会出现错误"PLS-307:too many declarations of 'subprogram' match this call."。
3、在SQL语句中使用的函数
通常在SQL语句中不能调用PL/SQL函数(无论是单独存储在数据库中的函数还是包中的函数),因为PL/SQL函数是过程性的语句。
在PL/SQL2.1以上版本中放宽了这个限制,但函数必须满足特定的约束才能在SQL语句中使用。
PL/SQL为函数指定了四种基本约束,这四种基本约束如下所示:
WNDS [Writes no database state] 在函数内不能用DML语句修改数据库中的表。
RNDS [Reads no database state ] 在函数内不能通过SELECT语句来读取数据库中的表。
WNPS [Writes no package state ] 在函数内不能修改包变量(包变量不能在赋值语句的左边或一人FETCH语句的INTO语句中)。
RNPS [Reads no package state ] 在函数内不能查询包变量(包变量不能在赋值语句的右边或不能是SQL表达式的一部分)。
当函数满足WNDS时,能够被SQL语句调用。
用户自定义函数必须符合如下约束才能被SQL语句调用,这些约束对于内嵌函数(系统提供的函数)也同样适用:
A.函数必须单独的或作为包的一部分存储在数据库中,不能作为块的一部分。
B.函数只能定义IN参数,不能定义其它两种参数。
C.形参类型必须是数据库中的数据类型,不能是PL/SQL中的数据类型(如boolean或record类型)。数据库类型包括number、char、varchar2、rowid、long、long raw和date。
D:函数返回的数据类型也必须是数据库中的数据类型。
例如,函数nameandsex将作家代码作为输入,返回作家的名字和性别:
create or replace function nameandsex(
p_authorcode auths.author_code%type)
return varchar2 AS
v_nameandsex varchar2(100);
begin
select name||' '||replace(replace(sex,0,'女'),1,'男')
into v_nameandsex from auths where author_code=p_authorcode;
return v_nameandsex;
end nameandsex;
下面用SQL语句调用它:
select seqno,nameandsex(author_code) "姓名和性别" from auths where author_code<'A00004'
当将单独存储在数据库中的函数用在SQL语句中时,PL/SQL引擎自动确定该函数有哪些约束,这些约束能否保证函数在SQL语句中的调用。
对于包函数,则先在包内部使用restrict_references编译指令来指定包函数的约束。在SQL语句中调用这个包函数时,PL/SQL根据编译指令指定的约束来判断包函数能否在SQL语句中调用。
restrict_references编译指令通过下面的语法指定函数的约束:
pragma restrict_references(function_name,WNDS[,WNPS][,RNDS][,RNPS]);
由于能在SQL语句中调用的函数都有WNDS基本约束,因此编译指令同样也要求这样。编译指令须在函数所在的包头中指定。
create or replace package authorpack as
function fun(p_authorcode auths.author_code%type) return varchar2;
--使用 约束
pragma restrict_references(fun,WNDS,WNPS,RNPS);
function authorcount return number;
pragma restrict_references(authorcount,WNDS,WNPS,RNPS);
end authorpack;
create or replace package body authorpack as
v_num number;--包变量
--函数fun的函数体满足WNPS、WNDS和RNPS约束。
function fun(p_authorcode auths.author_code%type)
return varchar2 as
v_return varchar2(16);
begin
select author_code||name into v_return from auths where author_code=p_authorcode;
return v_return;
end fun;
--函数authorcount的函数体不满足WNPS和RNPS约束。
function authorcount return number as
v_return number;
begin
if v_num is null then --包变量v_num被读,这将不满足RNPS约束。
select count(*) into v_return from auths where author_code like 'A%';
v_num:=v_return; --包变量被,这将不满足WNPS约束。
else
v_return:=v_num;
end if;
return v_return;
end authorcount;
end authorpack;
fun函数正常,但在包体中的authorcount函数代码并不符合指定的约束,包体中定义的变量v_num不仅被读也被修改,所以PL/SQL引擎编译到函数authorcount时,报"PLS-00452:Subprogram 'authorcount' violates its associated pragma"错误。
当遇到函数重载时,pragma只约束最过定义的函数。
注意,如果函数中用到了dbms_output、dbms_pipe、dbms_alter、dbms_sql、utl_file等系统包,则该函数不能用在SQL语句中。
当在过程性语句中调用一个函数时,可以使用参数缺省值。而通过SQL语句调用一个函数时,所有的参数都必须指定。另外,必须使用位置表示法,不能使用命名表示法。
4、系统提供的包dbms_output
分享到:
相关推荐
12oracle的PL/SQL编程-函数.包.触发器 PPT 12oracle的PL/SQL编程-函数.包.触发器 PPT
pl-sql-dev-8-setup PL/SQL developer 的安装文件 另外还有它的注册机 和 简体中文包 都在我的资源中 我的刚解决 所以免费贴出来和大家分享
PL/SQL中文包 本人亲测,可用。
PL/SQL 程序设计 本章主要重点: PL/SQL概述 PL/SQL块结构 PL/SQL流程 运算符和表达式 游标 异常处理 数据库存储过程和函数 包 触发器
SQL Exporter did not export very old dates in date format - SQL Exporter could export floats with comma as decimal separator <br>PL/SQL Developer主要特性: PL/SQL编辑器,功能强大——该编辑器...
《Oracle PL/SQL程序设计(第5版)》基于Oracle数据库11g,从PL/SQL编程、PL/SQL程序结构、PL/SQL程序数据、PL/SQL中的SQL、PL/SQL应用构建、高级PL/SQL主题这6个方面详细系统地讨论了PL/SQL以及如何有效地使用它。...
PL/SQL 编程基础知识详解,PL/SQL 包含过程化语句和SQL语句数据操作和查询语句被包含在PL/SQL代码的程序单元中(PL/SQL块),经过逻辑判断、循环等操作完成复杂的功能或者计算.。
pl/sql 免安装,绿色版pl/sql,亲测可用,内包含readme文档,配置清晰一目了然。提供给广大队友
第一章 PL-SQL一览 第二章 PL-SQL基础 第三章 PL-SQL数据类型 第四章 PL-SQL的控制结构 第五章 PL-SQL集合与记录...第十章 PL-SQL包 第十一章 PL-SQL对象类型 第十二章 本地动态SQL 第十三章 PL-SQL应用程序性能调优
PL/SQL 用户指南与参考 第一章 PL/SQL一览 第二章 PL/SQL基础 第三章 PL/SQL数据类型 第四章 PL/SQL的控制结构...第九章 PL/SQL包 第十章 PL/SQL对象类型 第十一章 本地动态SQL 第十二章 PL/SQL应用程序性能调优
最新的PL/SQL 汉化包,除了从未使用过的插件栏没有汉化,其余所有栏目全部汉化,设置-》快捷键设置,少量路径未汉化
pl-sql-dev-8-chinese PL/SQL Developer 8 中文包 资源里面还有安装程序 和 注册机 刚解决问题 所以贴出来和大家分享 注意:如果只需要单独的中文包 则只需要安装中文包以后 找到安装目录下的chinese.lang 文件...
SQL Exporter did not export very old dates in date format - SQL Exporter could export floats with comma as decimal separator <br>PL/SQL Developer主要特性: PL/SQL编辑器,功能强大——该编辑器...
oracle 数据连接工具,PL/SQL Developer 12资源包,包含汉化包和注册码。 详情查看:https://www.allroundautomations.com/plsqldev120.html
pl/sql数据库学习笔记,包含一些基础知识,和案例代码
PL/SQL 各种工具包,包含PDF生成PLSQL工具包 Excel文件生成、 RTF文件生成、 Zip文件压缩与解压、 JSON格式文件生成与解析、 通过PLSQL调用FTP、 发送电子邮寄工具包、 SOAP and REST web services工具包、 XML、HTTP...
PL/SQL Developer - 中文语言包 Language Packs For translated versions of PL/SQL Developer you can download and install one or more language packs below. After installation the application will be ...
SQL and Pl/SQL培训文档 第一天 第一章 PL/SQL 简介 安装scott/tigger用户模式 Example1 标准的PL/SQL块结构 PL/SQL块类型 Example2:子程序,函数,程序包 PL/SQL代码的执行 第二章 PL/SQL数据类型 预定义数据类型 ...
PL/SQL简介(第1~2章) PL/SQL中的SQL语句(第3章) 控制结构(第4~7章) 异常处理(第8~10章) 游标(第11~12章) 触发器(第13~14章) 复合数据类型(第15~16章) 动态SQL(第17章) 批量SQL(第18章) 子程序和包...
本书包含了真实世界的例子,涵盖了PL / SQL的所有高级功能。反过来,每个主要的认证主题都在一个单独的章节中介绍,使理解概念更容易。在每章的最后,你会发现很多练习题,以加强和测试你的学习。 如果您是PL / SQL...