SlideShare una empresa de Scribd logo
1 de 28
Descargar para leer sin conexión
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Your PL/SQL Office Hours session will begin
soon…
Polymorphic Table Functions!
with
Chris Saxon, @ChrisRSaxon & @SQLDaily
https://www.youtube.com/c/TheMagicofSQL
https://blogs.oracle.com/sql
Steven Feuerstein, @sfonplsql
http://www.youtube.com/c/PracticallyPerfectPLSQL
http://stevenfeuersteinonplsql.blogspot.com/
Copyright © 2019, Oracle and/or its affiliates. All rights reserved. |
Polymorphic
Table Functions
blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
Added in Oracle Database 18c, Polymorphic Table Functions
(PTFs) allow you do dynamically manipulate a result set at
runtime.
This means you can add or remove columns from a table,
based on input parameters
Copyright © 2019, Oracle and/or its affiliates. All rights reserved. |
Why would
I want to do
this?!
Ryan McGuire / Gratisography
Copyright © 2019, Oracle and/or its affiliates. All rights reserved. |
C,S,V =>
Dynamic
Customer Total Orders
Best customer 1,422
2nd best customer 1,000
All other customers 6,502
blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
PTF Use Cases
CSV to Column conversion
Inspect CSV files and automatically split
the fields into columns
Dynamic Pivot
Generate pivoted column names based
on a row source
Top-N+
Like a standard Top-N query, but with an
extra row, summarizing all remaining data
Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
To build a PTF, you need two things
A package
The package is the engine of the PTF. This must include a describe function. This tells
the database which columns are in the output
To assign values for each row to the new columns, you use a fetch_rows procedure
The function itself
You can create the PTF itself within the package
Or as a standalone function
Defining PTFs
Copyright © 2019, Oracle and/or its affiliates. All rights reserved. |
create or replace package add_cols_pkg as
function describe (
tab in out dbms_tf.table_t,
cols dbms_tf.columns_t
) return dbms_tf.describe_t;
procedure fetch_rows ;
end add_cols_pkg;
blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
Assign values
(optional)
Define new s
Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
create or replace function add_columns (
tab table,
cols columns
) return
table pipelined
table polymorphic
using add_cols_pkg;
/
Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
create or replace function add_columns (
tab table,
cols columns
) return
table pipelined
table polymorphic
using add_cols_pkg;
/
PTFs introduce two new "data types":
table
The input table for the PTF
Every PTF must have one of these
columns pseudo operator
A list of identifiers. These could be
existing columns in the table, or new
columns you want to add
Copyright © 2019, Oracle and/or its affiliates. All rights reserved. |
create or replace function add_columns (
tab table,
cols columns
) return
table pipelined
table polymorphic
using add_cols_pkg;
/
blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
In the polymorphic clause you
define it as using row or table
semantics.
With row semantics, the input is a
single row.
With table semantics, the input is a set
of rows. This allows you to sort the
input
The using clause states which package
contains the implementation of the PTF
Copyright © 2019, Oracle and/or its affiliates. All rights reserved. |
describe function
blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
You must have one of one of these in your package
This tells the database which columns will be in the result set
The following describe body adds columns to the output
Copyright © 2019, Oracle and/or its affiliates. All rights reserved. |
begin
for i in 1 .. cols.count loop
new_cols(i) := dbms_tf.column_metadata_t (
name => cols(i),
type => dbms_tf.type_number
);
end loop;
return dbms_tf.describe_t ( new_columns => new_cols );
end;
blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
This builds up an array of definitions for the new columns
dbms_tf.column_metadata_t defines their properties
Copyright © 2019, Oracle and/or its affiliates. All rights reserved. |
begin
for i in 1 .. cols.count loop
new_cols(i) := dbms_tf.column_metadata_t (
name => cols(i),
type => dbms_tf.type_number
);
end loop;
return dbms_tf.describe_t ( new_columns => new_cols );
end;
blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
To add the new columns to the results, you must return them
using dbms_tf.describe_t
Copyright © 2019, Oracle and/or its affiliates. All rights reserved. |
select * from add_columns (
dual, columns ( c1 )
);
DUMMY C1
X <null>
blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
Copyright © 2019, Oracle and/or its affiliates. All rights reserved. |
select * from add_columns (
dual, columns ( c1, c2 )
);
DUMMY C1 C2
X <null> <null>
blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
Copyright © 2019, Oracle and/or its affiliates. All rights reserved. |
fetch_rows procedure
blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
To assign values to each row for the new columns you need a
fetch_rows procedure
The following fetch_rows body sets the value of new
columns to
row# * column#
Copyright © 2019, Oracle and/or its affiliates. All rights reserved. |
begin
env := dbms_tf.get_env();
for clmn in 1 .. env.ref_put_col.count loop
for rw in 1 .. env.row_count loop
col ( rw ) := rw * clmn;
end loop;
dbms_tf.put_col ( clmn, col );
end loop;
end fetch_rows;
blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
dbms_tf.get_env captures the
current execution state
This includes details of all the
rows and columns processed in
this iteration of fetch_rows
Copyright © 2019, Oracle and/or its affiliates. All rights reserved. |
begin
env := dbms_tf.get_env();
for clmn in 1 .. env.ref_put_col.count loop
for rw in 1 .. env.row_count loop
col ( rw ) := rw * clmn;
end loop;
dbms_tf.put_col ( clmn, col );
end loop;
end fetch_rows;
blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
col is an array of row values
for a column
Copyright © 2019, Oracle and/or its affiliates. All rights reserved. |
begin
env := dbms_tf.get_env();
for clmn in 1 .. env.ref_put_col.count loop
for rw in 1 .. env.row_count loop
col ( rw ) := rw * clmn;
end loop;
dbms_tf.put_col ( clmn, col );
end loop;
end fetch_rows;
blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
To return the row values to the
client, you must call
dbms_tf.put_col
This assigns the array of row
values to the put column at
position CLMN
Copyright © 2019, Oracle and/or its affiliates. All rights reserved. |
select * from add_columns (
tab,
columns ( c1, c2 )
);
X C1 C2
1 1 2
2 2 4
3 3 6
4 4 8
blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
tab is a four-row table with the
column x
The PTF assigns incrementing
values to the columns added
Copyright © 2019, Oracle and/or its affiliates. All rights reserved. |
select * from add_columns (
tab,
columns ( c1, c2 )
);
X C1 C2
1 1 2
2 2 4
3 3 6
4 4 8
blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
Copyright © 2019, Oracle and/or its affiliates. All rights reserved. |
select * from add_columns (
tab order by x desc,
columns ( c1, c2 )
);
X C1 C2
4 1 2
3 2 4
2 3 6
1 4 8
blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
This PTF uses table semantics
So you can sort the input with
an order by clause after the
table name
This has a descending sort, so as
X decreases, C1 increases
Copyright © 2019, Oracle and/or its affiliates. All rights reserved. |
select * from add_columns (
tab partition by y order by x desc,
columns ( c1, c2 )
);
X Y C1 C2
4 0 1 2
2 0 2 4
3 1 1 2
1 1 2 4
blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
This PTF uses table semantics
So you can also split the input
into groups with an partition by
clause after the table name
The database calls the
fetch_rows procedure at least
once for each distinct value in
the partition by
Y = mod (X, 2); so odd and even
values of X have separate
counters
Copyright © 2019, Oracle and/or its affiliates. All rights reserved. |
X Y C1 C2
1021 1 1021 2042
1022 0 1022 2044
1023 1 1023 2046
1024 0 1024 2048
1025 1 1 2
1026 0 2 4
1027 1 3 6
1028 0 4 8
blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
PTFs process rows in batches
Empirical testing shows this as
units of 1,024 rows (whether
this is a hard limit is TBC)
After fetching this many rows,
the PTF calls fetch_rows again
So this resets the counter
If you write PTFs which have
running counters or
aggregations, you'll need to
save the execution state
You can do this with
dbms_tf.xstore procedures
Copyright © 2019, Oracle and/or its affiliates. All rights reserved. |
for clmn in 1 .. env.ref_put_col.count loop
dbms_tf.xstore_get('col' || clmn, last_row);
for rw in 1 .. env.row_count loop
col ( rw ) := ( rw + last_row ) * clmn;
end loop;
dbms_tf.put_col ( clmn, col );
dbms_tf.xstore_set (
'col' || clmn, last_row + env.row_count
);
end loop;
blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
The xstore holds key-
value pairs
If you get a non-
existent key, the input
value is unchanged
Copyright © 2019, Oracle and/or its affiliates. All rights reserved. |
How do
I debug it?
Gratisography
Copyright © 2019, Oracle and/or its affiliates. All rights reserved. |
dbms_tf.trace (
env => dbms_tf.get_env()
);
dbms_tf.trace (
msg => 'Your text here'
);
blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
The dbms_tf.trace procedure
has several overloads which
allow you to view the current
execution state
In my experience, the most
useful are:
• env; this displays the whole
execution state
• msg; which allows you to
add your own text
Like dbms_output, tracing
displays the results on screen,
not in a database table or view
Copyright © 2019, Oracle and/or its affiliates. All rights reserved. |
Now it's over to you!
Where canYou can find many PTF examples on https://livesql.oracle.com
Copyright © 2019, Oracle and/or its affiliates. All rights reserved. |
asktom.oracle.com
#AskTOMOfficeHours
Ryan McGuire / Gratisography

Más contenido relacionado

La actualidad más candente

Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Aaron Shilo
 

La actualidad más candente (20)

Oracle sql high performance tuning
Oracle sql high performance tuningOracle sql high performance tuning
Oracle sql high performance tuning
 
Polymorphic Table Functions in 18c
Polymorphic Table Functions in 18cPolymorphic Table Functions in 18c
Polymorphic Table Functions in 18c
 
Understanding index
Understanding indexUnderstanding index
Understanding index
 
Cursors
CursorsCursors
Cursors
 
Oracle statistics by example
Oracle statistics by exampleOracle statistics by example
Oracle statistics by example
 
[APJ] Common Table Expressions (CTEs) in SQL
[APJ] Common Table Expressions (CTEs) in SQL[APJ] Common Table Expressions (CTEs) in SQL
[APJ] Common Table Expressions (CTEs) in SQL
 
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
 
Top 10 Oracle SQL tuning tips
Top 10 Oracle SQL tuning tipsTop 10 Oracle SQL tuning tips
Top 10 Oracle SQL tuning tips
 
Oracle Database Performance Tuning Advanced Features and Best Practices for DBAs
Oracle Database Performance Tuning Advanced Features and Best Practices for DBAsOracle Database Performance Tuning Advanced Features and Best Practices for DBAs
Oracle Database Performance Tuning Advanced Features and Best Practices for DBAs
 
SQL Monitoring in Oracle Database 12c
SQL Monitoring in Oracle Database 12cSQL Monitoring in Oracle Database 12c
SQL Monitoring in Oracle Database 12c
 
Cost-based Query Optimization in Apache Phoenix using Apache Calcite
Cost-based Query Optimization in Apache Phoenix using Apache CalciteCost-based Query Optimization in Apache Phoenix using Apache Calcite
Cost-based Query Optimization in Apache Phoenix using Apache Calcite
 
SQL Macros - Game Changing Feature for SQL Developers?
SQL Macros - Game Changing Feature for SQL Developers?SQL Macros - Game Changing Feature for SQL Developers?
SQL Macros - Game Changing Feature for SQL Developers?
 
Tanel Poder Oracle Scripts and Tools (2010)
Tanel Poder Oracle Scripts and Tools (2010)Tanel Poder Oracle Scripts and Tools (2010)
Tanel Poder Oracle Scripts and Tools (2010)
 
SQL Queries
SQL QueriesSQL Queries
SQL Queries
 
DB Time, Average Active Sessions, and ASH Math - Oracle performance fundamentals
DB Time, Average Active Sessions, and ASH Math - Oracle performance fundamentalsDB Time, Average Active Sessions, and ASH Math - Oracle performance fundamentals
DB Time, Average Active Sessions, and ASH Math - Oracle performance fundamentals
 
Oracle SQL 1 Day Tutorial
Oracle SQL 1 Day TutorialOracle SQL 1 Day Tutorial
Oracle SQL 1 Day Tutorial
 
ORACLE PL SQL
ORACLE PL SQLORACLE PL SQL
ORACLE PL SQL
 
SQL Functions and Operators
SQL Functions and OperatorsSQL Functions and Operators
SQL Functions and Operators
 
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic MigrationsIntroduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
 
APEX Connect 2019 - SQL Tuning 101
APEX Connect 2019 - SQL Tuning 101APEX Connect 2019 - SQL Tuning 101
APEX Connect 2019 - SQL Tuning 101
 

Similar a Polymorphic Table Functions in SQL

Tony Jambu (obscure) tools of the trade for tuning oracle sq ls
Tony Jambu   (obscure) tools of the trade for tuning oracle sq lsTony Jambu   (obscure) tools of the trade for tuning oracle sq ls
Tony Jambu (obscure) tools of the trade for tuning oracle sq ls
InSync Conference
 
Fortran & Link with Library & Brief Explanation of MKL BLAS
Fortran & Link with Library & Brief Explanation of MKL BLASFortran & Link with Library & Brief Explanation of MKL BLAS
Fortran & Link with Library & Brief Explanation of MKL BLAS
Jongsu "Liam" Kim
 
Mysqlppt
MysqlpptMysqlppt
Mysqlppt
Reka
 

Similar a Polymorphic Table Functions in SQL (20)

18(ish) Things You'll Love About Oracle Database 18c
18(ish) Things You'll Love About Oracle Database 18c18(ish) Things You'll Love About Oracle Database 18c
18(ish) Things You'll Love About Oracle Database 18c
 
M|18 Ingesting Data with the New Bulk Data Adapters
M|18 Ingesting Data with the New Bulk Data AdaptersM|18 Ingesting Data with the New Bulk Data Adapters
M|18 Ingesting Data with the New Bulk Data Adapters
 
OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...
OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...
OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...
 
OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...
OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...
OOW16 - Oracle Database 12c - The Best Oracle Database 12c New Features for D...
 
Sqlapi0.1
Sqlapi0.1Sqlapi0.1
Sqlapi0.1
 
Tony jambu (obscure) tools of the trade for tuning oracle sq ls
Tony jambu   (obscure) tools of the trade for tuning oracle sq lsTony jambu   (obscure) tools of the trade for tuning oracle sq ls
Tony jambu (obscure) tools of the trade for tuning oracle sq ls
 
Tony Jambu (obscure) tools of the trade for tuning oracle sq ls
Tony Jambu   (obscure) tools of the trade for tuning oracle sq lsTony Jambu   (obscure) tools of the trade for tuning oracle sq ls
Tony Jambu (obscure) tools of the trade for tuning oracle sq ls
 
Les09.ppt
Les09.pptLes09.ppt
Les09.ppt
 
Fortran & Link with Library & Brief Explanation of MKL BLAS
Fortran & Link with Library & Brief Explanation of MKL BLASFortran & Link with Library & Brief Explanation of MKL BLAS
Fortran & Link with Library & Brief Explanation of MKL BLAS
 
Useful PL/SQL Supplied Packages
Useful PL/SQL Supplied PackagesUseful PL/SQL Supplied Packages
Useful PL/SQL Supplied Packages
 
Beg sql
Beg sqlBeg sql
Beg sql
 
Beg sql
Beg sqlBeg sql
Beg sql
 
Apache Cassandra 2.0
Apache Cassandra 2.0Apache Cassandra 2.0
Apache Cassandra 2.0
 
Mysqlppt
MysqlpptMysqlppt
Mysqlppt
 
DBA Commands and Concepts That Every Developer Should Know
DBA Commands and Concepts That Every Developer Should KnowDBA Commands and Concepts That Every Developer Should Know
DBA Commands and Concepts That Every Developer Should Know
 
05 Creating Stored Procedures
05 Creating Stored Procedures05 Creating Stored Procedures
05 Creating Stored Procedures
 
DBA Brasil 1.0 - DBA Commands and Concepts That Every Developer Should Know
DBA Brasil 1.0 - DBA Commands and Concepts That Every Developer Should KnowDBA Brasil 1.0 - DBA Commands and Concepts That Every Developer Should Know
DBA Brasil 1.0 - DBA Commands and Concepts That Every Developer Should Know
 
DBA Brasil 1.0 - DBA Commands and Concepts That Every Developer Should Know
DBA Brasil 1.0 - DBA Commands and Concepts That Every Developer Should KnowDBA Brasil 1.0 - DBA Commands and Concepts That Every Developer Should Know
DBA Brasil 1.0 - DBA Commands and Concepts That Every Developer Should Know
 
DBA Brasil 1.0 - DBA Commands and Concepts That Every Developer Should Know
DBA Brasil 1.0 - DBA Commands and Concepts That Every Developer Should KnowDBA Brasil 1.0 - DBA Commands and Concepts That Every Developer Should Know
DBA Brasil 1.0 - DBA Commands and Concepts That Every Developer Should Know
 
War of the Indices- SQL Server and Oracle
War of the Indices-  SQL Server and OracleWar of the Indices-  SQL Server and Oracle
War of the Indices- SQL Server and Oracle
 

Más de Chris Saxon

Más de Chris Saxon (7)

Game of Fraud Detection with SQL and Machine Learning
Game of Fraud Detection with SQL and Machine LearningGame of Fraud Detection with SQL and Machine Learning
Game of Fraud Detection with SQL and Machine Learning
 
Agile Database Development with JSON
Agile Database Development with JSONAgile Database Development with JSON
Agile Database Development with JSON
 
Using Edition-Based Redefinition for Zero Downtime PL/SQL Changes
Using Edition-Based Redefinition for Zero Downtime PL/SQL ChangesUsing Edition-Based Redefinition for Zero Downtime PL/SQL Changes
Using Edition-Based Redefinition for Zero Downtime PL/SQL Changes
 
Why Isn't My Query Using an Index? An Introduction to SQL Performance
Why Isn't My Query Using an Index? An Introduction to SQL PerformanceWhy Isn't My Query Using an Index? An Introduction to SQL Performance
Why Isn't My Query Using an Index? An Introduction to SQL Performance
 
12 Things Developers Will Love About Oracle Database 12c Release 2
12 Things Developers Will Love About Oracle Database 12c Release 212 Things Developers Will Love About Oracle Database 12c Release 2
12 Things Developers Will Love About Oracle Database 12c Release 2
 
How to Hack Your App Using SQL Injection
How to Hack Your App Using SQL InjectionHow to Hack Your App Using SQL Injection
How to Hack Your App Using SQL Injection
 
How to Find Patterns in Your Data with SQL
How to Find Patterns in Your Data with SQLHow to Find Patterns in Your Data with SQL
How to Find Patterns in Your Data with SQL
 

Último

Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Último (20)

Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 

Polymorphic Table Functions in SQL

  • 1. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Your PL/SQL Office Hours session will begin soon… Polymorphic Table Functions! with Chris Saxon, @ChrisRSaxon & @SQLDaily https://www.youtube.com/c/TheMagicofSQL https://blogs.oracle.com/sql Steven Feuerstein, @sfonplsql http://www.youtube.com/c/PracticallyPerfectPLSQL http://stevenfeuersteinonplsql.blogspot.com/
  • 2. Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | Polymorphic Table Functions blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon Added in Oracle Database 18c, Polymorphic Table Functions (PTFs) allow you do dynamically manipulate a result set at runtime. This means you can add or remove columns from a table, based on input parameters
  • 3. Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | Why would I want to do this?! Ryan McGuire / Gratisography
  • 4. Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | C,S,V => Dynamic Customer Total Orders Best customer 1,422 2nd best customer 1,000 All other customers 6,502 blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon PTF Use Cases CSV to Column conversion Inspect CSV files and automatically split the fields into columns Dynamic Pivot Generate pivoted column names based on a row source Top-N+ Like a standard Top-N query, but with an extra row, summarizing all remaining data
  • 5. Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon To build a PTF, you need two things A package The package is the engine of the PTF. This must include a describe function. This tells the database which columns are in the output To assign values for each row to the new columns, you use a fetch_rows procedure The function itself You can create the PTF itself within the package Or as a standalone function Defining PTFs
  • 6. Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | create or replace package add_cols_pkg as function describe ( tab in out dbms_tf.table_t, cols dbms_tf.columns_t ) return dbms_tf.describe_t; procedure fetch_rows ; end add_cols_pkg; blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon Assign values (optional) Define new s
  • 7. Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon create or replace function add_columns ( tab table, cols columns ) return table pipelined table polymorphic using add_cols_pkg; /
  • 8. Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon create or replace function add_columns ( tab table, cols columns ) return table pipelined table polymorphic using add_cols_pkg; / PTFs introduce two new "data types": table The input table for the PTF Every PTF must have one of these columns pseudo operator A list of identifiers. These could be existing columns in the table, or new columns you want to add
  • 9. Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | create or replace function add_columns ( tab table, cols columns ) return table pipelined table polymorphic using add_cols_pkg; / blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon In the polymorphic clause you define it as using row or table semantics. With row semantics, the input is a single row. With table semantics, the input is a set of rows. This allows you to sort the input The using clause states which package contains the implementation of the PTF
  • 10. Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | describe function blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon You must have one of one of these in your package This tells the database which columns will be in the result set The following describe body adds columns to the output
  • 11. Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | begin for i in 1 .. cols.count loop new_cols(i) := dbms_tf.column_metadata_t ( name => cols(i), type => dbms_tf.type_number ); end loop; return dbms_tf.describe_t ( new_columns => new_cols ); end; blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon This builds up an array of definitions for the new columns dbms_tf.column_metadata_t defines their properties
  • 12. Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | begin for i in 1 .. cols.count loop new_cols(i) := dbms_tf.column_metadata_t ( name => cols(i), type => dbms_tf.type_number ); end loop; return dbms_tf.describe_t ( new_columns => new_cols ); end; blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon To add the new columns to the results, you must return them using dbms_tf.describe_t
  • 13. Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | select * from add_columns ( dual, columns ( c1 ) ); DUMMY C1 X <null> blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
  • 14. Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | select * from add_columns ( dual, columns ( c1, c2 ) ); DUMMY C1 C2 X <null> <null> blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
  • 15. Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | fetch_rows procedure blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon To assign values to each row for the new columns you need a fetch_rows procedure The following fetch_rows body sets the value of new columns to row# * column#
  • 16. Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | begin env := dbms_tf.get_env(); for clmn in 1 .. env.ref_put_col.count loop for rw in 1 .. env.row_count loop col ( rw ) := rw * clmn; end loop; dbms_tf.put_col ( clmn, col ); end loop; end fetch_rows; blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon dbms_tf.get_env captures the current execution state This includes details of all the rows and columns processed in this iteration of fetch_rows
  • 17. Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | begin env := dbms_tf.get_env(); for clmn in 1 .. env.ref_put_col.count loop for rw in 1 .. env.row_count loop col ( rw ) := rw * clmn; end loop; dbms_tf.put_col ( clmn, col ); end loop; end fetch_rows; blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon col is an array of row values for a column
  • 18. Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | begin env := dbms_tf.get_env(); for clmn in 1 .. env.ref_put_col.count loop for rw in 1 .. env.row_count loop col ( rw ) := rw * clmn; end loop; dbms_tf.put_col ( clmn, col ); end loop; end fetch_rows; blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon To return the row values to the client, you must call dbms_tf.put_col This assigns the array of row values to the put column at position CLMN
  • 19. Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | select * from add_columns ( tab, columns ( c1, c2 ) ); X C1 C2 1 1 2 2 2 4 3 3 6 4 4 8 blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon tab is a four-row table with the column x The PTF assigns incrementing values to the columns added
  • 20. Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | select * from add_columns ( tab, columns ( c1, c2 ) ); X C1 C2 1 1 2 2 2 4 3 3 6 4 4 8 blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
  • 21. Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | select * from add_columns ( tab order by x desc, columns ( c1, c2 ) ); X C1 C2 4 1 2 3 2 4 2 3 6 1 4 8 blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon This PTF uses table semantics So you can sort the input with an order by clause after the table name This has a descending sort, so as X decreases, C1 increases
  • 22. Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | select * from add_columns ( tab partition by y order by x desc, columns ( c1, c2 ) ); X Y C1 C2 4 0 1 2 2 0 2 4 3 1 1 2 1 1 2 4 blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon This PTF uses table semantics So you can also split the input into groups with an partition by clause after the table name The database calls the fetch_rows procedure at least once for each distinct value in the partition by Y = mod (X, 2); so odd and even values of X have separate counters
  • 23. Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | X Y C1 C2 1021 1 1021 2042 1022 0 1022 2044 1023 1 1023 2046 1024 0 1024 2048 1025 1 1 2 1026 0 2 4 1027 1 3 6 1028 0 4 8 blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon PTFs process rows in batches Empirical testing shows this as units of 1,024 rows (whether this is a hard limit is TBC) After fetching this many rows, the PTF calls fetch_rows again So this resets the counter If you write PTFs which have running counters or aggregations, you'll need to save the execution state You can do this with dbms_tf.xstore procedures
  • 24. Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | for clmn in 1 .. env.ref_put_col.count loop dbms_tf.xstore_get('col' || clmn, last_row); for rw in 1 .. env.row_count loop col ( rw ) := ( rw + last_row ) * clmn; end loop; dbms_tf.put_col ( clmn, col ); dbms_tf.xstore_set ( 'col' || clmn, last_row + env.row_count ); end loop; blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon The xstore holds key- value pairs If you get a non- existent key, the input value is unchanged
  • 25. Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | How do I debug it? Gratisography
  • 26. Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | dbms_tf.trace ( env => dbms_tf.get_env() ); dbms_tf.trace ( msg => 'Your text here' ); blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon The dbms_tf.trace procedure has several overloads which allow you to view the current execution state In my experience, the most useful are: • env; this displays the whole execution state • msg; which allows you to add your own text Like dbms_output, tracing displays the results on screen, not in a database table or view
  • 27. Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | Now it's over to you! Where canYou can find many PTF examples on https://livesql.oracle.com
  • 28. Copyright © 2019, Oracle and/or its affiliates. All rights reserved. | asktom.oracle.com #AskTOMOfficeHours Ryan McGuire / Gratisography