`
kb5706
  • 浏览: 40858 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

PL/SQL-包

阅读更多
包可将一些有联系的对象放在其内部。任何能在块定义部分出现的对象都可以在包中出现。这些对象包括存储过程、函数、游标、自定义的类型(例如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 12oracle的PL/SQL编程-函数.包.触发器 PPT

    pl-sql-dev-8-setup PL/SQL developer 8 的安装文件

    pl-sql-dev-8-setup PL/SQL developer 的安装文件 另外还有它的注册机 和 简体中文包 都在我的资源中 我的刚解决 所以免费贴出来和大家分享

    PL/SQL中文包

    PL/SQL中文包 本人亲测,可用。

    PL/SQL 程序设计

    PL/SQL 程序设计 本章主要重点:  PL/SQL概述  PL/SQL块结构  PL/SQL流程  运算符和表达式  游标  异常处理  数据库存储过程和函数  包  触发器

    PL/SQL Developer 6.05注册版-1

    SQL Exporter did not export very old dates in date format - SQL Exporter could export floats with comma as decimal separator &lt;br&gt;PL/SQL Developer主要特性: PL/SQL编辑器,功能强大——该编辑器...

    Oracle PL/SQL程序设计(第5版)(下册)第二部分

    《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 编程基础知识详解,PL/SQL 包含过程化语句和SQL语句数据操作和查询语句被包含在PL/SQL代码的程序单元中(PL/SQL块),经过逻辑判断、循环等操作完成复杂的功能或者计算.。

    pl/sql 免安装,绿色版pl/sql

    pl/sql 免安装,绿色版pl/sql,亲测可用,内包含readme文档,配置清晰一目了然。提供给广大队友

    PL/SQL经典介绍

    第一章 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包 第十章 PL/SQL对象类型 第十一章 本地动态SQL 第十二章 PL/SQL应用程序性能调优

    PL/SQL 最新汉化包

    最新的PL/SQL 汉化包,除了从未使用过的插件栏没有汉化,其余所有栏目全部汉化,设置-》快捷键设置,少量路径未汉化

    pl-sql-dev-8-chinese PL/SQL Developer 8 中文包

    pl-sql-dev-8-chinese PL/SQL Developer 8 中文包 资源里面还有安装程序 和 注册机 刚解决问题 所以贴出来和大家分享 注意:如果只需要单独的中文包 则只需要安装中文包以后 找到安装目录下的chinese.lang 文件...

    PL/SQL Developer 7.1.5 注册版-3

    SQL Exporter did not export very old dates in date format - SQL Exporter could export floats with comma as decimal separator &lt;br&gt;PL/SQL Developer主要特性: PL/SQL编辑器,功能强大——该编辑器...

    PL/SQL Developer 12 安装包汉化包注册码

    oracle 数据连接工具,PL/SQL Developer 12资源包,包含汉化包和注册码。 详情查看:https://www.allroundautomations.com/plsqldev120.html

    pl/sql数据库学习笔记

    pl/sql数据库学习笔记,包含一些基础知识,和案例代码

    Oracle PL/SQL 工具包收集

    PL/SQL 各种工具包,包含PDF生成PLSQL工具包 Excel文件生成、 RTF文件生成、 Zip文件压缩与解压、 JSON格式文件生成与解析、 通过PLSQL调用FTP、 发送电子邮寄工具包、 SOAP and REST web services工具包、 XML、HTTP...

    PL/SQL Developer - 中文

    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 pl/sql存储过程

    SQL and Pl/SQL培训文档 第一天 第一章 PL/SQL 简介 安装scott/tigger用户模式 Example1 标准的PL/SQL块结构 PL/SQL块类型 Example2:子程序,函数,程序包 PL/SQL代码的执行 第二章 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章) 子程序和包...

    Oracle Advanced PL/SQL Developer Professional Guide

    本书包含了真实世界的例子,涵盖了PL / SQL的所有高级功能。反过来,每个主要的认证主题都在一个单独的章节中介绍,使理解概念更容易。在每章的最后,你会发现很多练习题,以加强和测试你的学习。 如果您是PL / SQL...

Global site tag (gtag.js) - Google Analytics