table()函數的使用,提供查詢效率

一、序言
前段時間一直在弄報表,快被這些報表整吐了,然后接觸到了Oracle的table()函數。所以今天把table()函數的具體用法整理下,防止下次遇到忘記了。。
利用table()函數,可接收輸入參數,然后將pl/sql 返回的結果集代替table。由于表函數可將數據轉換分階段處理,并省去中間結果的存儲和緩沖表,所以它的速度相對物理表要快很多,當然比直接查視圖更是快不少。
二、table()函數使用步驟
定義對象類型
對象類型定義:封裝了數據結構和用于操縱這些數據結構的過程和函數。由對象類型頭、對象類型體組成
對象類型頭:用于定義對象的公用屬性和方法;
①屬性:最少要包含一個屬性,最多包含1000個屬性。定義時必須提供屬性名和數據類型,但不能指定默認值和not null。并且不能包括long、long raw、rowid、urowid和PL/SQL特有類型(boolean%type%rowtype\ref curdor等);
② 可以包含也可以不包含方法,可以定義構造方法、member方法、static方法、map方法和order方法。
③ 語法
create?or?replace?type?type_name?as?object?(
????????v_name1?datatype?[?,v_name2?datatype,...?],
????????[?member?|?static?method1?spec,?member?|?static?method2?spec?,?...?]
);
--?type_name是對象類型的名稱;
--?v_name是屬性名稱;
--?datatype是屬性數據類型;
--?method是方法的名稱;
對象類型體:用于實現對象類型頭所定義的公用方法。
① 方法類型
方法作用說明構造方法用于初始化對象并返回對象實例與對象類型同名的函數,默認的構造方法參數是對象類型的所有屬性。(9i前只能使用系統(tǒng)默認的構造方法、9i后可自定義構造函數,自定義必須使用constructor function關鍵字)member方法用于訪問對象實例的數據當使用member方法時,可以使用內置參數self訪問當前對象實例。當定義member方法時,無論是否定義self參數,它都會被作為第一個參數傳遞給member方法。但如果要定義參數self,那么其類型必須要使用當前對象類型。member方法只能由對象實例調用,而不能由對象類型調用。static方法用于訪問對象類型可以在對象類型上執(zhí)行全局操作,而不需要訪問特定對象實例的數據,因此static方法引用self參數。static方法只能由對象類型調用,不能由對象實例調用(和member相反)map方法可以在對多個對象實例之間排序;將對象實例映射成標量數值來比較可以定義map方法,但只能有一個,與order互斥order方法只能比較2個實例的大小定義對象類型時最多只能定義一個order方法,而且map和order方法不能同時定義
② 語法
create?or?replace?type?body?type_name?as
????member?|?static?method1?body;
????member?|?static?method1?body;...
--?type_name是對象類型的名稱;
--?method是方法的名稱;
--?member?|?static?見上表格
基于對象類型的表類型
語法
create?or?replace?type?table_name?as?table?of?type_name;
--table_name?表類型名稱
--type_name?對象類型名稱
定義表函數
語法
create?or?replace?function?function_name?([p1,p2...pn])?return?table_name
as
v_test?table_name?:=?table_name();
begin
...
end?loop;
return?v_test;
end?function_name;
--?function_name?函數名稱
--?p1,p2...pn?函數入參
--?table_name?表函數名稱
調用表函數
語法:
select?*?from?table(function_name(20));
或者
select?*?from?the(select?function_name(20)?from?dual);
--function_name?定義好的表函數名稱
三、table() 具體使用實例
公共部分對象類型和表類型創(chuàng)建
①對象類型創(chuàng)建
create?or?replace?type?t_test?as?object(
id?integer,
rq?date,
mc?varchar2(60)
);
② 表類型創(chuàng)建
create?or?replace?type?t_test_table?as?table?of?t_test;
3.1 table()結合數組 使用
①創(chuàng)建表函數
create?or?replace?function?f_test_array(n?in?number?default?null)?return?t_test_table
as
v_test?t_test_table?:=?t_test_table();
begin
for?i?in?1?..?nvl(n,100)?loop
v_test.extend();
v_test(v_test.count)?:=?t_test(i,sysdate,'mc'||i);
end?loop;
return?v_test;
end?f_test_array;
② 調用
select?*?from?table(f_test_array(10));
或
select?*?from?the(select?f_test_array(10)?from?dual);
3.2 table()結合PIPELINED函數(這次報表使用的方式)
① 創(chuàng)建表函數
create?or?replace?function?f_test_pipe(n?in?number?default?null)?return?t_test_table?PIPELINED
as
v_test?t_test_table?:=?t_test_table();
begin
for?i?in?1?..?nvl(n,100)?loop
pipe?row(t_test(i,sysdate,'mc'||i));
end?loop;
return;
end?f_test_pipe;
② 調用
select?*?from?table(f_test_pipe(10));
或
select?*?from?the(select?f_test_pipe(10)?from?dual);
3.3 table()結合系統(tǒng)包使用
①創(chuàng)建測試
create?table?test?(id?varchar2(20),mc?varchar2(20));
②表中插入數據
insert?into?test?values('1','mc1');
commit;
③ 查看表執(zhí)行計劃
explain?plan?for?select?*?from?test;
④調用
select?*?from?table(dbms_xplan.display);
大概就這么幾個,如果后面有新的用法再補充。。