Oracle Pipelined Table Functions简介
转自: 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简介的更多相关文章
- Oracle Golden Gate原理简介
		Oracle Golden Gate原理简介 http://www.askoracle.org/oracle/HighAvailability/20140109953.html#6545406-tsi ... 
- KingbaseES 如何实现Oracle pipelined 功能
		管道函数即是可以返回行集合(可以使嵌套表nested table 或数组 varray)的函数,我们可以像查询物理表一样查询它或者将其赋值给集合变量.KingbaseES 数据库可以用 setof 实 ... 
- Oracle中PL/SQL简介、基本语法以及数据类型
		Oracle中PL/SQL简介.基本语法以及数据类型 一.PL/SQL简介. Oracle PL/SQL语言(Procedural Language/SQL)是结合了结构化查询和Oracle自身过程控 ... 
- 对于Oracle analyze table的使用总结 . 对于Oracle analyze table的使用总结 .
		对于Oracle analyze table的使用总结 . 对于Oracle analyze table的使用总结 . analyze table 一般可以指定分析: 表,所有字段,所有索引字段,所有 ... 
- oracle partition table 分区表详解
		Oracle partition table 分区表详解 分区表就是通过使用分区技术,将一张大表,拆分成多个表分区(独立的segment),从而提升数据访问的性能,以及日常的可维护性.分区表中,每个分 ... 
- [转帖学习]Oracle的 SYS_CONTEXT 函数简介
		Oracle的 SYS_CONTEXT 函数简介 https://blog.csdn.net/IndexMan/article/details/48606369 1.什么是SYS_CONTEXT? S ... 
- oracle alter table
		oracle alter table ALTER TABLE (表名) ADD (列名 数据类型); ALTER TABLE (表名) MODIFY (列名 数据类型); ALTER TABLE (表 ... 
- 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 ... 
- java:Oracle(table的增删改查,data的增删改查)
		1.oracle命名规范:和Java的命名规范很像 1.严格区分大小写 2.所有的sql语句都要以';'结尾 3.所有的sql 都要使用空格区分:sqlplus空格/空格as空格sysdba回车 4. ... 
随机推荐
- xgboost 完全调参指南
			http://www.2cto.com/kf/201607/528771.html xgboost: https://www.analyticsvidhya.com/blog/2016/03/comp ... 
- Entity Framework 6.0 Tutorials(1):Introduction
			以下系统文章为EF6.0知识的介绍,本章是第一篇 原文地址:http://www.entityframeworktutorial.net/entityframework6/introduction.a ... 
- hdu 4278 Faulty Odometer(进制转换)
			十进制转八进制的变形: #include<stdio.h> int main() { int n; while(scanf("%d",&n)!=EOF& ... 
- Java实现四则运算 谢雅淇 袁杏仪
			GitHub链接:https://github.com/3216004716/four-operations.git 项目相关要求 使用 -n 参数控制生成题目的个数,例如 Myapp.exe -n ... 
- Robot Framework 使用总结
			最近项目上使用了RF快速实现了一些验收测试的自动化case,感觉不错,很好用,下面就记录一下使用RF实现自动化的过程. 什么是RF? RF是一种测试框架,帮助测试人员在其框架下快速实现验收测试的自动化 ... 
- 转:[python] pip 升级所有的包
			pip 当前内建命令并不支持升级所有已安装的Python模块. 列出当前安装的包: pip list 列出可升级的包: pip list --outdate 升级一个包: pip install -- ... 
- 关于CS0016: Could not write to output file ‘c:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Temporary AS
			1.添加用户"Network Service” 和 “IIS_IUSERS” 读下面目录的读写权限 a) C:\Windows\Temp b) C:\Windows\Microsoft.NE ... 
- docker系列 参考文章
			Docker 系列一(概念原理和安装) Docker 系列二(操作镜像) Docker 系列三(容器管理) 持续更新... ubuntu 安装docker 参考文章 :(https://blog.cs ... 
- 20165219 2017-2018-2 《Java程序设计》第9周学习总结
			20165219 2017-2018-2 <Java程序设计>第9周学习总结 课本知识总结 URL类 URL类是java.net包中的一个重要的类,使用URL创建对象的应用程序称为客户端程 ... 
- nginx负载均衡tomcat和配置ssl
			目录 tomcat 组件功能 engine host context connector service server valve logger realm UserDatabaseRealm 工作流 ... 
