table functions - planboard symposium 2013
DESCRIPTION
Er is een stelling: 'If you can do it in SQL, use SQL.' Maar soms is zelfs de zeer krachtige Oracle versie van SQL niet genoeg en heb je behoefte aan méér, zoals loops, condities etc. Oracle biedt sinds Oracle 9i de mogelijkheid om PL/SQL-code te bouwen en op te nemen in de FROM clause van je query. Hoe? Door de output van een PL/SQL functie zo te formatteren dat die op een tabel lijkt, dus met records van waarden (rijen met kolommen). Hiermee heb je alle kracht van PL/SQL én SQL tot je beschikking in je SQL-statement. Deze aanpak biedt nóg een voordeel: de code in de PL/SQL-functie wordt slechts éénmaal uitgevoerd, en niet voor elke rij (functie in de WHERE-clause) of voor elke rij in het resultaat (functie in de SELECT). If you can do it in SQL, use SQLTRANSCRIPT
![Page 2: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/2.jpg)
About me…
• Patrick Barel
• Working with Oracle since 1997
• Working with PL/SQL since 1999
• Playing with APEX since 2003 (mod_plsql)
• ACE since 2011
• OCA since December 20th 2012
![Page 3: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/3.jpg)
Read me…
http://blog.bar-solutions.com
http://technology.amis.nl
http://allthingsoracle.com
![Page 4: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/4.jpg)
Download me…
Plugins for PL/SQL Developer
http://bar-solutions.com
Plugins for Apex
http://apex-plugin.com
![Page 5: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/5.jpg)
Watch me…
![Page 7: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/7.jpg)
Patrick Barel, AMIS Mai 28th 2013
Table Functions
PL/SQL in SQL
![Page 8: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/8.jpg)
![Page 9: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/9.jpg)
�Overview of Table Functions
�Table Function Concepts
�Using Table Functions
Table functions
![Page 10: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/10.jpg)
Table functions are functions that produce a collection of rows (either a nested table or a varray) that can be queried like a physical database table. You use a table function like the name of a database table, in the FROM clause of a query.
Overview of table functions
![Page 11: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/11.jpg)
�Define Record Type
�Define NestedTable type
�Define function returning Nested Table type
�Query function using the TABLE() operator
Table function concepts
![Page 12: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/12.jpg)
• Defined as an object table of a collection
– First an object type
SQL> CREATE TYPE now_t AS OBJECT
2 (now VARCHAR2(8));
3 /
Type created.
Table function concepts, result set
![Page 13: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/13.jpg)
• Defined as an object table of a collection
– Second; the collection type
SQL> CREATE TYPE now_tt AS
2 TABLE OF now_t;
3 /
Type created.
Table function concepts, result set
![Page 14: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/14.jpg)
• Return type is the object table
CREATE OR REPLACE FUNCTION now
RETURN now_tt AS
l_returnvalue now_tt := now_tt();
…
BEGIN
…
RETURN l_returnvalue;
END;
Table function concepts, function
![Page 15: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/15.jpg)
• Queried with the TABLE function
SELECT *
FROM TABLE(now);
Table function concepts, function
![Page 16: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/16.jpg)
CREATE OR REPLACE FUNCTION now RETURN now_tt AS
l_returnvalue now_tt := now_tt();
l_now VARCHAR2(8);
BEGIN
FOR counter IN 1 .. 4 LOOP
l_now := to_char(SYSDATE, 'HH24:MI:SS');
dbms_lock.sleep(1);
l_returnvalue.extend;
l_returnvalue(l_returnvalue.last) := now_t(l_now);
END LOOP;
RETURN l_returnvalue;
END;
Table function concepts, simple function
![Page 17: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/17.jpg)
SQL> SELECT *
2 FROM TABLE(now)
3 /
NOW
--------
16:54:21
16:54:22
16:54:23
16:54:24
4 rows selected.
Table function concepts, simple function
![Page 18: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/18.jpg)
• Query results passed as a parameter
– Parameter type is REF CURSOR
– SYS_REFCURSOR can be used
for weakly typed option
CREATE OR REPLACE FUNCTION now_and_then
(cursor_in SYS_REFCURSOR )
RETURN now_and_then_tt AS
Table function concepts, nesting functions
![Page 19: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/19.jpg)
• CURSOR keyword denotes value passed within query
SELECT *
FROM TABLE(now_and_then( CURSOR ( SELECT *
FROM TABLE(now))))
/
Table function concepts, nesting functions
![Page 20: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/20.jpg)
CREATE OR REPLACE FUNCTION now_and_then
(cursor_in SYS_REFCURSOR)
RETURN now_and_then_tt AS
l_returnvalue now_and_then_tt := now_and_then_tt();
l_now VARCHAR2(8);
l_then VARCHAR2(8);
BEGIN
LOOP
FETCH cursor_in
INTO l_now;
EXIT WHEN cursor_in%NOTFOUND;
l_then := to_char(SYSDATE, 'HH24:MI:SS');
l_returnvalue.extend;
l_returnvalue(l_returnvalue.last) := now_and_then_t(l_now, l_then);
END LOOP;
RETURN l_returnvalue;
END;
Table function concepts, nested function
![Page 21: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/21.jpg)
SQL> SELECT *
2 FROM TABLE ( now_and_then( CURSOR( SELECT *
3 FROM TABLE ( now ))))
4 /
NOW AND_THEN
-------- --------
16:58:51 16:58:55
16:58:52 16:58:55
16:58:53 16:58:55
16:58:54 16:58:55
4 rows selected.
Table function concepts, nested function
![Page 22: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/22.jpg)
• Function can be pipelined
• Produce results as they are created
– Returning results one record at a time
Pipelined table functions
![Page 23: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/23.jpg)
• Adding PIPELINED keyword to function specification
• Actual return datatype is collection• PIPE ROW function returns single record to calling process and then continues processing
• Return is still requiredCREATE OR REPLACE FUNCTION now
RETURN now_tPIPELINED AS
l_returnvalue single_time_t;BEGIN
loop ...PIPE ROW(l_returnvalue);...
end loop;RETURN;
END;
Pipelining : syntax
![Page 24: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/24.jpg)
CREATE OR REPLACE FUNCTION now
RETURN now_tt
PIPELINED AS
l_returnvalue now_t;
l_now VARCHAR2(8);
BEGIN
FOR counter IN 1 .. 4 LOOP
dbms_lock.sleep(2);
l_now := to_char(SYSDATE, 'HH24:MI:SS');
l_returnvalue := now_t(l_now);
PIPE ROW (l_returnvalue);
END LOOP;
RETURN;
END;
Pipelined function
![Page 25: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/25.jpg)
SQL> SELECT *
2 FROM TABLE(now_and_then(CURSOR(SELECT *
3 FROM TABLE(now))))
4 /
NOW AND_THEN
-------- --------
19:54:15 19:54:15
19:54:17 19:54:17
19:54:19 19:54:19
3 rows selected.
Pipelined function
Without pipelining
it would be:
NOW AND_THEN
-------- --------
19:54:15 19:54:19
19:54:17 19:54:19
19:54:19 19:54:19
now_and_then.sql
![Page 26: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/26.jpg)
• Functions can be parallelized
• If the source data can be processed in parallel, the functions can be processed in parallel
Parallel table functions
![Page 27: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/27.jpg)
Typical data processing
Stage 1OLTP
F1 F2 Data
Warehouse
Stage 2 F3
Data goes through several transformations, in table functions, and then gets loaded into a database
![Page 28: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/28.jpg)
Parallel & pipelined data processing
OLTPF1 Data
Warehouse
F1
F1
F2
F2
F2
F3
F3
F3
Data goes through several transformations, in table functions, in parallel (multiple processes)and then gets loaded into a database
![Page 29: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/29.jpg)
• Prior to Oracle9i, calling a function inside a SQL statement caused serialization.
– The parallel query mechanism could not be used.
• Now you can enable parallel execution of a table function.
– This greatly increases the usability of PL/SQL-enriched SQL in data warehouse
applications.
Parallel execution and table functions
parallel.sql
![Page 30: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/30.jpg)
• The table function's parameter list must consist only of a single strongly-typed REF CURSOR.
• Include the PARALLEL_ENABLE hint in the program header.
– Choose a partition option that specifies how the function's execution should be partitioned.
– "ANY" means that the results are independent of the order in which the function receives the input rows (through the REF CURSOR).
Enabling parallel execution
{[ORDER | CLUSTERORDER | CLUSTERORDER | CLUSTERORDER | CLUSTER] BY column_list} PARALLEL_ENABLEPARALLEL_ENABLEPARALLEL_ENABLEPARALLEL_ENABLE ({PARTITIONPARTITIONPARTITIONPARTITION p BYBYBYBY
[ANY | (HASH | RANGE) column_list]} )
![Page 31: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/31.jpg)
PARALLEL_ENABLE (
Partition p_input_rows BY ANY )
CREATE OR REPLACE FUNCTION Aggregate_Xform (
p_input_rows in My_Types.cur_t) RETURN
My_Types.dept_sals_tab
PIPELINED
CLUSTER P_INPUT_ROWS BY (dept)
PARALLEL_ENABLE
( PARTITION p_input_rows
BY HASH (dept) )
ORDER p_input_rows BY (c1, c2)
PARALLEL_ENABLE
( PARTITION p_input_rows
BY RANGE (c1) )
with
with
with
Simplest form, results don't
vary from order in which
function gets input rows.
All rows for a given department
must go to the same slave,
and rows are delivered
consecutively.
Rows are delivered to a
particular slave as directed by
partition... and will be locally
sorted by that slave.
Examples of parallelized functions
![Page 32: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/32.jpg)
Serial execution
Scramble
alter table emp noparallel;
select *
from table
( scramble
( cursor ( select empno, ename from emp))
);
EMP
![Page 33: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/33.jpg)
Parallel execution
Scramble
Scramble
Scramble
EMP
Scramble
alter table emp parallel 4;
select *
from table
( scramble
( cursor ( select empno, ename from emp))
);
![Page 34: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/34.jpg)
- Using PL/SQL in SQL
- Create script based on the table data
Using the table function
![Page 35: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/35.jpg)
• Using SQL
Create script based on the table data
DEPT
(table)
SQL
statement
insert into DEPT( LOC, DNAME, DEPTNO)
values ( 'NEW YORK', 'ACCOUNTING', 10);
insert into DEPT( LOC, DNAME, DEPTNO)
values ( 'DALLAS', 'RESEARCH', 20);
insert into DEPT( LOC, DNAME, DEPTNO)
values ( 'CHICAGO', 'SALES', 30);
insert into DEPT( LOC, DNAME, DEPTNO)
values ( 'BOSTON', 'OPERATIONS', 40);
![Page 36: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/36.jpg)
SQL
statement
SELECT 'insert into DEPT( LOC, DNAME, DEPTNO) values
( '''||
LOC||''', '''||
DNAME||''', '||
DEPTNO||');' line
FROM DEPT;
• Using SQL
Create script based on the table data
![Page 37: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/37.jpg)
SELECT *
FROM table(createinsertscriptfor('DEPT'));
SQL
statement
• Using table functions
Create script based on the table data
![Page 38: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/38.jpg)
• Using table functions
• Hide complexity behind PL/SQL interface
• Don’t worry about datatypes
Create script based on the table data
![Page 39: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/39.jpg)
�Overview of Table Functions
�Table Function Concepts
�Return collection, query like table
�Pipelined
�Parallel
�Using Table Functions
�Use PL/SQL in SQL
�Hide complexity
Table functions
![Page 40: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/40.jpg)
�tahiti.oracle.com
�For all documentation online
�Oracle PL/SQL Programming (the book)
�Especially chapter 17 (by Steven Feuerstein) and chapter 21 (by Steven Feuerstein with help from Adrian Billington)
References
![Page 41: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/41.jpg)
![Page 42: Table functions - Planboard Symposium 2013](https://reader035.vdocument.in/reader035/viewer/2022081413/54890464b47959fb0c8b587a/html5/thumbnails/42.jpg)