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. ...
随机推荐
- HTML中meta标签的作用与使用
META标签用来描述一个HTML网页文档的属性 META标签可分为两大部分:HTTP-EQUIV和NAME变量. HTTP实例 HTML代码实例中有一项内容是 <meta http-equiv= ...
- 黑盒测试实践--Day6 11.30
黑盒测试实践--Day6 11.30 今天完成任务情况: 应用设计的场景用例,完成测试用例的编写 完成测试用例在自动化测试工具QTP上的测试 分析测试结果得到缺陷报告 小靳 软件测试 今天主要钻研了q ...
- LightOJ 1027 A Dangerous Maze (数学期望)
题意:你面前有 n 个门,每次你可以选择任意一个进去,如果xi是正数,你将在xi后出去,如果xi是负数,那么xi后你将回来并且丢失所有记忆,问你出去的期望. 析:两种情况,第一种是直接出去,期望就是 ...
- 编写高质量代码改善C#程序的157个建议——建议33:避免在泛型类型中声明静态成员
建议33:避免在泛型类型中声明静态成员 在上一建议中,已经理解了应该将MyList<int>和MyList<string>视作两个完全不同的类型,所以,不应该将MyList&l ...
- arp欺骗进行流量截获-1
这边博文主要讲一下怎么使用arp欺骗进行流量截获,主要用于已经攻入内网以后,进行流量监听以及修改. 一.什么是arp arp协议是以太网的基础工作协议,其主要作用是是一种将IP地址转化成物理地 ...
- Codeforces Round #551 (Div. 2)B. Serval and Toy Bricks
B. Serval and Toy Bricks time limit per test 1 second memory limit per test 256 megabytes input stan ...
- 【转】如何把CD上的音乐拷贝到电脑上
参考:https://www.ixueshu.com/document/9c44893da6e90cf7318947a18e7f9386.html 参考:https://jingyan.baidu.c ...
- 【转】plsql 永久注册码适用个版本
源地址:https://blog.csdn.net/sinat_33142609/article/details/72540025 注册码:Product Code:4t46t6vydkvsxekkv ...
- apache2.4配置
首先修改httpd.conf配置文件. vim conf/httpd.conf 添加: Listen 1234 然后把 # Virtual hosts #Include conf/extra/ ...
- BUAA_OO_电梯系列
电梯作业 第一次作业和第二次作业 由于我第一次作业给傻瓜电梯写了捎带所以第一次第二次作业差不多 电梯运行一个线程Elevator,输入控制一个线程Call 一个物理电梯控制表可以完成移动和进出人功能, ...