+ All Categories
Home > Documents > PL/SQL enhancements in Oracle9i - · PDF filePL/SQL enhancements in Oracle9i paper #129,...

PL/SQL enhancements in Oracle9i - · PDF filePL/SQL enhancements in Oracle9i paper #129,...

Date post: 01-Feb-2018
Category:
Upload: phamkhanh
View: 228 times
Download: 2 times
Share this document with a friend
95
Transcript

Bryn Llewellyn

Product Managerfor PL/SQLOracle Corporation

PL/SQL enhancementsin Oracle9i

paper #129, Oracle OpenWorld, San Francisco, Tue 4-Dec-2001

But before I start…But before I start…

OTN homepageOTN homepage

TechnologiesTechnologies

PL/SQLPL/SQL

otn.oracle.com/tech/pl_sqlotn.oracle.com/tech/pl_sql

What are the Benefits?

Speed and scalabilityFunctionalityUsability for the developer

What’s been enhanced?

ImplementationLanguage featuresSupplied packages

What kind of enhancements?

TransparentSemi-transparentNew features

– New constructs in the language– Richer APIs in the supplied packages

Here comes the list…Here comes the list…

Implementation

Feature Perf Funct UseFeatureFeature PerfPerf FunctFunct UseUse

Native compilation of PL/SQLNative compilation of PL/SQLNative compilation of PL/SQL

Manipulating records faster by up to 5xManipulating records faster by up to 5xManipulating records faster by up to 5x

Inter-package calls faster by up to 1.5xInterInter--package calls faster by up to 1.5xpackage calls faster by up to 1.5x

Utl_Tcp native implementationUtl_TcpUtl_Tcp native implementationnative implementation

Common SQL parserCommon SQL parserCommon SQL parser

Language features

Feature Perf Funct UseFeatureFeature PerfPerf FunctFunct UseUse

Table functionsTable functionsTable functions

Cursor expressionsCursor expressionsCursor expressions

Multilevel collectionsMultilevel collectionsMultilevel collections

Bulk binding in native dynamic SQLBulk binding in native dynamic SQLBulk binding in native dynamic SQL

Exception handling in bulk binding DML operationsException handling in bulkException handling in bulk binding binding DML operationsDML operations

CASE statements and CASE expressionsCASE statements and CASE expressionsCASE statements and CASE expressions

Exception handling in bulk DML

Consider giving employees a 10% raise where employee_id among the values in a table of numbers…forall j in id.first..id.last

There might be a per department salary cap– so some intended updates will failPre-Oracle9i the whole bulk statement failedNow the OK updates will fail and the exceptions can be reportedsave exceptionssql%bulk_exceptions collection

Multilevel collection syntax

for j in my_multi.first..my_multi.lastloopfor k in my_multi(j).first..my_multi(j).lastloopShow ( my_multi(j)(k) );

end loop;end loop;

Collections can be nested to arbitrary depth

CASE statement syntax

case nwhen 1 then Action1;when 2 then Action2;when 3 then Action3;else ActionOther;

end case;

CASE statement syntax

casewhen p = 1 then Action1;when q = 1 then Action2;when r > 1 then Action3;else ActionOther;

end case;

“searched” variety

CASE expression syntax

text := case nwhen 1 then 'one'when 2 then 'two'when 3 then 'three'else 'other'

end;

CASE expression syntax

text := casewhen p = 1 then 'one'when r = 2 then 'two'when q > 1 then 'three'else 'other'

end;

“searched” variety

CASE_NOT_FOUND exceptionbeginp:=0; q:=0; r:=0;casewhen p = 1 then Action1;when r = 2 then Action2;when q > 1 then Action3;

end case;exceptionwhen case_not_found thenShow ('Exception: case_not_found' );

end;

Language features – cont.

Feature Perf Funct UseFeatureFeature PerfPerf FunctFunct UseUse

VARCHAR2 <-> NVARCHAR2 (etc) assignmentVARCHAR2 <VARCHAR2 <--> NVARCHAR2 (etc) assignment> NVARCHAR2 (etc) assignment

VARCHAR2 <-> CLOB assignmentVARCHAR2 <VARCHAR2 <--> CLOB assignment> CLOB assignment

SUBSTR and INSTR w/ CLOBSUBSTR and INSTR w/ CLOBSUBSTR and INSTR w/ CLOB

Seamless access to new SQL features

e.g. MERGE, multitable insert, new time datatypes…

Seamless access to new SQL featuresSeamless access to new SQL features

e.g. MERGE, multitable insert, new time datatypese.g. MERGE, multitable insert, new time datatypes……

OO: Schema evolutioninheritance supporta.k.a. subtyping and polymorphism

OOOO: : Schema evolutionSchema evolutioninheritance supportinheritance supporta.k.a. subtyping and polymorphisma.k.a. subtyping and polymorphism

Supplied packages

Feature Perf Funct UseFeatureFeature PerfPerf FunctFunct UseUse

Utl_Http enhancedUtl_HttpUtl_Http enhancedenhanced

Utl_Raw enhancedUtl_Utl_Raw Raw enhancedenhanced

Utl_File enhancedUtl_FileUtl_File enhancedenhanced

Nineteen new packagesNineteenNineteen new packagesnew packages

Utl_Http enhancementsUsed to send HTTP request and handle the reply mechanically – especially in B2B applicationsOracle9i adds…

– “POST” method – arbitarily long request– Authentication– Access to return status code– RAW reply– cookie support

I.e. provides full support for the semantics that can be expressed via HTTPFull functionality for character set conversion for request and reply

I can’t possiblytalk abouteverythingon that list

in detail!

I can’t possiblytalk abouteverythingon that list

in detail!

So insteadI’m going topick just a coupleto look atin depth…

So insteadI’m going topick just a coupleto look atin depth…

• Native compilation• Native compilation

• Table functionsand cursor expressions

• Table functionsand cursor expressions

Native compilation of PL/SQL

When PL/SQL is used as a thin wrapper for SQL its execution speed is rarely an issueBut we see an increasing trend to use PL/SQL for computationally intensive database independent tasksHere it is the execution speed of the PL/SQL code that determines the performance

Background

Pre-Oracle9i, compilation of PL/SQL source code always results in bytecode which is stored in the database and interpreted at run-time by a virtual machine implemented within ORACLE

What’s new?

In Oracle9i PL/SQL source code may optionally be compiled into native object code which is linked into ORACLE

What’s the benefit?

Speed increased by up to 40%“Thin wrapper” programs won’t speed up so much

…but they won’t slow down!

How does it work?

The code generator translates the PL/SQL source code into C source codeThis is compiled on the given platform and stored as object files on the filesystem……and then linked into ORACLE

How do you do it?

One-time DBA setupThe developer chooses at compile time via the session parameter…

plsql_compiler_flags

One-time DBA setup

Specify 3rd party utilities for compiling and linking– Should be owned by the ORACLE owner– Only the ORACLE owner should have

write accessSpecify directories for the compiled object librariesDone via system parameters

Developer choice

alter sessionset plsql_compiler_flags =

'NATIVE'/* or 'INTERPRETED' */;

sets the compilation mode for subsequently compiled PL/SQL library units

Oracle recommends…

All PL/SQL library units that are called from a given natively compiled top-level unit should also be compiled natively

there is a cost for the context switch when a library unit compiled in native mode invokes one compiled in interpreted mode

Recommendation includes the Oracle-supplied library units (by default these are compiled in interpreted mode)

Oracle9i in Action

170 Systems, Inc have been an Oracle Partner for eleven years and participated in the Beta Program for the Oracle9i Database with particular interest in PL/SQL Native CompilationThey have now certified their 170 MarkView Document Management and Imaging System™against Oracle9iThey have updated the install scripts to optionally turn on Native Compilation

170 MarkViewDocument Managementand Imaging System

Provides Content Management, Document Management, Imaging and Workflow solutionsTightly integrated with the Oracle9i Database, Oracle9i Application Server andthe Oracle E-Business SuiteEnables businesses to capture and manage all of their information online in a single, unified system

170 MarkView™

Customers include…– British Telecommunications– E*TRADE Group– the Apollo Group– the University of Pennsylvania

Very large numbers of documents, images, concurrent users, and high transaction ratesPerformance and scalability especially important

Large-scale multi-user, multi-access system

170 MarkView™

Business logic, including preparation of data for presentation, is implemented in the database in PL/SQL

Involves complex logic and intensive string processing supported by stacks and lists of values modeled as PL/SQL collections.

Visit 170 Systems at Booth # 1914

170 Systems

Have observed a performance increase of up to 40% for computationally intensive routines

…and no performance degradation

Native Compilation - summary

It’s a semi-transparent enhancementIt gives you improved performanceTry it !

• Table functionsand cursor expressions

• Table functionsand cursor expressions

Table functionsand cursor expressions

Cursor variables – recapManipulating cursor expressions in PL/SQLUsing a cursor expressionas an actual parameter to a PL/SQL functionTable functions pre-Oracle9iOracle9i pipelined table functionsDaisy-chaining table functionsParallelization

Cursor variables - recap

Supported pre-Oracle9iAllow encapsulation of logicspecific to tuples of a particular formatto be independent ofthe concrete SELECT statementwhich retrieves them

Cursor variables - recap

procedure Bulk_Fetch_From_Cursor( p_cursor in sys_refcursor )

is...

SYS_REFCURSOR is a new Oracle9iusability featureDefines a generic weak cursor once and for all

Set up the target

Declare an index-by PL/SQL table for thefetched rows

...istype names_t istable of varchar2(4000)index by binary_integer;

the_names names_t;begin...

Do the bulk fetch

fetch p_cursorbulk collectinto the_names;

Works pre-Oracle9iPerformance boost because reduces context switching between PL/SQL and SQL engines

Process the results

for j in the_names.first..the_names.lastloopShow ( the_names(j) );

end loop;

Works pre-Oracle9i

Invoke the proceduredeclarethe_cursor sys_refcursor;

beginopen the_cursor for'select last_name from employees

order by last_name';Bulk_Fetch_From_Cursor ( the_cursor );close the_cursor;

Note we’re using Native Dynamic SQL

New in Oracle9i

This is just one example of bulk binding working with native dynamic SQLThe combination now works in all situations

– DefiningSELECT

– In-bindingFORALL … USING

– Out-bindingFORALL … USING … RETURNING

Table functionsand cursor expressions

Cursor variables – recapManipulating cursor expressions in PL/SQLUsing a cursor expressionas an actual parameter to a PL/SQL functionTable functions pre-Oracle9iOracle9i pipelined table functionsDaisy-chaining table functionsParallelization

Cursor expressions and PL/SQL

Suppose we want to make a pretty print

…listing departments

…and under each department list its employees

Explicit 3GL approach

for department in ( select ... )loopShow ( department.department_name );for employee in ( select ...where department_id =

department.department_id )loopShow ( employee.last_name );

This SQL does the job in one go

selectdepartment_name,cursor (

select last_namefrom employees ewhere e.department_id =

d.department_id)

from departments d;

Use in it PL/SQL – new in Oracle9i

declarecursor depts isselect

department_name,cursor ( select ... )

from departments d;

Since there’s only one SQL statement(we had two in the explicit approach)the CBO has a better chance

Set up the fetch targets

Just for fun we’ll do some bulk fetching

v_dname dep...%type;emps sys_refcursor;

type enames_t is table of emp...%typeindex by...;

v_enames enames_t;

Outer loop

Fetch the cursor into the ref cursor targetand then fetch it (bulk) into its targetopen depts;loopfetch depts into v_dname, emps;exit when depts%notfound;Show ( v_dname );fetch empsbulk collect into v_ename;

Inner loop

Process the bulk fetched results

for j in v_ename.first..v_ename.lastloopShow ( v_ename(j) );

end loop;

Table functionsand cursor expressions

Cursor variables – recapManipulating cursor expressions in PL/SQLUsing a cursor expressionas an actual parameter to a PL/SQL functionTable functions pre-Oracle9iOracle9i pipelined table functionsDaisy-chaining table functionsParallelization

Cursor terminology

A cursor variable (i.e. a variable of typeREF CURSOR) points to an actual cursorIt may be used as a formal parameter to a PL/SQL procedure or functionA cursor expression defines an actual cursor…and is legal in a SQL statement

Func ( cursor ( select c from t ) )

So you’d expect to write…

Cursor expression as an actual parameter to a PL/SQL function

Pre-Oracle9i this was never allowedAt Oracle9i it is allowed…

…when a function is invoked ina top level SQL statement

Cursor expression inWHERE clause functionselect ...from employees managers where Func(cursor ( < select stuff for

this manager's reports > ),managers.hire_date

) = 1;

Cursor expression inWHERE clause function

We’re deciding on the basis of elaborate procedural logicWriting the whole thing as a procedure you need to output to a tableWith the logic in a WHERE clause function you can define a VIEW for dynamic reuse

A cursor expressioncan be an actual parameterto a PL/SQL functionin a top levelSQL statement

A cursor expressioncan be an actual parameterto a PL/SQL functionin a top levelSQL statement

Hold that thought…

Table functionsand cursor expressions

Cursor variables – recapManipulating cursor expressions in PL/SQLUsing a cursor expressionas an actual parameter to a PL/SQL functionTable functions pre-Oracle9iOracle9i pipelined table functionsDaisy-chaining table functionsParallelization

Pre-Oracle9i table function

We define our row, and a table of our rows…

create type my_rowas object ( idx number,

text varchar2(20) );

create type my_tab as table of my_row;

Pre-Oracle9i table function

function Func return my_tab isv_tab my_tab;

beginv_tab := my_tab ( my_row ( ... ) );< extend the table and compute the rows >return v_tab;

end Func;

All the rows are created before the function returns

Pre-Oracle9i table function

select *from table( cast

( Func() as my_tab ));

Nice, but the response characterstics are not what we’re used to with a rowsource

Table functionsand cursor expressions

Cursor variables – recapManipulating cursor expressions in PL/SQLUsing a cursor expressionas an actual parameter to a PL/SQL functionTable functions pre-Oracle9iOracle9i pipelined table functionsDaisy-chaining table functionsParallelization

Oracle9i pipelined table function

function Func return my_tab pipelined isv_row my_row;

beginfor ...loopv_row := my_row ( ... );pipe row ( v_row );

end loop;return;

end Func;

As soon asa row is computed,it’s deliveredrowsource-style

As soon asa row is computed,it’s deliveredrowsource-style

Hold that thought too…

Note:

The pipelined and pipe row keywordscan only be used together as shownA pipelined table function can be invokedonly in the FROM list of a SELECT clause

select * from table ( Func() );

We can now use a simpler syntax…

We can now use package-level types for the row and for the table

Table functionsand cursor expressions

Cursor variables – recapManipulating cursor expressions in PL/SQLUsing a cursor expressionas an actual parameter to a PL/SQL functionTable functions pre-Oracle9iOracle9i pipelined table functionsDaisy-chaining table functionsParallelization

Remember…

A cursor expression can be an actual parameter to a PL/SQL function in a top level SQL statementSo a table function may now be defined with an input parameter of type REF CURSOR and invoked with a cursor expression as the actual parameter

function Func_2 ( p_cur in sys_refcursor )return Pkg.my_tab pipelined isv_in_row Pkg.my_in_row;v_out_row Pkg.my_row;

beginloopfetch p_cur into v_in_row;exit when p_cur%notfound;

< compute out-row(s) from in-row(s) >pipe row ( v_out_row );

end loop;close p_cur;return;

end Func_2;

We’re consuming in-rows,Transforming them procedurally to out-rowswith an arbitrarily complex M:N algorithm,and piping out-rowsas soon as they’re ready

We’re consuming in-rows,Transforming them procedurally to out-rowswith an arbitrarily complex M:N algorithm,and piping out-rowsas soon as they’re ready

How do we use it?

Suppose t is a table which supports a select list compatible with Pkg.my_rowWe can now invoke the table function thus…

select * from table(Func_2( cursor ( select * from t ) )

);

Think about it…

We now have a very powerful generic transformation techniqueIt starts with the results from a SELECT and transforms them into something you can SELECTfromSounds familiar?Note: don’t forget, the table function can have ordinary input parameters

Think of a table functionas a deluxe,parameterizable view

Think of a table functionas a deluxe,parameterizable view

t might have been a view…create view t asselect * from table ( Func() );

So we’d actually be doing…

select * from table(Func_2 ( cursor(select * from table ( Func() ) )

));

Now we’re daisy-chainingNow we’re daisy-chaining

Daisy-chaining

We can plug any number of transformationsback-to-backEach can perform an arbitrarily complex transformationThe starting point could be an Oracle tableOr it could be a table functionthat accesses external datavia Utl_Fileor via the call-out framework

Table functionsand cursor expressions

Cursor variables – recapManipulating cursor expressions in PL/SQLUsing a cursor expressionas an actual parameter to a PL/SQL functionTable functions pre-Oracle9iOracle9i pipelined table functionsDaisy-chaining table functionsParallelization

Who’s going to use them?

The driver for developing table functions was datawarehousing, especially the ETL phaseSo of course the story wouldn’t be complete without a parallel capabilityLet’s look at the syntax…

PARALLEL_ENABLE syntax

function Func_2 ( p_cur in sys_refcursor )return Pkg.my_tabpipelinedparallel_enable ( partition p_cur by any )

is...

Must have an input REF CURSOR parameter to drive the partitioningANY is the simple, special case – results don’t depend on the order of processing

Caution…

If you use ANY and your assertion is wrong, the results will be unpredictableThe developer must design the algorithm so that the results don’t depend on the degree of parallelism

What if the results do dependon the order of processing?

We can be more explicit when we declare how we want the input rows to be partitionedThis requires that we have a strongly typed input cursor, e.g…

package Pkg istype my_row is record ( n number, ... );type cur_t is ref cursor return my_row;

end Pkg;

CLUSTER … BYfunction Func_3 ( p_cur in Pkg.cur_t )return Pkg.my_tabpipelinedparallel_enable( partition p_cur by hash (n) )

cluster p_cur by (n)is...

The algorithm requires that all rows for a given value of n come together to a single slave……but doesn’t care about the order

ORDER … BYfunction Func_4 ( p_cur in Pkg.cur_t )return Pkg.my_tabpipelinedparallel_enable( partition p_cur by range (n) )

order p_cur by ( n, m )is...

Not only must all rows for a given value of n come together to a single slave……but also they must be ordered by n, m

Before…

stage1stage1t1t1 stage2stage2t2t2 t3t3

datadatawarehouse

oltpoltpwarehouse

Using Oracle9i table functions…

t3t3t2t2t1t1

t3t3t2t2t1t1

t3t3t2t2t1t1

t3t3t2t2t1t1

t3t3t2t2t1t1

datadatawarehouse

oltpoltpwarehouse

pipelined parallelized

Comparison…

Sun Ultra-Enterprise 45003 GB RAM, 10 CPUs of 168 MHz1,000,000 row source table1 row in to 7 rows out pivot transformOracle8i – PL/SQL cursor loop with 7 INSERTsOracle9i – table function with 7 PIPE ROWsPerformance and Scalability in DSS Environmentwith Oracle9i,Neil Thombre, Oracle Corp – OOW paper #822also on otn.oracle.com/deploy/performance/

87 87 minmin

Oracle8Oracle8iiOracle9Oracle9iipipelinedpipelined

37 37 minmin

2.4 2.4 xx

Oracle9Oracle9iipipelinedpipelinedparallel 20parallel 20

12 12 minmin

7.5 7.5 xx

Table Functions - summary

An exciting new language feature

Generic applicability…think deluxe, parameterizable view

Especially beneficial inExtraction Load Transformationphase in warehousing applications

Oracle9i PL/SQL gives you…

Improved performanceIncreased functionalityBetter usability for the developer

you should upgrade !you should upgrade !

Q U E S T I O N SQ U E S T I O N SA N S W E R SA N S W E R S


Recommended