Oracle 管道化表函式

2022-05-27 06:51:12 字數 3420 閱讀 4342

在pl/sql中,如果要返回資料的多個行,必須通過返回乙個ref cursor的游標,或者乙個資料集合(如臨時表或物理表)來完成,而ref cursor的侷限於可以從查詢中選擇的資料,而資料集合的侷限性在於必須先create table(無論是建立臨時表還是物理表)來進行具體化,具體化後,會因為頻繁刪除表導致大量的碎片。

oracle 9i開始,引入了管道化表函式,解決了這種情況。

管道化表函式是返回整個行的集合的函式,可以直接在sql中進行查詢,他就好像是真正的資料庫表一樣。他存在於記憶體中,比物理表速度要快幾十倍。

管道化表函式必須返回乙個集合,在函式中pipe row 語句被用來返回該集合的單個元素,該函式必須以乙個空的return語句結束,以表明他已經完成。一旦建立了該函式,就可以使用table()操作符從sql查詢中來呼叫它。

使用管道化表函式需要定義以下內容:

1. 定義乙個object型別的type

create type ty_obj as object ();

2. 定義乙個type繼承了這個ty_obj;

create type ta_obj as

table

of ty_obj;

3. 建立乙個管道化函式

create

orreplace

function fun_name return

ta_obj pipelined

isbegin

……

pipe

row ();

exception

end;

下面是乙個管道化表函式的例子。

create type ty_numlist as

object(

n1

number

, n2

varchar2(50));

create type ta_numlist as

table

ofty_numlist;

create

orreplace

function fn_num return

ta_numlist pipelined

isfv_numlist ty_numlist;

begin

for x in

1.. 20

loop

fv_numlist :

= ty_numlist(x, '

row'

||x);

pipe

row (fv_numlist);

endloop;

return

;end;--

接下來可以查詢結果了;

select

*from

table(fn_num);

這個管道化函式是可以帶引數的,比如:建立時,使用了id這個引數

create

function my_fun(id number) return

tt pipelined;

--那麼查詢時,可以這樣呼叫

select

*from

table(mu_fun(11));

下面是一些比較複雜的用法:把乙個查詢的結果通過管道化函式來返回。

1. 建立type

create

orreplace type ty_prov as

object

( prov_id

number(8

), prov_code

varchar2(9

), eng_code

varchar2(9

), prov_name

varchar2(12))

2. 建立type

create

orreplace type ta_prov as

table

of ty_prov

3.建立管道化函式

create

orreplace

function getprovmsg(pp_code varchar2) return

ta_prov pipelined

isfv_prov ty_prov;

begin

for x in (select prov_id, prov_code, eng_nm, prov_name from bam_t01_province_def where prov_code =

pp_code) loop

fv_prov :

=ty_prov(x.prov_id, x.prov_code, x.eng_nm, x.prov_name);

pipe

row (fv_prov);

endloop;

return;

exception

when others then

-20001,'

getprovmsg : '||

sqlerrm );

end;

4. 使用下面語句來查詢

sql>

select

*from

table(getprovmsg('

100'

)) ;

prov_id prov_code eng_code prov_name

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

10100

100 bj 北京

以上參考自:

關於效率的小知識:

對於物理表,他的資料儲存在物理磁碟上,當資料第一次被read時,會被load到db cache中,根據lru演算法來決定這些資料會否置換出記憶體。如果資料一直在記憶體中,他會被所有session共享,由於資料是機構化的,所以在記憶體中掃瞄的效率是最高的。

對於臨時表,它和它的索引都是建立在臨時表空間上的,當在乙個session中第一次插入資料時,才開始在使用者的預設臨時表空間下分配臨時資料段,不同的session擁有不同的段,以保證不同會話不會相互影響。臨時表的資料也是結構化的,第一次讀取資料後,資料也會被cache到db cache中。

table()函式是9i的新特性,實際上是將乙個儲存在記憶體中的物件結構化後,使這個物件能以表的形式來查詢。物件是以流的方式儲存的,對流的結構化轉換會導致效率下降。所以它的效率應該低於存在於記憶體中的物理表和臨時表。(但應該高於第一次裝載入記憶體的物理表和臨時表)

關於對記憶體的影響:

網上幾乎沒有資料提及這個table()特性對sga和pga造成的嚴重影響。所以我們暫且忽略吧。或者有高手幫忙補充補充~!

from:封燁

ORACLE管道化表函式

在pl sql中,如果要返回資料的多個行,必須通過返回乙個ref cursor的游標,或者乙個資料集合 如臨時表或物理表 來完成,而ref cursor的侷限於可以從查詢中選擇的資料,而資料集合的侷限性在於必須先create table 無論是建立臨時表還是物理表 來進行具體化,具體化後,會因為頻繁...

管道化表函式PIPELINED

為了讓 pl sql 函式返回資料的多個行,必須通過返回乙個 ref cursor 或乙個資料集合來完成。ref cursor 的這種情況侷限於可以從查詢中選擇的資料,而整個集合在可以返回前,必須進行具體化。oracle 9i 通過引入的管道化表函式糾正了後一種情況。表函式是返回整個行的集 通常作為...

oracle 管道流函式

管道流函式 1 先定義 物件類中 比如 create or replace type obj cjgzl is object mjvarchar2 20 民警 sspcsvarchar2 12 派出所 sqdmvarchar2 20 社群 fwslnumber 10 房屋數 czrksnumber ...