转自: http://www.linuxidc.com/Linux/2011-05/35797.htm

//概况  

//基本上,当你希望一个PLSQL(或者java或者c)程序作为数据源,而不是表,  

//你可能会用到管道函数(pipelined function).  

//pipelined function操作起来就像一张表  

//一个pl/sql函数可能会用于数据仓库的数据库里面,转换大量的数据。  

//这可能包括格式化一系列转换数据,它们是不同的函数执行后得到的结果。  

//在Oracle database 9i之前,大量的数据转换,既需要显著的内存开销,  


//又需要在转换的每个阶段将数据存储在中间表里面。在这两种情况下,  

//加载进程都会致使性能的下降。

//使用PL/SQL表函数,可以在数据转换的时候有效的减少开销。PL/SQL表函数  


//可以接收和返回多行,交付这些数据,当他们准备好的时候,而不是一次性的处理;  

//而且PL/SQL表函数还可以并行执行操作。  

--  

//实例1:生成随机数  

//你怎么样用一条sql语句生成在1-49之间的互不相同的随机数呢?  

//我们可能从一组已经生成的数中去查询(注意下面的最内层的查询);  

//任何拥有大于等于49行记录的表都可以做到。若不使用管道函数的话,下面是最好的解决办法:  

select r  

  from (select r  

           from (select rownum r  

                   from all_objects  

                  where rownum < 50)  

          order by dbms_random.value)  

where rownum <= 6;  

/  

         R  

----------  

        36  

        40  

        30  

        26  

         3  

        42  

//我们将最内部的查询叫做内嵌视图,它产生了1..49这些数,我们通过DBMS_RANDOM.VALUE,  

//来对这49个数进行排序。我们将结果集打包在另一个内嵌视图中只返回6行,  

//如果我们反复的执行这个查询,我们每次得到的6个数都会不同。  

--  

//这种问题经常出现,或许不是关于怎么生成6个随机数,而是怎么样得到N行?  

//例如,我们想要得到包括在2011-05-01和2011-05-15之间的所有日期;怎样不用"真实"表,  

//解决这个问题呢?Oracle9i/10g内置的PIPELINED function将会告诉你答案。  

//我们编写一个PL/SQL函数,它工作起来就像一个表。我们需要借助于sql的集合类型,  

//它描述了PIPELINED function返回的值。这个例子中,我们选择了一个数的表,我们创建的虚拟表,  

//它将会返回下面的数:1,2,3,...N :  

create type array  

    as table of number;  

/  

//下一步,我们创建这个PIPELINED function,它将会接收一个输入来限制返回的行数。如果没有输入,  

//这个函数将会一直长时间的生成很多行(所以,在这个查询中,一定要细心,确保使用rownum,  

//或其他的数来限制产生的行数)。  

//位于第4行的PIPELINED关键字,将会使这个函数工作起来想像一个表:  

create function  

  gen_numbers(n in number default null)  

  return array  

  PIPELINED  

  as 

  begin  

     for i in 1 .. nvl(n,999999999)  

     loop  

         pipe row(i);  

     end loop;  

     return;  

  end;  

/  

//假设我们需要3行数据,我们现在可以使用下面的其中一个查询实现:  

select * from TABLE(gen_numbers(3));  

COLUMN_VALUE  

------------  

           1  

           2  

           3  

or  

select * from TABLE(gen_numbers)  

where rownum <= 3;  

COLUMN_VALUE  

------------  

           1  

           2  

           3  

//现在我们准备去回答最开始的问题了,语句如下:  

select *  

  from (  

  select *  

    from (select * from table(gen_numbers(49)))  

  order by dbms_random.random  

  )  

where rownum <= 6  

/  

COLUMN_VALUE  

------------  

          27  

          24  

          46  

          17  

          44  

          45  

//我们可以使用这个虚拟表的功能去做很多事情,例如产生一个范围内的所有日期:  

select to_date('2011-05-01','yyyy-mm-dd')+  

        column_value-1  

  from TABLE(gen_numbers(15))  

/  

TO_DATE('2' 

-----------  

2011-05-01   

2011-05-02   

2011-05-03   

2011-05-04   

2011-05-05   

2011-05-06   

2011-05-07   

2011-05-08   

2011-05-09   

2011-05-10   

2011-05-11   

2011-05-12   

2011-05-13   

2011-05-14   

2011-05-15   

//注意上面我们使用了column_value,这是一个PIPELINED function返回的默认列的名字。  

//典型的Pipelined例子  

//当使用PL/SQL表函数时,下面是典型的步骤  

//  ·生产函数必须在其定义中使用PIPELINED关键字  

//  ·生产函数必须使用一个out参数,这个参数是一个集合,对应到返回的结果集  

//  ·一旦有结果产生,通过使用PIPE ROW关键字将其输送给消费函数  

//  ·生产函数必须以RETURN语句结束,但是不需要制定返回值  

//  ·消费函数必须使用TABLE关键字,将从PIPELINE function返回的行集当成一个常规表  

//第一步.定义一个返回的行集的格式。  

//       在这个实例中,我们返回这三个类型的值:int,date,varchar2(25)  

CREATE OR REPLACE TYPE myObjectFormat   

AS OBJECT  

(  

  A   INT,  

  B   DATE,  

  C   VARCHAR2(25)  

)  

/  

//下一步,为第一步定义的类型定义一个集合类型  

CREATE OR REPLACE TYPE myTableType  

   AS TABLE OF myObjectFormat  

/  

//最后,生产函数被打包到一个包里面,它是一个pipelined function就像被pipelined关键字所标记一样。  

CREATE OR REPLACE PACKAGE myDemoPack  

AS  

      FUNCTION prodFunc RETURN myTableType PIPELINED;  

END;  

/  

CREATE OR REPLACE PACKAGE BODY myDemoPack AS  

FUNCTION prodFunc RETURN myTableType PIPELINED IS  

BEGIN  

  FOR i in 1 .. 5  

    LOOP  

      PIPE ROW (myObjectFormat(i,SYSDATE+i,'Row '||i));  

    END LOOP;  

    RETURN;  

  END;  

END;  

/  

//测试结果:  

alter session set nls_date_format='yyyy-mm-dd';  

SELECT * FROM TABLE(myDemoPack.prodFunc());  

                A B           C  

----------------- ----------- ------------  

                1 2011-05-05  Row 1  

                2 2011-05-06  Row 2  

                3 2011-05-07  Row 3  

                4 2011-05-08  Row 4  

                5 2011-05-09  Row 5  

//结论:  

//在一个select语句里面,我们需要一个数据源,而不是一张表的话,Pipelined functions非常有用。

Oracle Pipelined Table Functions简介的更多相关文章

  1. Oracle Golden Gate原理简介

    Oracle Golden Gate原理简介 http://www.askoracle.org/oracle/HighAvailability/20140109953.html#6545406-tsi ...

  2. KingbaseES 如何实现Oracle pipelined 功能

    管道函数即是可以返回行集合(可以使嵌套表nested table 或数组 varray)的函数,我们可以像查询物理表一样查询它或者将其赋值给集合变量.KingbaseES 数据库可以用 setof 实 ...

  3. Oracle中PL/SQL简介、基本语法以及数据类型

    Oracle中PL/SQL简介.基本语法以及数据类型 一.PL/SQL简介. Oracle PL/SQL语言(Procedural Language/SQL)是结合了结构化查询和Oracle自身过程控 ...

  4. 对于Oracle analyze table的使用总结 . 对于Oracle analyze table的使用总结 .

    对于Oracle analyze table的使用总结 . 对于Oracle analyze table的使用总结 . analyze table 一般可以指定分析: 表,所有字段,所有索引字段,所有 ...

  5. oracle partition table 分区表详解

    Oracle partition table 分区表详解 分区表就是通过使用分区技术,将一张大表,拆分成多个表分区(独立的segment),从而提升数据访问的性能,以及日常的可维护性.分区表中,每个分 ...

  6. [转帖学习]Oracle的 SYS_CONTEXT 函数简介

    Oracle的 SYS_CONTEXT 函数简介 https://blog.csdn.net/IndexMan/article/details/48606369 1.什么是SYS_CONTEXT? S ...

  7. oracle alter table

    oracle alter table ALTER TABLE (表名) ADD (列名 数据类型); ALTER TABLE (表名) MODIFY (列名 数据类型); ALTER TABLE (表 ...

  8. Oracle alter table modify column Syntax example

    http://www.dba-oracle.com/t_alter_table_modify_column_syntax_example.htm For complete tips on Oracle ...

  9. java:Oracle(table的增删改查,data的增删改查)

    1.oracle命名规范:和Java的命名规范很像 1.严格区分大小写 2.所有的sql语句都要以';'结尾 3.所有的sql 都要使用空格区分:sqlplus空格/空格as空格sysdba回车 4. ...

随机推荐

  1. Part10-C语言环境初始化-一跃进入C大门lesson3

    1.跳转到c代码 因为内存中的代码来自于垫脚石SRAM,他们是相同的. 采用绝对跳转方式来完成. 因为我们是从汇编代码跳转到c语言的程序,所以我们要提前准备一个main.c文件. 修改makefile ...

  2. Linux下的多线程下载工具mwget

    之前在做项目的时候,遇到一个难题,需要一个多线程下载器,于是阴差阳错的看到了这款工具--mwget,之所以是阴差阳错,是因为mwget的多线程下载功能,并不是我们想要的多线程. wget大家都知道吧, ...

  3. DB2 函数快速构造测试数据

    函数快速构造测试数据 [案例]使用DB2内置函数快速构造测试数据 无论您是在用原型证明某一概念,还是开发一个全新的应用程序,或者只是学习 SQL,您都需要在您的应用程序上运行测试数据.为了有效地测试应 ...

  4. 解决golang windows调试问题:Could not determine version number: could not find symbol value for runtime.buildVersion

    版本信息: go:1.8.3 windows: win7/64 idea-go-plugin:171.4694.61 在windows下,使用dlv进行调试的时候,如果golang程序引入了c模块,比 ...

  5. 「BZOJ 2152」聪聪可可

    题目链接 戳这 \(Solution\) 这道题看起来就像点分治对吧.没错就是点分治. 什么是点分治 如果你不会点分治,可以去看看这儿 现在看到这里,首先确保你已经会了点分治,如果不会你还往下看,听不 ...

  6. Delphi XE8中Android开发有用的资源!

    一,FireMonkey Component Library在XE8帮助(topics.chm)中的位置:FireMonkey Component Library,展示了FireMonkey控件在VC ...

  7. 使用itchat监控微信消息,从此不再为撤回烦恼

    强大的Itchat itchat是一个开源的微信个人号接口,使用python封装接入微信网页版接口,通过调用itchat来登录微信网页版收发消息. 项目简介 - itchat 掌握itchat之后,只 ...

  8. kali linux之漏洞扫描

    发现弱点:基于端口服务扫描结果版本信息,搜索已公开的漏洞数据库 使用弱点扫描器实现漏洞管理 弱点扫描类型(扫描结果不能确定是不是准确的,应该综合对待威胁) 主动扫描:有身份验证,无身份验证 被动扫描: ...

  9. 深度学习之 TensorFlow(一):基础库包的安装

    1.TensorFlow 简介:TensorFlow 是谷歌公司开发的深度学习框架,也是目前深度学习的主流框架之一. 2.TensorFlow 环境的准备: 本人使用 macOS,Python 版本直 ...

  10. centos 在vm下网络不通

    VMware是一款虚拟机,支持各种热门系统,我们可以在VMware虚拟机中安装其他系统以满足个人需求,但在为VMware安装CentOS6.5后,无法连接网络,这是什么原因导致的呢?下面就给大家介绍下 ...