Download - Advanced Techniques.ppt
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 1/269
PL/SQL Advanced Techniques - page 17/10/2013 Copyright 2001 Steven Feuerstein
Achieving PL/SQL Excellence
Oracle PL/SQLAdvanced Techniques
Oracle7 thru Oracle8i
Steven Feuersteinwww.StevenFeuerstein.com
www.Quest.comwww.OReilly.com
and contributions most excellent from Bill Pribyl and Dick Bolz
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 2/269
PL/SQL Advanced Techniques - page 27/10/2013 Copyright 2001 Steven Feuerstein
Objective & Outline
Objective
– Expand your knowledge and awareness of important and newfeatures of the PL/SQL language.
Outline – Building with Packages (Oracle7+)
– PL/SQL Collections (Oracle7 and Oracle8+)
– Cursor Variables (Oracle7 and Oracle8+)
– Dynamic SQL: DBMS_SQL and Native Dynamic SQL (8i)
– Calling Java from PL/SQL (Oracle8i) and C (Oracle8)
– Oracle Advanced Queuing with DBMS_AQ (Oracle8)
– Managing Large Objects with DBMS_LOB (Oracle8) – Other Oracle8i New Features
» Autonomous Transactions (Oracle8i)
» Invoker Rights Model (Oracle8i)
» Row Level Security: DBMS_RLS
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 3/269
PL/SQL Advanced Techniques - page 37/10/2013 Copyright 2001 Steven Feuerstein
Software Used in Training
PL/Vision: a library of packages installed on top of PL/SQL.
– PL/Vision Lite - use it, copy, change it for free -- unless you buildsoftware to be sold commercially.
– Active PL/SQL Knowledge Base: contains PL/Vision Professional, thefully supported and enhanced version.
Demonstration scripts executed in the training can befound on the RevealNet PL/SQL Pipeline: – http://www.revealnet.com/Pipelines/PLSQL/index.htm
– Archives surfboard, Miscellaneous, PL/SQL Seminar Files
– See filedesc.doc for a listing of many of the files.
The PL/SQL IDE (Integrated Development Environment). – You no longer have to use SQL*Plus and a crude editor! Choose from
among the many listed in plsql_ides.txt.
plsql_ides.txt
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 4/269
PL/SQL Advanced Techniques - page 47/10/2013 Copyright 2001 Steven Feuerstein
Building withPL/SQL Packages
Achieving PL/SQL Excellence
Overview
Initialization section
Overloading
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 5/269PL/SQL Advanced Techniques - page 57/10/2013 Copyright 2001 Steven Feuerstein
What is a Package?
A collection of code elements, from procedures and
functions to TYPE, variable and cursor declarations. – Single-most important structure within PL/SQL, and almost
certainly one of the most under-utilized.
– Conceptually very simple, it can take some time to fully grasp theimplications and potential of the package.
The method of choice by Oracle and other softwaredevelopers for extending the PL/SQL language.
– You will find packages in the database, in Oracle Developer/2000, inOracle Application Server.
Let‟s review some of the benefits of packages.
tmr.pkgdbparm.pkg
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 6/269PL/SQL Advanced Techniques - page 67/10/2013 Copyright 2001 Steven Feuerstein
When to Build a Package
Join physically logically-related code.
– Can lead to performance improvements. – Puts more structure and organization in your body of code.
Improve transaction integrity by hiding data structures
behind the package interface. – Instead of writing SQL directly in your programs, you call thepackaged procedures and functions instead.
Construct very flexible and usable utilities for developers.
– There's a big difference between a bunch of separate programs anda coherent, package-based "component".
watch.pkg
custrules.pkginsga.pkg
te_employee.pkste_employee.pkb
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 7/269PL/SQL Advanced Techniques - page 77/10/2013 Copyright 2001 Steven Feuerstein
Package Initialization
The initialization section is a block of code at the end of
the package body that is executed once per session, thefirst time any package element is referenced. – The PL/SQL runtime engine determines when and if this code
should be run.
Does thepackage have an
init section?
Program referencespackage elementthe first time ineach session.
no
Run initializationcode.
yes
Complete requestfor packaged
element.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 8/269PL/SQL Advanced Techniques - page 87/10/2013 Copyright 2001 Steven Feuerstein
Package Initialization Structure
The initialization section:
– Is defined after and outside of anyprograms in the package.
– Is not required. In fact, mostpackages you build won't have one.
– Can have its own exception handling
section.
Useful for: – Performing complex setting of
default or initial values.
– Setting up package data which does
not change for the duration of asession.
– Confirming that package is properlyinstantiated.
PACKAGE BODY pkgIS
PROCEDURE proc ISBEGINEND;
FUNCTION func RETURNBEGINEND;
BEGINEND pkg;
BEGIN after/outsideof any program
defined in the pkg.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 9/269PL/SQL Advanced Techniques - page 97/10/2013 Copyright 2001 Steven Feuerstein
Configure Session with Init. Section
PACKAGE BODY sessinit IS/* No declared package elements at all! */
BEGIN/* Get user preferences for this user. */SELECT lov_flag, tb_flag, defprinterINTO show_lov, show_toolbar, printerFROM user_config
WHERE user_id = USER;
EXCEPTION WHEN NO_DATA_FOUNDTHEN
/* No record for this user. */show_lov := 'Y';show_toolbar := 'Y'; printer := 'lpt1';
WHEN OTHERSTHEN
RAISE_APPLICATION_ERROR (-20000,'No profile for ' || USER);
END sessinit;
PACKAGE sessinit
IS show_lov CHAR(1);show_toolbar CHAR(1);
printer VARCHAR2(60);END sessinit;
An unusual package!
– Specification containsonly variables.
– Body contains onlyinitialization section.
init.pkginit.tst
Also a package with
many design flaws...
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 10/269PL/SQL Advanced Techniques - page 107/10/2013 Copyright 2001 Steven Feuerstein
Populate Collections
The PL/Vision Date package, PLVdate, employs several
PL/SQL tables to convert strings and to perform datearithmetic. – This increases the flexibility of the date conversion process.
– The datemgr.pkg file demonstrates the basic technique (and thereliance on an initialization section) used to achieve this flexibility.
BEGINfmts(1) := 'DD-MON-RR';fmts(2) := 'DD-MON-YYYY';fmts(3) := 'DD-MON';fmts(4) := 'MM/DD';...fmts(9) := 'MM/DD/YYYY';
fmts(10) := 'MMDDYYYY';fmts(11) := 'YYYYMMDD';fmts(12) := 'RRMMDD';fmt_count := 12;
END dt;
datemgr.pkgdates.sql
Initialization sectionpopulates a
PL/SQL table.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 11/269
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 12/269
PL/SQL Advanced Techniques - page 127/10/2013 Copyright 2001 Steven Feuerstein
Overloading in PL/SQL Built-ins
PL/SQL uses overloading in many common functions.
– You just probably never gave it a thought, and took functions likeTO_CHAR and TO_DATE totally for granted.
– But Oracle couldn't offer that level of convenience withoutoverloading.
date_string := TO_CHAR (SYSDATE, 'MMDDYY');
number_string := TO_CHAR (10000);
Without overloading, you would have to deal with somethinglike this:
date_string :=TO_CHAR_FROM_DATE (SYSDATE, 'MMDDYY');
number_string :=TO_CHAR_FROM_NUMBER (10000);
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 13/269
PL/SQL Advanced Techniques - page 137/10/2013 Copyright 2001 Steven Feuerstein
How Overloading Works
For two or more modules to be overloaded, the compiler must be
able to distinguish between the two calls at compile-time. Thereare two different "compile times":
– 1. When you compile the package or block containing theoverloaded code.
– 2. When you compile programs that use the overloaded code.
Distinguishing characteristics: – The formal parameters of overloaded modules must differ in number,
order or datatype family (CHAR vs. VARCHAR2 is not different enough).
– The programs are of different types: procedure and function.
Undistinguishing characteristics:
– Functions differ only in their RETURN datatype.
– Arguments differ only in their mode (IN, OUT, IN OUT).
– Their formal parameters differ only in datatype and the datatypes are inthe same family.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 14/269
PL/SQL Advanced Techniques - page 147/10/2013 Copyright 2001 Steven Feuerstein
Examples of Invalid OverloadingsPACKAGE too_similarIS
PROCEDURE calc (reg_in IN CHAR);PROCEDURE calc (reg_in IN VARCHAR2);END too_many_cals;
PACKAGE only_returnsIS
FUNCTION func1 (val IN VARCHAR2) RETURN DATE;FUNCTION func1 (val IN VARCHAR2) RETURN VARCHAR2;
END only_returns;
PACKAGE param_modesIS
PROCEDURE proc1 (val IN VARCHAR2);PROCEDURE proc1 (val IN OUT VARCHAR2);
END param_modes;
Parameter
data typescause conflict.
Only difference
is functionRETURN type.
Only difference
is parameter mode.
too_similar.calc ('123');which one?
DBMS_OUTPUT.PUT_LINE (only_returns.func1 (v_value));which one?
param_modes.proc1 (v_value);which one?
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 15/269
PL/SQL Advanced Techniques - page 157/10/2013 Copyright 2001 Steven Feuerstein
Overload Wherever Possible
Supporting Many Data Combinations
– Apply the same action to different kinds or combinations of data. Inthis case, the overloading does not provide a single name for different activities, so much as providing different ways of requesting the same activity.
– The DBMS_OUTPUT.PUT_LINE procedure illustrates this technique --and the PL/Vision p.l substitute does an even better job.
Fitting the Program to the User – To make your code as useful as possible, you may construct different
versions of the “same” program which correspond to differentpatterns of use.
Overloading by Type, not Value – A less common application of overloading. You use the type of data
and not its value to determine which of the overloaded programsshould be executed.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 16/269
PL/SQL Advanced Techniques - page 167/10/2013 Copyright 2001 Steven Feuerstein
A "Classic" Overloaded Package
PACKAGE pIS
PROCEDURE l(date_in IN DATE, mask_in IN VARCHAR2 := ‘Month DD, YYYY - HH:MI:SS PM');
PROCEDURE l (number_in IN NUMBER);
PROCEDURE l (char_in IN VARCHAR2);
PROCEDURE l (char_in IN VARCHAR2, number_in IN NUMBER);
PROCEDURE l(char_in IN VARCHAR2, date_in IN DATE,
mask_in IN VARCHAR2 := 'Month DD, YYYY - HH:MI:SS PM');
PROCEDURE l (boolean_in IN BOOLEAN);
PROCEDURE l (char_in IN VARCHAR2, boolean_in IN BOOLEAN);END p;
p.spsp.spb
Many different datatype combinations, allowing the user to pass data tothe "display engine" without writing "pre-processing" code.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 17/269
PL/SQL Advanced Techniques - page 177/10/2013 Copyright 2001 Steven Feuerstein
Advantage of Extended Overloading
p.l ('So what is different?');
p.l (print_report_fl);
p.l (SQLERRM, SQLCODE);
p.l (SYSDATE);
•Extended overloadings aremore likely to meet user needs.
DBMS_OUTPUT.PUT_LINE('So what is different?');
DBMS_OUTPUT.PUT_LINE(TO_CHAR (SYSDATE,'MM/DD/YY HH:MI:SS'));
DBMS_OUTPUT.PUT_LINE(SQLERRM || ': ' ||TO_CHAR (SQLCODE));
IF print_report_flTHEN
DBMS_OUTPUT.PUT_LINE ('TRUE');ELSE
DBMS_OUTPUT.PUT_LINE ('FALSE');END IF;
• Minimal overloading means lots of extra coding...
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 18/269
PL/SQL Advanced Techniques - page 187/10/2013 Copyright 2001 Steven Feuerstein
Fitting the Program to the User
A single piece of functionality, such as "display data" or "createa file", can be applied or needed under very differentcircumstances.
If you take these different circumstances into account when youdesign your package specification, the user of your packagecan benefit from writing less code.
– Your code is a a more natural "fit" under a variety of requirements.
In my experience, few developers are considerate enough of their users to try to anticipate their needs.
– If you want to write software that is admired,appreciated...and taken com pletely for g ranted , think aboutthe way it will be used.
Writing "unnecessary" code? Time to overload!
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 19/269
PL/SQL Advanced Techniques - page 197/10/2013 Copyright 2001 Steven Feuerstein
Creating a File for a Quick Touch
Suppose a developer needs to create a file to be used as a "flag" in theoperating system.
– She doesn't care what's in it. It just needs to be present .
– Here is the code required by UTL_FILE:
DECLAREfid UTL_FILE.FILE_TYPE;
BEGIN
fid := UTL_FILE.FOPEN ('tmp/flags', 'exists.flg', 'W');UTL_FILE.PUT_LINE (fid, 'blah');UTL_FILE.FCLOSE (fid);
END;
In other words, you have to declare the record to hold the file handle,even though you are simply going to close the file immediately after
opening it. Of course, sometimes you will want to create a file and then perform
additional operations, so this is just the way it has to be, right?WRONG!
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 20/269
PL/SQL Advanced Techniques - page 207/10/2013 Copyright 2001 Steven Feuerstein
Procedure and Function Overloaded
Why not overload a "create file" program so that you can pickthe one that most closely fits your situation?
Consider the PLVfile package of PL/Vision.
PACKAGE PLVfileIS
/* Procedure */ PROCEDURE fcreate(file_in IN VARCHAR2,line_in IN VARCHAR2 := NULL);
/* Function */ FUNCTION fcreate(file_in IN VARCHAR2,line_in IN VARCHAR2 := NULL)
RETURN UTL_FILE.FILE_TYPE;
END PLVfile;
Overloading of FCreate
DECLAREfid UTL_FILE.FILE_TYPE;
BEGINfid := PLVfile.fcreate
('temp.ini', v_user);PLVfile.put_line
(fid, TO_CHAR (SYSDATE));
Use as Function
BEGINPLVfile.fcreate ('exists.flg');
END;
Use as Procedure
custrules.pkg
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 21/269
PL/SQL Advanced Techniques - page 217/10/2013 Copyright 2001 Steven Feuerstein
"By-Type" Overloading
In some situations, the user does not need to pass data,
but the type o f data. – For example, when you use DBMS_SQL to set up a dynamic
query, you must call the DEFINE_COLUMN procedure to definethe datatype of the Nth column in the cursor.
There are three ways to accomplish this:
– Don't overload. Define a different program name for eachdatatype.
– Pass a string “name” of the datatype.
– Pass a piece of data of the right type.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 22/269
PL/SQL Advanced Techniques - page 227/10/2013 Copyright 2001 Steven Feuerstein
Options for Specifying Column Type
Don't even bother overloading...
BEGINDBMS_SQL.DEFINE_INTEGER_COLUMN (cur, 1);DBMS_SQL.DEFINE_VARCHAR2_COLUMN (cur, 2, 30);
BEGINDBMS_SQL.DEFINE_COLUMN (cur, 1, 'NUMBER');DBMS_SQL.DEFINE_COLUMN (cur, 2, 'STRING', 30);
BEGINDBMS_SQL.DEFINE_COLUMN (cur, 1, DBMS_SQL.NUMBER_TYPE);DBMS_SQL.DEFINE_COLUMN (cur, 2, DBMS_SQL.VARCHAR2_TYPE, 30);
Pass a named constant...
Pass a literal value...
Now let's look at two examples of overloading by datatype...
– DBMS_SQL.DEFINE_COLUMN
– PLVgen.func
So many programnames to remember!
Nastyhard-coding...
Lotsa typing,lotsa names...
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 23/269
PL/SQL Advanced Techniques - page 237/10/2013 Copyright 2001 Steven Feuerstein
Defining Dynamic SQL Columns
The DBMS_SQL.DEFINE_COLUMN procedure defines the
datatype of a column. – To make it easier to accomplish this task, you only need to pass avalue -- any value -- of the correct type.
– The three code blocks below are equivalent, from the perspectiveof DBMS_SQL.DEFINE_COLUMN.
BEGINDBMS_SQL.DEFINE_COLUMN (cur, 1, 1);DBMS_SQL.DEFINE_COLUMN (cur, 2, 'a', 30);
BEGINDBMS_SQL.DEFINE_COLUMN (cur, 1, DBMS_UTILITY.GET_TIME);DBMS_SQL.DEFINE_COLUMN (cur, 2, USER, 30);
BEGINDBMS_SQL.DEFINE_COLUMN (cur, 1, v_empno);DBMS_SQL.DEFINE_COLUMN (cur, 2, v_ename, 30);
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 24/269
PL/SQL Advanced Techniques - page 247/10/2013 Copyright 2001 Steven Feuerstein
Generating Functions by Value
In PLVgen, the user indicates the type of function to be generatedby providing a value .
– The particular value itself is of no impor tance. Any number, anydate, any string, any Boolean will do.
PACKAGE PLVgenIS
PROCEDURE func (name_in IN VARCHAR2, type_in IN VARCHAR2);
PROCEDURE func (name_in IN VARCHAR2, type_in IN NUMBER);
PROCEDURE func (name_in IN VARCHAR2, type_in IN DATE);
SQL> exec plvgen.func('total_salary', 1)
A number function, please!
SQL> exec plvgen.func('last_date', SYSDATE)
A date function, please!
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 25/269
PL/SQL Advanced Techniques - page 257/10/2013 Copyright 2001 Steven Feuerstein
The Frustrations of Overloading
Watch out! An overloading can compile successfully, but
you might later found out that you cannot actually cal l anyof the overloaded programs.
PACKAGE profitsIS
PROCEDURE calc (comp_id_IN IN NUMBER);
PROCEDURE calc (comp_id_IN IN company.comp_id%TYPE);END;
In the above example, I rely on an anchored type (%TYPE)
to establish the datatype of the second calc‟s parameter. – When I compile profits, PL/SQL does not sense a conflict withabove overloading even though comp_id is a numeric column.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 26/269
PL/SQL Advanced Techniques - page 267/10/2013 Copyright 2001 Steven Feuerstein
Quiz! Nuances of Overloading
Can I overload two programs which have parameters
that differ only by name , like calc_totals shown above? – If not, why not?
– If so, how would you do it? (Don't peek at the next page!)
PACKAGE salesIS
PROCEDURE calc_total (zone_in IN VARCHAR2);
PROCEDURE calc_total (reg_in IN VARCHAR2);
END sales;
BEGIN
sales.calc_total ('NORTHWEST');
sales.calc_total ('ZONE2');END;
?sales.pkg
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 27/269
PL/SQL Advanced Techniques - page 277/10/2013 Copyright 2001 Steven Feuerstein
Using Named Notation
Explicit association between the formal parameter (the"name") with the actual parameter (the "value").
Advantages of named notation include: – Code is more "self-documenting". This is especially useful when
working with infrequently used built-in programs. – You can skip over (not specify values for) any IN parameters that
have default values. That way you don't have to know and pass default values.
<formal parameter name> => <expression>
DBMS_JOB.submit (job => v_jobno,
what => 'DBMS_DDL.ANALYZE_OBJECT ' ||'(''TABLE'',''LOAD1'',''TENK''' ||',''ESTIMATE'',null,estimate_percent=>50);',
next_date => TRUNC (SYSDATE + 1),interval => 'TRUNC(SYSDATE+1)');
namednot.sql
A hi i PL/SQL E ll
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 28/269
PL/SQL Advanced Techniques - page 287/10/2013 Copyright 2001 Steven Feuerstein
PL/SQLCollections
Achieving PL/SQL Excellence
Collections are single-dimensioned lists of information.
Three types of collections: – Index-by tables (Oracle7 only, originally called PL/SQL tables)
– Nested tables (Oracle8 and above)
– Variable arrays (VARRAYs, Oracle8 and above)
Wh t U C ll ti
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 29/269
PL/SQL Advanced Techniques - page 297/10/2013 Copyright 2001 Steven Feuerstein
When to Use Collections
Maintain any kind of list of related information for use in
your programs.
Emulate bi-directional cursors, which are otherwise notsupported in PL/SQL
Cache data in session-level memory for faster access.
Build hash tables (custom indexing structures).
Improve query performance by avoiding joins.
Avoid mutating table errors in database triggers.
I d B T bl
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 30/269
PL/SQL Advanced Techniques - page 307/10/2013 Copyright 2001 Steven Feuerstein
Index-By Tables
Characteristics of an index-by table: – Unbounded
» Practically speaking. Valid row numbers range: -2,147,483,647 to 2,147,483,647
» You will not actually create tables this large. Instead, this broad range allows you toemploy the row number as an intelligent key.
– Sparse
» Data does not have to be stored in consecutive rows of information.
– Homogeneous
» Data in each row has the same structure.
– Available only in PL/SQL
TYPE <table_type> IS TABLE OF <datatype> INDEX BY BINARY_INTEGER;
DECLARETYPE inmem_emp_t IS TABLE OF emp%ROWTYPE
INDEX BY BINARY_INTEGER;emp_copy inmem_emp_t;
I d b T bl
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 31/269
PL/SQL Advanced Techniques - page 317/10/2013 Copyright 2001 Steven Feuerstein
TYPE
declaration
PACKAGE BODY family IS
TYPE child_list_type ISTABLE OF VARCHAR2 (30)INDEX BY BINARY_INTEGER;
children child_list_type;Variable
declaration
Index_by Tables
children
6412
6904 „Lisa Marie‟
„Gary Richard‟
„Barbara Anne‟ 6306
„Lisa Nadezhka‟ 6904
6810 „Adam Russell‟
6412 „Gary Richard‟
„Barbara Anne‟ 6306
children children (6810) := „Adam Russell; children (6904) := 'Lisa Nadezhka';
Component
Selection
kid := children (4);
Error:NO_DATA_FOUND
datemgr.pkg
N t d T bl
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 32/269
PL/SQL Advanced Techniques - page 327/10/2013 Copyright 2001 Steven Feuerstein
Nested Tables
Nested table characteristics – Homogeneous
» Each row contains the same structure of data.
– Unbounded, but only with explicit EXTEND requests
» Practically speaking. Valid row numbers range: 1 to 2,147,483,647
– Initially dense, but can become sparse if you DELETE inner rows – Available both in PL/SQL and SQL (as a column in a table)
– The order of elements is not preserved in the database
[CREATE OR REPLACE] TYPE <table_type> IS
TABLE OF <datatype> [NOT NULL];
DECLARETYPE when_t IS TABLE OF DATE; birthdays when_t;
Nested Tables
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 33/269
PL/SQL Advanced Techniques - page 337/10/2013 Copyright 2001 Steven Feuerstein
Lisa Marie
Gary Richard
BOND
Nested Tables
CREATE OR REPLACETYPE child_table_type IS TABLE OF VARCHAR2 (30);
CREATE TABLE db_family (surname VARCHAR2 (30),kids child_table_type)NESTED TABLE kids STORE AS kids_ntab;
BOLZ
Barbara Annedb_family
For ORACLE's use only
surname kids
Max RichardEric Thomas
ntdemo.sql
Variable Arrays
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 34/269
PL/SQL Advanced Techniques - page 347/10/2013 Copyright 2001 Steven Feuerstein
Variable Arrays
Characteristics of variable arrays:
– Homogeneous» Each row contains the same structure of data.
– Bounded
» Upper limit established when the TYPE is defined. Maximum value: 2,147,483,647
– Dense
» Never any gaps between defined rows, can be EXTENDed or TRIMmed.
– Available both in PL/SQL and SQL (as a column in a table)
» And the order of elements are preserved in the database.
– Variable arrays are actually stored in the DB table
[CREATE OR REPLACE] TYPE <table_type> IS
VARRAY (N) OF <datatype> [NOT NULL];
DECLARETYPE numbers_t IS VARRAY (10) OF NUMBER;salaries numbers_t;
Variable Arrays
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 35/269
PL/SQL Advanced Techniques - page 357/10/2013 Copyright 2001 Steven Feuerstein
Variable Arrays
vademo.sql
CREATE OR REPLACETYPE child_va_type IS VARRAY (8) OF VARCHAR2 (30);
CREATE TABLE db_family (surname VARCHAR2 (30), kids child_va_type);
BOND
1 Eric Thomas
2 Max Richard
BOLZ1 Barbara Anne2 Gary Richard3 Lisa Marie
db_family
surname kids
Defining Collections
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 36/269
PL/SQL Advanced Techniques - page 367/10/2013 Copyright 2001 Steven Feuerstein
Defining Collections
First, you define the TYPE of the collection.
– For index-by tables, this can only occur in a PL/SQL declarationsection. Best option: package specification.
– For nested tables and VARRAYs, you can define the TYPE in thedatabase with a CREATE statement, or in a PL/SQL declarationsection.
Then you declare an instance of that type, a collection, fromthe TYPE.
– You can declare multiple collections from that TYPE.
CREATE OR REPLACE PACKAGE tabtypesIS
TYPE integer_ibt IS TABLE OF INTEGER INDEX BY BINARY_INTEGER;TYPE integer_nt IS TABLE OF INTEGER;TYPE integer_vat IS VARRAY(10) OF INTEGER;...
END tabtypes;
Obtaining Collection Information
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 37/269
PL/SQL Advanced Techniques - page 377/10/2013 Copyright 2001 Steven Feuerstein
Obtaining Collection Information
ALL_COLL_TYPES – The types you have created (or have access to) in the database
ALL_TYPE_ATTRS – Attributes of the data type used in the TYPE definition.
– The code used to define the collection TYPE
There is no information in the data dictionary available for index-by tables.
colldd.sql
SELECT A.attr_name || ' - ' || A.attr_type_name AttributesFROM all_coll_types T, all_type_attrs A
WHERE T.owner = USER AND T.owner = A.owner AND T.type_name IN ('NAMES_VT', 'TMRS_VT') AND T.elem_type_name = A.type_name;
Initializing Collections
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 38/269
PL/SQL Advanced Techniques - page 387/10/2013 Copyright 2001 Steven Feuerstein
Initializing Collections
Before you can use a collection, it must be initialized.
– Index-by tables are initialized automatically, empty when declared.
– Nested tables and VARRAYs are atomically null. You must initializethem explicitly with a constructor.
DECLARETYPE numbers_t IS VARRAY (10) OF NUMBER;salaries numbers_t := numbers_t (100, 200, 300);
BEGIN
CREATE TYPE numbers_t IS VARRAY (10) OF NUMBER;/DECLARE -- Initialize the collection.
salaries numbers_t := numbers_t (100, 200, 300);BEGIN
TYPE defined inthe database
TYPE defined inPL/SQL
CREATE TABLE employee_denorm (employee_id INTEGER,salary_history numbers_t);
Collection usedin a table
Collections of Composites
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 39/269
PL/SQL Advanced Techniques - page 397/10/2013 Copyright 2001 Steven Feuerstein
Collections of Composites
Starting with Oracle 7.3, the “homogeneous” contents of anindex-by table's row can be a record .
– Can easily create an index-by table with the same structure as adatabase table by declaring a record with %ROWTYPE.
Starting with Oracle8, the datatype for any of the collection typescan also be an object.
– But you cannot have nested composite datatypes.DECLARE
TYPE comp_rectype IS RECORD(comp_id company.company_id%TYPE, total_rev NUMBER);
TYPE comp_tabtype IS TABLE OF comp_rectypeINDEX BY BINARY_INTEGER;
comp_tab comp_tabtype;BEGIN
comp_tab(1).comp_id := 1005;
Here we have a threestep process. Again,
consider puttingTYPEs in database or
packages.
Sparse is Nice
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 40/269
PL/SQL Advanced Techniques - page 407/10/2013 Copyright 2001 Steven Feuerstein
Sparse is Nice
The sparse characteristic of index-by tables and nestedtables can be put to good use. – In an index-by table, a row exists in the table only when a value is
assigned to that row. In this way, it is very similar to a database table.
Rows do not have to be defined sequentially. – You should no t fill sequentially, unless the order in which items are
selected is of importance. – Instead, consider using the row value as "smart data" for your
application (primary key, order by date, etc.).
Especially handy when caching data from relational tables inuser memory.
– In almost every case, your collections will contain a row's worth of information.
Transferring DB Table to Collection
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 41/269
PL/SQL Advanced Techniques - page 417/10/2013 Copyright 2001 Steven Feuerstein
Transferring DB Table to Collection
CREATE OR REPLACE PACKAGE psempIS
TYPE emp_tabtype ISTABLE OF emp%ROWTYPEINDEX BY BINARY_INTEGER;
emp_tab emp_tabtype;END;
This package moves the
entire contents of the emptable into its correspondingcollection.
Some questions:
– Why would I put thiscollection table in apackage?
– When is the collectionloaded with the data?
– What rows in that collection
are utilized?
CREATE OR REPLACE PACKAGE BODY psempISBEGIN
FOR rec IN (SELECT * FROM emp)LOOP
emp_tab (rec.empno) := rec;END LOOP;
END;
Initializationsection of package
psemp.pkgpsemp.tst
Collection Gotchas
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 42/269
PL/SQL Advanced Techniques - page 427/10/2013 Copyright 2001 Steven Feuerstein
Collection Gotchas
EXTEND before assigning a value to a row. – Not necessary for index-by tables, but you must do it for VARRAYs
and nested tables.
For index-by tables, you must reference existing rows or a
NO_DATA_FOUND exception is raised. – Use the EXISTS method to determine if a row existed.
– For VARRAYs and nested tables, once extended, the row exists, evenif you haven't assigned a value explicitly.
CREATE TYPE names_t IS TABLE OF VARCHAR2(30);/
DECLAREgreedy_ceos names_t := names_t ();
BEGINgreedy_ceos(1) := 'Hamilton, Jordan';
END;/
Error -6533!
You've got toEXTEND first!
Handling Collection Gotchas
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 43/269
PL/SQL Advanced Techniques - page 437/10/2013 Copyright 2001 Steven Feuerstein
Handling Collection Gotchas
You can EXTEND one or more rows. – Assign a default value with a second, optional argument.
– Pre-extending a large number of rows in advance canimprove performance.
Include a handler for NO_DATA_FOUND or use the EXISTSmethod to avoid these exceptions.
BEGIN-- Extend by 10 since I know I will need that many.
-- Set the value of each new row to the contents of the first row.salaries.EXTEND (10, salaries(salaries.FIRST));
BEGINIF salaries.EXISTS (v_employee_id)
THEN-- We are OK.ELSE
DBMS_OUTPUT.PUT_LINE ('Data for employee not available.');END IF;
preextend.tst
Collection Methods
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 44/269
PL/SQL Advanced Techniques - page 447/10/2013 Copyright 2001 Steven Feuerstein
Collection Methods
Obtain information about the collection
– COUNT returns number of rows currently defined in the table.
– EXISTS returns TRUE if the specified row is defined.
– FIRST/LAST return lowest/highest numbers of defined rows.
– NEXT/PRIOR return the closest defined row after/before the specifiedrow.
– LIMIT tells you the max. number of elements allowed in a VARRAY.
Modify the contents of the collection – DELETE deletes one or more rows from the index-by table.
– EXTEND adds rows to a nested table or VARRAY.
– TRIM removes rows from a VARRAY.
The built-in package plitblm (PL/sql Index-TaBLe Methods)defines these methods.
The DELETE Method
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 45/269
PL/SQL Advanced Techniques - page 457/10/2013 Copyright 2001 Steven Feuerstein
The DELETE Method
You can delete one or more rows from a collection usingDELETE:
BEGIN-- Delete all rows
myCollection.DELETE;
-- Delete one (the last) row myCollection.DELETE (myCollection.LAST);
-- Delete a range of rows myCollection.DELETE (1400, 17255);
END;
DELETE releases memory, but you may also want to callDBMS_SESSION.FREE_UNUSED_USER_MEMORY.
Navigating Through Collections
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 46/269
PL/SQL Advanced Techniques - page 467/10/2013 Copyright 2001 Steven Feuerstein
Navigating Through Collections
Use FIRST and NEXT to move from beginning to end.
Use LAST and PRIOR to move from end to beginning.
rowind PLS_INTEGER := birthdays.FIRST; -- birthdays.LAST
BEGINLOOP
EXIT WHEN rowind IS NULL;
DBMS_OUTPUT.PUT_LINE(birthdays(rowind).best_present);
rowind := birthdays.NEXT (rowind); -- birthdays.PRIOR
END LOOP;END;
Using Collections Inside SQL
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 47/269
PL/SQL Advanced Techniques - page 477/10/2013 Copyright 2001 Steven Feuerstein
Us g Co ect o s s de SQ
Nested tables and VARRAYs can be defined as columns of atable and referenced directly within SQL.
You can also apply SQL operations to the contents of nestedtables and VARRAYs with these operators:
– THE - Maps a single column value in a single row to a virtualdatabase table
– CAST - Maps a collection of one type to a collection of another type – MULTISET - Maps a database table to a collection
– TABLE - Maps a collection to a database table
Index-by tables are programmatic constructs only.
– You cannot make a direct reference to an index-by table in SQL. – Instead, so do indirectly with a PL/SQL function.
Using Collections inside SQL
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 48/269
PL/SQL Advanced Techniques - page 487/10/2013 Copyright 2001 Steven Feuerstein
g Q
Lisa MarieGary Richard
BOND
BOLZ
Barbara Annedb_family
surname children
Max RichardEric Thomas
Lisa Marie
Gary Richard
Barbara Anne
column_value
SELECT column_valueFROM TABLE (SELECT children FROM db_family
WHERE surname = 'BOLZ');
UPDATE TABLE(SELECT children FROM db_family WHERE SURNAME = 'BOLZ)
SET column_value = 'Lisa Nadezhka' WHERE column_value = 'Lisa Marie');
Lisa Nadezhka
Gary Richard
Barbara Anne
. . .
BOLZ
db_family
surname children
Using the THE Operator
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 49/269
PL/SQL Advanced Techniques - page 497/10/2013 Copyright 2001 Steven Feuerstein
g p
Use THE to manipulate (retrieve, INSERT, UPDATE, DELETE)contents of a nested table in a database table.
– Can only use with nested tables, not VARRAYs or index-by tables.
– Only accessible from within SQL statements in PL/SQL.
CREATE TYPE action_list_t IS TABLE OF VARCHAR2(100);/CREATE TABLE inflation_beater (
focus_area VARCHAR2(100),activities action_list_t) NESTED TABLE activities STORE AS activities_tab;
SELECT VALUE (act)FROM THE (SELECT activities FROM inflation_beater
WHERE focus_area = 'FORTUNE 100') act;
UPDATE THE (SELECT activities FROM inflation_beater WHERE focus_area = 'FORTUNE 100')
SET COLUMN_VALUE = 'DISBAND OSHA' WHERE COLUMN_VALUE = 'SIDESTEP OSHA';
the.sql
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 50/269
Using the MULTISET Operator
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 51/269
PL/SQL Advanced Techniques - page 517/10/2013 Copyright 2001 Steven Feuerstein
g p
MULTISET is the inverse of TABLE, converting a set of data(table, view, query) into a VARRAY or nested table. – Cannot use with index-by tables.
– You can use MULTISET to emulate or transform relational joins intocollections, with potential client-server performance impact.
DECLARECURSOR bird_curs IS
SELECT b.genus, b.species,CAST( MULTISET(SELECT bh.country FROM bird_habitats bh
WHERE bh.genus = b.genus AND bh.species = b.species)
AS country_tab_t)FROM birds b;
bird_row bird_curs%ROWTYPE;
BEGINOPEN bird_curs;FETCH bird_curs into bird_row;
END;multiset.sql
Retrieves all detailinformation for the
master in one trip.
Referencing IB Tables inside SQL
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 52/269
PL/SQL Advanced Techniques - page 527/10/2013 Copyright 2001 Steven Feuerstein
CREATE OR REPLACE PACKAGE ibtab ISFUNCTION rowval (indx IN PLS_INTEGER) RETURN DATE;
PRAGMA RESTRICT_REFERENCES (rowval, WNPS, WNDS);END;
CREATE OR REPLACE PACKAGE BODY ibtab ISTYPE date_tab IS TABLE OF DATE INDEX BY BINARY_INTEGER;hiredates date_tab;
FUNCTION rowval (indx IN PLS_INTEGER) RETURN DATEIS BEGIN
RETURN hiredates (indx);END;
END;
g
You can't directly reference an index-by table's contentsinside SQL.
Instead, call functions that retrieve the table's data, but hidethe index-by table structure.
ibtab_in_sql.sql
Make accessiblein SQL for
Oracle8 andbelow.
Examples of Collections in Action
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 53/269
PL/SQL Advanced Techniques - page 537/10/2013 Copyright 2001 Steven Feuerstein
Emulation of bi-directional cursor operations
Avoid mutating table problems in databasetriggers.
Bi-Directional Cursor Emulation
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 54/269
PL/SQL Advanced Techniques - page 547/10/2013 Copyright 2001 Steven Feuerstein
CREATE OR REPLACE PACKAGE bidirIS
/* Iterate through rows in the result set */PROCEDURE setRow (nth IN PLS_INTEGER);FUNCTION getRow RETURN employee_plus%ROWTYPE;PROCEDURE nextRow;PROCEDURE prevRow;
END;
Oracle does not yet support the ability to move back andforth (and at random) through a cursor's result set.
– A talked-about feature for Oracle9i -- nope, didn't make it!
Instead, deposit your data in a collection and then provideprograms to access that data in the necessary fashion.
This is particularly useful (read: efficient) when you need to
perform multiple passes against the data.
bidir.pkgbidir.tst
Notice that thecollection itself is
hidden.
The Mutating Table Problem
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 55/269
PL/SQL Advanced Techniques - page 557/10/2013 Copyright 2001 Steven Feuerstein
Row level triggers cannot query from or change the contents of the table to whichit is attached; it is "mutating".
So what are you supposed to do when arow-level operation needs to "touch" thattable?
UPDATE row 1
UPDATE row N
UPDATE emp SET sal = 1000Statement Level
Row Level
Database triggers can be attached to the SQL statementand/or the individual row operations on a table.
Note: in Oracle8i, youcan use autonomoustransactions to relax
restrictionsassociated withqueries.
mutating.sql
A Solution Based on Index-by Tables
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 56/269
PL/SQL Advanced Techniques - page 567/10/2013 Copyright 2001 Steven Feuerstein
Since you cannot perform the processing desired in therow-level trigger, you need to defer the action until you get
to the statement level.
If you are going to defer the work, you have to remember what you needed to do. – an index-by table is an ideal repository for this reminder list.
1st row trigger fires
Nth row trigger fires
Work List(PL/SQL Table)
Statement Trigger
Writes to list
Writes to list
Process datain the list.
An Example: Ranking Salespeople
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 57/269
PL/SQL Advanced Techniques - page 577/10/2013 Copyright 2001 Steven Feuerstein
A table holds the rankings based on the amount of annualsales of salespeople within a department.
– As the sales amount is updated in this table, the rankings must alsochange to show the new standings for that department only.
Salesperson ID Sales Amount RankDepartment ID
1055 64333 74055.88 3
1055 65709 144533.911055 65706 109000.25
1047 70904 65011.25
12
6
"Deferred work" is not only necessary, but preferable.
– By storing the salesperson‟s department ids as they change, wethen know which departments to re-rank.
– We might update more than one department within a statement sowe must be able to retain multiple department numbers.
Trigger Logic Required
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 58/269
PL/SQL Advanced Techniques - page 587/10/2013 Copyright 2001 Steven Feuerstein
CREATE OR REPLACE TRIGGER Rank_Sales_Strg AFTER INSERT OR UPDATE OR DELETEON rank_sales
BEGINrank.rank_depts; END;
Statement Level Trigger
All details of theranking are hidden
in the package body.
CREATE OR REPLACE TRIGGER Rank_Sales_Rtrg AFTER insert OR update OF sales_amtON rank_sales FOR EACH ROW
WHEN (OLD.sales_amt != NEW.sales_amt)BEGIN
rank.add_dept (:new.dept_id); END;
Row Level Trigger Doesn't fire unless
the sales_amtis actually changed.
ranking.pkg
The Ranking Package
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 59/269
PL/SQL Advanced Techniques - page 597/10/2013 Copyright 2001 Steven Feuerstein
PACKAGE rankIS
PROCEDURE add_dept (dept_id_in IN INTEGER);
PROCEDURE rank_depts;END rank;
PACKAGE BODY rankIS
in_process BOOLEAN := FALSE;
TYPE dept_tabtype IS TABLE OF BOOLEAN INDEX BY BINARY_INTEGER;dept_tab dept_tabtype;
PROCEDURE add_dept (dept_id_in IN INTEGER) ISBEGIN
IF NOT in_process
THENdept_tab (dept_id_in) := TRUE;
END IF;END add_dept
Table holds indicator that departmentneeds re-ranking.
Create row to indicatedepartment to be ranked.
The Ranking Package, Continued
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 60/269
PL/SQL Advanced Techniques - page 607/10/2013 Copyright 2001 Steven Feuerstein
PROCEDURE rank_deptsIS
v_deptid PLS_INTEGER := dept_tab.FIRST;BEGIN
IF NOT in_processTHEN
in_process := TRUE;LOOP
EXIT WHEN v_deptid IS NULL; perform_ranking (v_deptid);v_deptid := dept_tab.NEXT (v_deptid);
END LOOP;END IF;
in_process := FALSE;
dept_tab.DELETE;END rank_dept;
END rank;
Avoid recursiveexecution of logic
Row number isdepartment number.
Clean up for next time.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 61/269
Tips for Using Collections
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 62/269
PL/SQL Advanced Techniques - page 627/10/2013 Copyright 2001 Steven Feuerstein
Wrap access to your collections.
– In many cases, you will want to avoid direct access to (assigning
and retrieving) rows in your collections. – This will give you the flexibility to change your implementation.
– You can also hide complex rules for setting the row number.
Get creative!
– Don't always fill and use the index-by table sequentially. – If you can somehow translate your application data to an integer, it
can be used as a row number, and therefore offers indexed access.
– Julian date formats and DBMS_UTILITY.GET_HASH_VALUE offer two different methods.
Achieving PL/SQL Excellence
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 63/269
PL/SQL Advanced Techniques - page 637/10/2013 Copyright 2001 Steven Feuerstein
Cursor Variables
Architecture of Cursor Variables
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 64/269
PL/SQL Advanced Techniques - page 647/10/2013 Copyright 2001 Steven Feuerstein
ResultSet
Result
Set
A cursor variable points to an underlying cursor o bject in thedatabase. – The cursor object in turns points to (and keeps its place in) a result set.
The cursor variable can be passed between programs (evenbetween, say, a Java servlet and a PL/SQL stored procedure). – Static SQL only -- until Oracle8i.
Cursor Object
Cursor Variable
Hard-CodedCursor
Cursor Variable
PGA
SharedGlobal
Area
With Hard-Coded Cursors With Cursor Variables
Benefits of Cursor Variables
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 65/269
PL/SQL Advanced Techniques - page 657/10/2013 Copyright 2001 Steven Feuerstein
Share cursor management between programs, even acrossthe client-server divide. – You don't have to pass the result sets of a cursor in order to allow
the client-side program to have direct access to the data in theresult set.
– Oracle Developer 2.1 utilizes cursor variables when you choose toconstruct a "base table block" around stored procedures instead of
a database table.
Share the same code across multiple, different queries. – Since the cursor name is no longer hard-coded, you can use a
single block of code (say, a reporting program) against differentqueries.
– We will try out this technique at the end of the section.
Cursor Variable Example
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 66/269
PL/SQL Advanced Techniques - page 667/10/2013 Copyright 2001 Steven Feuerstein
DECLARETYPE company_curtypeIS
REF CURSOR RETURN company%ROWTYPE;
company_curvar company_curtype;
company_rec company_curvar%ROWTYPE;
BEGIN
OPEN company_curvar FORSELECT * FROM company;
FETCH company_curvar INTO company_rec;
CLOSE company_curvar;END;
Declare a variablecursor TYPE.
Declare cursor variablebased on that type.
Declare a recordfrom cursor variable.
OPEN cursor variable,specifying the query.
FETCH from thecursor variable.
Close thecursor variable.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 67/269
Declaring Cursor Types and Variables
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 68/269
PL/SQL Advanced Techniques - page 687/10/2013 Copyright 2001 Steven Feuerstein
Cursors are declared in two steps, just like programmer-defined records and PL/SQL tables.
– 1. Define a cursor TYPE -- either "weak" or "strong".
– 2. Define a cursor variable.
DECLARE
TYPE weak_curtype IS REF CURSOR;
TYPE comp_curtype IS REF CURSOR RETURN company%ROWTYPE;
curcmp_new comp_curtype;
cur_any weak_curtype;BEGIN
Declare a WEAKreferenced cursor TYPE.
Declare a STRONGreferenced cursor TYPE.
Declare cursor variablesfrom the TYPEs.
Strong vs. Weak Cursor Types
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 69/269
PL/SQL Advanced Techniques - page 697/10/2013 Copyright 2001 Steven Feuerstein
A st rong (or constrained) cursor type has a definedreturn data specification.
– Can only reference cursor objects which return the same dataspecification, which can be any single SQL datatype or anypreviously defined record structure.
– Datatype mismatches are identified at compile time.
TYPE cur_typ_name IS REF CURSOR [ RETURN return_type ];
TYPE cur_typ_name IS REF CURSOR RETURN emp%ROWTYPE; /* Strong */
TYPE cur_typ_name IS REF CURSOR; /* Weak */
The weak (or unconstrained) cursor type does no t havea RETURN clause. – It can reference any cursor object, be opened FOR any query.
– Datatype mismatches can on ly be identified at runtime.
Opening with the Cursor Variable
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 70/269
PL/SQL Advanced Techniques - page 707/10/2013 Copyright 2001 Steven Feuerstein
When you open a cursor variable (whether of the weakor strong variety), you must provide the SQL query thatidentifies the result set. – If the variable has not yet been assigned to cursor object, the
OPEN FOR statement implicitly creates an object for thevariable.
– If the variable is already pointing to a cursor object, the OPENFOR reuses the existing object and attaches the new query tothat cursor object.
Remember, the cursor object is nothing more than a
memory location. – It is maintained independently of the query itself.
OPEN cursor_name FOR select_statement;
Opening with Strong Cursor Types
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 71/269
PL/SQL Advanced Techniques - page 717/10/2013 Copyright 2001 Steven Feuerstein
STRONG cursor data specifications must match or becompatible with the structure of the SELECT statement. – You can establish the return type based on a database table, a
cursor or a programmer-defined record.
DECLARE
TYPE emp_curtype IS REF CURSOR RETURN emp%ROWTYPE;
emp_curvar emp_curtype;
BEGINOPEN emp_curvar FOR SELECT * from emp;...
END;
Match Needed
Opening with Weak Cursor Types
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 72/269
PL/SQL Advanced Techniques - page 727/10/2013 Copyright 2001 Steven Feuerstein
A weak cursor TYPE doesn't define the RETURN structure; you canassociate any SELECT statement with a weak cursor variable.
FUNCTION open_emp_or_dept (get_type_in IN VARCHAR2)RETURN pkg.cv_type
ISretval pkg.cv_type;
BEGINIF get_type_in = ‘EMP’
THENOPEN retval FOR SELECT * FROM emp;
ELSIF get_type_in = ‘DEPT’ THEN
OPEN retval FOR SELECT * FROM dept; END IF;RETURN retval;
END;
PACKAGE pkg ISTYPE cv_type IS REF CURSOR;
END;
Either query will "do".Verification will takeplace at the FETCH.
REF TYPE placed inpackage so that it
is "globally" available.
Fetching from the Cursor Variable
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 73/269
PL/SQL Advanced Techniques - page 737/10/2013 Copyright 2001 Steven Feuerstein
Fetching with cursor variables follows the same rules asthose with static cursors.
The INTO structure must match in number and datatype to:
– FOR STRONG cursor types, it match the cursor type dataspecification.
– FOR WEAK cursor types, it match the OPEN FOR statementstructure.
Compatibility checks are performed prior to fetching row. – The ROWTYPE_MISMATCH exception is raised on failure.
– Fetching can continue with a different INTO clause.
FETCH cursor_var_name INTO record_name;FETCH cursor_var_name INTO var_name, var_name, ...;
mismatch.sql
When to Use Cursor Variables
M k it i f lli ( i ll PL/SQL
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 74/269
PL/SQL Advanced Techniques - page 747/10/2013 Copyright 2001 Steven Feuerstein
Make it easier for calling programs (especially non-PL/SQLprograms) to manipulate result sets.
– JDBC recognizes cursor variables.
Define a base table block in Forms Builder (formerly OracleForms) on stored procedures rather than a table directly.
Use a single block of code to manipulate multiple queries. – With explicit cursors, you have to repeat the code for each cursor,
since cursor names are "hard coded".
– You cou ld use dynamic SQL to achieve this effect, but static cursorsare more efficient than dynamic SQL and cursor variables are lesscomplicated than DBMS_SQL.
hccursor.sql
Consolidating Different Cursors The following package specification hides the SQL behind a single open
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 75/269
PL/SQL Advanced Techniques - page 757/10/2013 Copyright 2001 Steven Feuerstein
The following package specification hides the SQL behind a single openfunction. – It also creates the data structures you will need to call the function.
CREATE OR REPLACE PACKAGE allcursIS
bydept CONSTANT INTEGER := 1; bysal CONSTANT INTEGER := 2;
TYPE int_rt IS RECORD (key INTEGER);
TYPE cv_t IS REF CURSOR RETURN int_rt;
FUNCTION open (type_in IN INTEGER) RETURN cv_t;END;/
allcurrs.pkgallcurs.tstexplcv.sql
Consolidating Different Cursors
The open function simply opens FOR a different SELECT based on the
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 76/269
PL/SQL Advanced Techniques - page 767/10/2013 Copyright 2001 Steven Feuerstein
The open function simply opens FOR a different SELECT based on thecriteria passed to it.
CREATE OR REPLACE PACKAGE BODY allcursIS
FUNCTION open (type_in IN INTEGER) RETURN cv_tIS
retval cv_t;BEGIN
IF type_in = bydeptTHEN
OPEN retval FOR SELECT empno FROM emp ORDER BY deptno;ELSIF type_in = bysalTHEN
OPEN retval FOR SELECT empno FROM emp ORDER BY SAL;END IF;
RETURN retval;END;
END;/
Hiding SQL Variations in Resulting Code The following block demonstrates that you can alter which SQL
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 77/269
PL/SQL Advanced Techniques - page 777/10/2013 Copyright 2001 Steven Feuerstein
The following block demonstrates that you can alter which SQLstatement to query -- in this case, change the ORDER BY clause --without having to change the code you write.
DECLAREcv allcurs.cv_t;v_empno emp.empno%TYPE;
BEGIN
cv := allcurs.open (&1);
LOOPFETCH cv INTO v_empno;EXIT WHEN cv%NOTFOUND; p.l (v_empno);
END LOOP;
CLOSE cv;END;/
"Report processor"is independent of
the particular SELECT
Cursor Variables
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 78/269
PL/SQL Advanced Techniques - page 787/10/2013 Copyright 2001 Steven Feuerstein
Flexibility
– Choose which static SQL statement is executed at run-time.
Strong and Weak Types
– Create REF CURSORs for specific queries, or a more general,unconstrained type.
Hide Variations in Underlying SQL – You no longer have to repeat the same code for different cursors.
Improve Client-Side Access to Data – At least in Oracle Developer 2.1, you can build screens that access
data using a cursor variable-based procedural API.
Let's
summarize
Achieving PL/SQL Excellence
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 79/269
PL/SQL Advanced Techniques - page 797/10/2013 Copyright 2001 Steven Feuerstein
Dynamic SQL and dynamic PL/SQL:
– The DBMS_SQL package
– Native dynamic SQL in Oracle8i
Dynamic SQL
Dynamic SQL and PL/SQL Execution
"D i SQL" th t t t th SQL t t t
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 80/269
PL/SQL Advanced Techniques - page 807/10/2013 Copyright 2001 Steven Feuerstein
"Dynamic SQL" mean that you construct the SQL statementor PL/SQL block at runtime and then execute it. – Available in PL/SQL since Release 2.1 and DBMS_SQL.
– Also supported with "native dynamic SQL" in Oracle8i.
What can you do with Dynamic SQL?
Build ad-hoc query and update applications. – Very common requirement on the Web.
Execute DDL inside PL/SQL programs. – Construct powerful DBA utilities; you no longer have to write SQL
to generate SQL to get your job done.
Execute dynamically-constructed PL/SQL programs.
– One example: implement indirect referencing in PL/SQL.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 81/269
Native Dynamic SQL
Prior to Oracle8i you would use the DBMS SQL built-in
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 82/269
PL/SQL Advanced Techniques - page 827/10/2013 Copyright 2001 Steven Feuerstein
Prior to Oracle8i, you would use the DBMS_SQL built-inpackage to execute dynamic SQL.
– But this package is very complex, difficult to use, and relatively slow(performance did improve significantly as of Oracle8).
The new "native dynamic SQL" or NDS of Oracle8i offerstwo native statements in the PL/SQL language to implementmost of your dynamic SQL requirements: – EXECUTE IMMEDIATE <sql string>, used for DDL, DML and single
row fetches.
– OPEN FOR <sql string>, used for multi-row queries.
EXECUTE IMMEDIATE
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 83/269
PL/SQL Advanced Techniques - page 837/10/2013 Copyright 2001 Steven Feuerstein
Use this statement to execute any dynamic SQL statement(including a PL/SQL block) except for multi-row queries.
The INTO clause allows you to pass values from the selectlist of a single row query into local variables, includingobjects, collections and records.
The USING clause allows you to specify bind arguments or variables to be passed into the SQL string before execution.
EXECUTE IMMEDIATE sql-string
[INTO {define_variable[, define_variables]... | record }]
[USING {IN | OUT | IN OUT] bind argument[, {IN | OUT | IN OUT] bind argument]...];
COUNT(*) For Any Table
Here's a handy and simple utility based on NDS:
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 84/269
PL/SQL Advanced Techniques - page 847/10/2013 Copyright 2001 Steven Feuerstein
Here s a handy and simple utility based on NDS:
IF tabCount ('citizens', 'insured = ''NO''') > 40,000,000THEN
DBMS_OUTPUT.PUT_LINE ('Not the best health care system in the world...and not much of a democracy either!');
END IF;
tabcount81.sf compare with:
tabcount.sf
CREATE OR REPLACE FUNCTION tabCount (tab IN VARCHAR2, whr IN VARCHAR2 := NULL, sch IN VARCHAR2 := NULL)RETURN INTEGER
ISretval INTEGER;
BEGINEXECUTE IMMEDIATE
'SELECT COUNT(*) FROM ' || NVL (sch, USER) ||'.' || tab || ' WHERE ' || NVL (whr, '1=1')
INTO retval;RETURN retval;
END;
Specify schema, table andWHERE clause...
Other Execute Immediate Examples
Perform an update...
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 85/269
PL/SQL Advanced Techniques - page 857/10/2013 Copyright 2001 Steven Feuerstein
pCREATE OR REPLACE PROCEDURE updnumval (
tab_in IN VARCHAR2, col_in IN VARCHAR2,
start_in IN DATE, end_in IN DATE,val_in IN NUMBER) IS
BEGINEXECUTE IMMEDIATE
'UPDATE ' || tab_in ||' SET ' || col_in || ' = :val
WHERE hiredate BETWEEN :lodate AND :hidate'USING val_in, start_in, end_in;
END;
Pass in bindvariables withUSING clause.
Execute a stored procedure...
PROCEDURE runprog (pkg_in IN VARCHAR2, name_in IN VARCHAR2) ISv_str VARCHAR2 (100);
BEGINv_str := 'BEGIN ' || pkg_in || '.' || name_in || '; END;';EXECUTE IMMEDIATE v_str;
EXCEPTION WHEN OTHERS THEN
pl ('Compile Error "' || SQLERRM || '" on: ' || v_str); END;
Using Objects and Collections in NDS
One of the key advantages to NDS over DBMS_SQL is that it
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 86/269
PL/SQL Advanced Techniques - page 867/10/2013 Copyright 2001 Steven Feuerstein
PROCEDURE add_profit_source (hosp_name IN VARCHAR2, pers IN Person,cond IN preexisting_conditions)
ISBEGIN
EXECUTE IMMEDIATE'INSERT INTO ' || tabname (hosp_name) ||
' VALUES (:revenue_generator, :revenue_inhibitors)'USING pers, cond;
END;
y g _works with Oracle8 datatypes, including objects and
collections. – No special syntax needed...
– In the following example, the USING clause allows me to pass anobject and nested table to an INSERT statement with a variable tablename.
health$.pkg
Multiple Row Queries and NDS
Oracle extends the cursor variable feature of Oracle7 to
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 87/269
PL/SQL Advanced Techniques - page 877/10/2013 Copyright 2001 Steven Feuerstein
support multi-row dynamic queries.
– Here is a simple utility the displays the values of any date, number or string column in any table.
CREATE OR REPLACE PROCEDURE showcol (tab IN VARCHAR2, col IN VARCHAR2, whr IN VARCHAR2 := NULL)
ISTYPE cv_type IS REF CURSOR;
cv cv_type;val VARCHAR2(32767);
BEGINOPEN cv FOR 'SELECT ' || col || ' FROM ' || tab ||
' WHERE ' || NVL (whr, '1 = 1');LOOP
FETCH cv INTO val;
EXIT WHEN cv%NOTFOUND;DBMS_OUTPUT.PUT_LINE (val);
END LOOP;CLOSE cv;
END;showcol.spndsutil.pkg
Familiar cursor
variable syntax!
Some Fine Print for NDS
You cannot pass schema elements (table names, column
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 88/269
PL/SQL Advanced Techniques - page 887/10/2013 Copyright 2001 Steven Feuerstein
p ( ,names, etc.) through the USING clause.
You cannot pass the NULL literal directly in the USINGclause. Instead, pass a variable with a NULL value.
The USING clause for a query can only have IN bindarguments.
You can have duplicate placeholders (for bind arguments). – If dynamic SQL, then you provide a value for each placeholder (by
position).
– If dynamic PL/SQL, provide a value for each distinct placeholder (by
name).
str2list.pkg
Dynamic SQL using DBMS_SQL
Prior to Oracle8i, the only way to perform dynamic SQL was
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 89/269
PL/SQL Advanced Techniques - page 897/10/2013 Copyright 2001 Steven Feuerstein
y y p ywith the DBMS_SQL package.
DBMS_SQL is a very large and complex package, with manyrules to follow and lots of code to write.
Supports all four methods of dynamic SQL, in particular method 4.
The overhead for using DBMS_SQL has decreasedsignificantly in Oracle8 and again in Oracle8i.
You should only use DBMS_SQL when you cannot use NDS.
Learning Through Examples
DDL
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 90/269
PL/SQL Advanced Techniques - page 907/10/2013 Copyright 2001 Steven Feuerstein
– Create an index from within PL/SQL
DML – Update rows in a table
DML with binding – Update rows using bind variables
Queries – Method 3 and a dynamic WHERE clause
PL/SQL Version of "SELECT *" – Example of Method 4
PL/SQL – Create a generic calculation program
DDL with Dynamic SQL
PROCEDURE create_index
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 91/269
PL/SQL Advanced Techniques - page 917/10/2013 Copyright 2001 Steven Feuerstein
Creates an index on any column(s) in any table inyour schema. – Open a cursor, which will be used to execute the DDL
statement.
– Construct the DDL statement as a string.
– Parse and execute that DDL statement.
_(index_in IN VARCHAR2, tab_in IN VARCHAR2, col_in IN VARCHAR2)
IS
cur INTEGER := DBMS_SQL.OPEN_CURSOR;fdbk INTEGER;DDL_statement VARCHAR2(200)
:= 'CREATE INDEX ' || index_in || ' ON ' || tab_in ||' ( ' || col_in || ')';
BEGINDBMS_SQL.PARSE (cur, DDL_statement, DBMS_SQL.NATIVE);
fdbk := DBMS_SQL.EXECUTE (cur);DBMS_SQL.CLOSE_CURSOR (cur);
END;
creind.sp
Updates with Dynamic SQL
Update numeric column for specified employees.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 92/269
PL/SQL Advanced Techniques - page 927/10/2013 Copyright 2001 Steven Feuerstein
CREATE OR REPLACE PROCEDURE updnumval (
col_in IN VARCHAR2,ename_in IN emp.ename%TYPE,val_in IN NUMBER)
IScur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;fdbk PLS_INTEGER;
BEGINDBMS_SQL.PARSE (cur,
'UPDATE emp SET ' || col_in || ' = ' || val_in ||' WHERE ename LIKE UPPER (''' || ename_in || ''')',DBMS_SQL.NATIVE);
fdbk := DBMS_SQL.EXECUTE (cur);
DBMS_OUTPUT.PUT_LINE ('Rows updated: ' || TO_CHAR (fdbk));
DBMS_SQL.CLOSE_CURSOR (cur);END;
updnval1.sp
Updates with Bind Variables Update salaries for date range using binding.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 93/269
PL/SQL Advanced Techniques - page 937/10/2013 Copyright 2001 Steven Feuerstein
CREATE OR REPLACE PROCEDURE updnumval (col_in IN VARCHAR2,start_in IN DATE, end_in IN DATE, val_in IN NUMBER)
IScur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;fdbk PLS_INTEGER;
BEGINDBMS_SQL.PARSE (cur, 'UPDATE emp SET ' ||
col_in || ' = ' || val_in ||' WHERE hiredate BETWEEN :lodate AND :hidate',DBMS_SQL.NATIVE);
DBMS_SQL.BIND_VARIABLE (cur, 'lodate', start_in);DBMS_SQL.BIND_VARIABLE (cur, 'hidate', end_in);
fdbk := DBMS_SQL.EXECUTE (cur);
DBMS_OUTPUT.PUT_LINE ('Rows updated: ' || TO_CHAR (fdbk));DBMS_SQL.CLOSE_CURSOR (cur);
END;
updnval2.spupdnval3.sp
Processing Flow for a Dynamic Query
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 94/269
PL/SQL Advanced Techniques - page 947/10/2013 Copyright 2001 Steven Feuerstein
Make sure SELECT iswell formed(PARSE)
Bind any variables(BIND_VARIABLE)(BIND_ARRAY)
Give cursor structure(DEFINE_COLUMN)(DEFINE_ARRAY)
Fill buffer with data(FETCH_ROWS)(EXECUTE_AND_FETCH)
Retrieve the data(COLUMN_VALUE)
Fill cursor with data(EXECUTE)
Release cursor memory(CLOSE_CURSOR)
Allocate cursor memory(OPEN_CURSOR)
Queries with Dynamic SQL Show employees using a dynamic WHERE clause...
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 95/269
PL/SQL Advanced Techniques - page 957/10/2013 Copyright 2001 Steven Feuerstein
CREATE OR REPLACE PROCEDURE showemps (where_in IN VARCHAR2 := NULL)IS
cur INTEGER := DBMS_SQL.OPEN_CURSOR;rec emp%ROWTYPE; fdbk INTEGER;
BEGINDBMS_SQL.PARSE (cur, 'SELECT empno, ename FROM emp ' ||
' WHERE ' || NVL (where_in, '1=1'), DBMS_SQL.NATIVE);
DBMS_SQL.DEFINE_COLUMN (cur, 1, 1);
DBMS_SQL.DEFINE_COLUMN (cur, 2, 'a', 60);
fdbk := DBMS_SQL.EXECUTE (cur);LOOP
EXIT WHEN DBMS_SQL.FETCH_ROWS (cur) = 0;DBMS_SQL.COLUMN_VALUE (cur, 1, rec.empno);DBMS_SQL.COLUMN_VALUE (cur, 2, rec.ename);
DBMS_OUTPUT.PUT_LINE (TO_CHAR (rec.empno) || '=' || rec.ename);END LOOP;
DBMS_SQL.CLOSE_CURSOR (cur);END;
showemps.spshowemp2.spshowemps.tst
Dynamic SELECT * FROM Any Table Method 4 example: the number of columns queried changes with each
table.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 96/269
PL/SQL Advanced Techniques - page 967/10/2013 Copyright 2001 Steven Feuerstein
– The resulting code is much more complicated.
BEGINFOR each-column-in-table LOOP
add-column-to-select-list;END LOOP;
DBMS_SQL.PARSE (cur, select_string, DBMS_SQL.NATIVE);
FOR each-column-in-table LOOPDBMS_SQL.DEFINE_COLUMN (cur, nth_col, datatype);
END LOOP;
LOOPfetch-a-row;
FOR each-column-in-table LOOPDBMS_SQL.COLUMN_VALUE (cur, nth_col, val);END LOOP;
END LOOP;END;
intab.sp
Very simplified
pseudo-code
Using EXECUTE_AND_FETCH
FUNCTION execute_and_fetch(cursor in IN INTEGER
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 97/269
PL/SQL Advanced Techniques - page 977/10/2013 Copyright 2001 Steven Feuerstein
Makes it easy to execute and fetch a single row from aquery. – Very similar to the implicit SELECT cursor in native PL/SQL, which returns a
single row, raises NO_DATA_FOUND or raises the TOO_MANY_ROWSexception.
– If exact_match is TRUE, then EXECUTE_AND_FETCH will raise the
TOO_MANY_ROWS exception if more than one row is fetched by theSELECT.
– Even if the exception is raised, the first row will still be fetched andavailable.
(cursor_in IN INTEGER,exact_match IN BOOLEAN DEFAULT FALSE)
RETURN INTEGER;
numrows := DBMS_SQL.EXECUTE_AND_FETCH (cur);
numrows := DBMS_SQL.EXECUTE_AND_FETCH (cur, TRUE);
Dynamic Formula Execution Suppose I am building a user interface that allows a user to
select a formula for execution and enter the arguments
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 98/269
PL/SQL Advanced Techniques - page 987/10/2013 Copyright 2001 Steven Feuerstein
select a formula for execution, and enter the arguments. – Using static PL/SQL, I would have to modify my screen every time a
new formula was added. – With DBMS_SQL, a single function will do the trick.
FUNCTION dyncalc (oper_in IN VARCHAR2,nargs_in IN INTEGER := 0,arg1_in IN VARCHAR2 := NULL, arg2_in IN VARCHAR2 := NULL,arg3_in IN VARCHAR2 := NULL, arg4_in IN VARCHAR2 := NULL,arg5_in IN VARCHAR2 := NULL, arg6_in IN VARCHAR2 := NULL,arg7_in IN VARCHAR2 := NULL, arg8_in IN VARCHAR2 := NULL,arg9_in IN VARCHAR2 := NULL, arg10_in IN VARCHAR2 := NULL)RETURN VARCHAR2;
dyncalc.sf dyncalc.pkg
More on Dynamic PL/SQLBEGIN
cur := open_and_parse
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 99/269
PL/SQL Advanced Techniques - page 997/10/2013 Copyright 2001 Steven Feuerstein
Use BIND_VARIABLE to bind any placeholders in the string -- evenOUT arguments which are not being bound to any values.
Use VARIABLE_VALUE to extract a value from any variable you havebound.
You must have a BEGIN-END around the code.
Possibilities inherent in dynamic PL/SQL are mind-boggling!
('BEGIN get_max_sal (:deptin, :salout); END;');
DBMS_SQL.BIND_VARIABLE (cur, ‘deptin’, v_deptin); DBMS_SQL.BIND_VARIABLE (cur, ‘salout’, my_salary);
fdbk := DBMS_SQL.EXECUTE (cur);
DBMS_SQL.VARIABLE_VALUE (cur, ‘salout’, my_salary); END;
dynplsql.sqldynplsql.spdynplsql.tst
Indirect Referencing with Dyn PL/SQL
Oracle Forms offers support for indirect referencing with theNAME IN and COPY built-ins
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 100/269
PL/SQL Advanced Techniques - page 1007/10/2013 Copyright 2001 Steven Feuerstein
NAME_IN and COPY built ins.
PL/SQL does not support indirect referencing, but you canaccomplish much of the same thing with dynamic PL/SQLexecution. Here is an example of a "PL/SQL NAME_IN":
FUNCTION valbyname (nm IN VARCHAR2) RETURN VARCHAR2 ISv_cur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;fdbk PLS_INTEGER;retval PLV.dbmaxvc2;
BEGINDBMS_SQL.PARSE (v_cur,
'BEGIN :val := ' || nm || '; END;',DBMS_SQL.NATIVE);
DBMS_SQL.BIND_VARIABLE (v_cur, 'val', 'a', 2000);fdbk := DBMS_SQL.EXECUTE (v_cur);
DBMS_SQL.VARIABLE_VALUE (v_cur, 'val', retval);DBMS_SQL.CLOSE_CURSOR (v_cur);RETURN retval;
END;
dynvar.pkgdynvar.tst
DBMS_SQL Status Built-ins The package offers a set of modules to return information about the last-
operated cursor in your session.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 101/269
PL/SQL Advanced Techniques - page 1017/10/2013 Copyright 2001 Steven Feuerstein
p y
– Call these immediately after your usage to make sure they refer to your
cursor.
IS_OPEN
– Is the cursor already open?
LAST_ERROR_POSITION
– Returns relative column position in cursor of text causing error condition. LAST_ROW_COUNT
– Returns the cumulative count of rows fetched from the cursor.
LAST_ROW_ID
– Returns the ROWID of last row processed.
LAST_SQL_FUNCTION_CODE
– Returns SQL function code of cursor.
Working with LONG Values
DBMS_SQL provides special procedures so that you canextract values from a LONG column in a table
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 102/269
PL/SQL Advanced Techniques - page 1027/10/2013 Copyright 2001 Steven Feuerstein
extract values from a LONG column in a table.
– DBMS_SQL.DEFINE_COLUMN_LONG – DBMS_SQL.COLUMN_VALUE_LONG
First, you define the column as a LONG,
Then you retrieve the column using the special
COLUMN_VALUE_LONG variant. – Transfer the LONG contents into an index-by table so that you can
transfer a value of more than 32K bytes into your PL/SQL program.
dumplong.pkgdumplong.tst
New DBMS_SQL Features
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 103/269
PL/SQL Advanced Techniques - page 1037/10/2013 Copyright 2001 Steven Feuerstein
PL/SQL8
Extensions toDBMS_SQL
New Features in DBMS_SQL
The functionality of DBMS_SQL has been
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 104/269
PL/SQL Advanced Techniques - page 1047/10/2013 Copyright 2001 Steven Feuerstein
extended in Oracle8 in several ways:
– Parse very long SQL strings
– Describe cursor columns
– Use "array processing" to perform bulk updates,inserts, deletes and fetches.
– Support for RETURNING clause to avoid unnecessaryqueries.
Describing Cursor Columns
PROCEDURE DBMS_SQL.DESCRIBE_COLUMNS(c IN INTEGER
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 105/269
PL/SQL Advanced Techniques - page 1057/10/2013 Copyright 2001 Steven Feuerstein
Before PL/SQL8, it was not possible to determinethe datatypes of the columns defined in a cursor.
– Now you can call the DBMS_SQL.DESCRIBE_COLUMNS.
Returns all of the column information in an indextable of records.
– The record TYPE is also defined in DBMS_SQL.
(c IN INTEGER,col_cnt OUT INTEGER,desc_t OUT DBMS_SQL.DESC_TAB);
Basic Steps to Describe Columns The following script shows the individual steps you will
need to perform in order to use this feature.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 106/269
PL/SQL Advanced Techniques - page 1067/10/2013 Copyright 2001 Steven Feuerstein
CREATE OR REPLACE PROCEDURE show_columnsIS
cur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;cols DBMS_SQL.DESC_TAB; ncols PLS_INTEGER;
BEGINDBMS_SQL.PARSE (cur,
'SELECT hiredate, empno FROM emp', DBMS_SQL.NATIVE);
DBMS_SQL.DESCRIBE_COLUMNS (cur, ncols, cols);
FOR colind IN 1 .. ncolsLOOP
DBMS_OUTPUT.PUT_LINE (cols(colind).col_name);
END LOOP;DBMS_SQL.CLOSE_CURSOR (cur);
END;
desccols.pkgdesccols.tstshowcols.sp
"Array Processing" in DBMS_SQL PL/SQL8 now allows you to specify the use of "arrays", i.e.,
index tables, when you perform updates, inserts, deletes
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 107/269
PL/SQL Advanced Techniques - page 1077/10/2013 Copyright 2001 Steven Feuerstein
and fetches.
Instead of providing a scalar value for an operation, youspecify an index table. DBMS_SQL then repeats your actionfor every row in the table.
It really isn't "array processing". – In actuality, DBMS_SQL is executing the specified SQL statement N
times, where N is the number of rows in the table.
This technique still, however, can offer a significantperformance boost over Oracle7 dynamic SQL.
Recommendations for Dynamic SQL Bind (vs. concatenate) whenever possible.
– Increased chance of reusing parsed SQL, and easier code to write.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 108/269
PL/SQL Advanced Techniques - page 1087/10/2013 Copyright 2001 Steven Feuerstein
– But remember: you cannot pass schema elements (table names,column names, etc.) through the USING clause.
Encapsulate statements to improve error handling. – With NDS, only possible for statements that do not need USING and
INTO clauses, though you could write variations for those as well.
– Encapsulate DBMS_SQL.PARSE so that you include the trace in that
program.
Use the Oracle8i invoker rights model whenever you want toshare your dynamic SQL programs among multipleschemas. – Otherwise that SQL will be executed under the authority
of the owner of the code, not the invoker of the code. effdsql.sqlopenprse.pkgwhichsch.sql
NDS or DBMS_SQL: Which is Best?
Dynamic SQL and PL/SQL is very useful, but DBMS_SQL ishard to use. Both implementations will still come in handy...
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 109/269
PL/SQL Advanced Techniques - page 1097/10/2013 Copyright 2001 Steven Feuerstein
p y
– If, of course, you have upgraded to Oracle8i!
Major Advantages of NDS:
– Ease of use
– Performance – Works with all SQL
datatypes (including user-defined object andcollection types)
– Fetch into records
When You'd Use DBMS_SQL:
– Method 4 Dynamic SQL
– DESCRIBE columns of cursor – SQL statements larger than 32K
– RETURNING into an array
– Reuse of parsed SQL statements
– Bulk dynamic SQL
– Available from client-side PL/SQL
Achieving PL/SQL Excellence
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 110/269
PL/SQL Advanced Techniques - page 1107/10/2013 Copyright 2001 Steven Feuerstein
OracleAdvanced Queuing
The high performance, asynchronous,persistent messaging subsytem of Oracle
Who Needs Messaging? Everyone!
In the distributed world of the Internet, systems are nowheavily reliant on the ability of components to communicate
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 111/269
PL/SQL Advanced Techniques - page 1117/10/2013 Copyright 2001 Steven Feuerstein
with each other in a dependable, consistent manner.
DistributionCenter
Coffee BeansProducer Retailer
Consumer
ShippingService
Applications Relying on Messaging
Stock trading system
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 112/269
PL/SQL Advanced Techniques - page 1127/10/2013 Copyright 2001 Steven Feuerstein
Airline reservation system
Auction portals
Any e-commerce application
Key Features of Oracle AQ Leverage full power of SQL
– Messages are stored in database tables
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 113/269
PL/SQL Advanced Techniques - page 1137/10/2013 Copyright 2001 Steven Feuerstein
Database high availability, scalability and reliability all carryover to queues – Strong history and retention
– Backup and recovery
– Comprehensive journaliing
Rich message content increases usefulness of queueing – Use object types to define highly structured payloads
New to Oracle8i, AQ now offers a publish/subscribe style of messaging between applications. – Rule-based subscribers, message propagation, the listen feature and
notification capabilities.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 114/269
Oracle AQ Highlights
In 8.0, AQ supports:
– Multiple queues
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 115/269
PL/SQL Advanced Techniques - page 1157/10/2013 Copyright 2001 Steven Feuerstein
p q
– Resetting order and priority of queued items – Queue management using only SQL & PL/SQL
– Multiple message recipients
– Propagation of queue to remote servers
Oracle8i adds:
– Rules-based publish & subscribe
– Listening on multiple queues
– Easier monitoring – Native Java interface
AQ Components
The DBMS_AQ package offers enqueue anddequeue capabilities
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 116/269
PL/SQL Advanced Techniques - page 1167/10/2013 Copyright 2001 Steven Feuerstein
q p
The DBMS_AQADM package providesadministrative functionality to manage queues andqueue tables.
Underlying database tables and views
The queue monitor (background process)
– Set # of processes with the AQ_TM_PROCESSESinitialization parameter.
DBMS_AQADM Highlights
CREATE_QUEUE_TABLE Assigns name, payload type, storage clause, sortcolumn, whether multiple consumers
D t bl if ll i th t bl h b
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 117/269
PL/SQL Advanced Techniques - page 1177/10/2013 Copyright 2001 Steven Feuerstein
DROP_QUEUE_TABLE Drops table if all queues in the table have beenstopped
CREATE_QUEUE Associates queue table with queue; assigns retryand retention properties to queue
DROP_QUEUE Drops a stopped queue
START_QUEUE Can also turn on/off enqueue and dequeue
operationsSTOP_QUEUE Stops queue, optionally waiting for outstanding
transactions
ADD_SUBSCRIBER Adds an “agent” as a subscriber
Creating Queue Tables and Queues
CREATE TYPE message_type AS OBJECT(title VARCHAR2(30),text VARCHAR2(2000));
Define the "payload"
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 118/269
PL/SQL Advanced Techniques - page 1187/10/2013 Copyright 2001 Steven Feuerstein
BEGIN
DBMS_AQADM.CREATE_QUEUE_TABLE(queue_table => 'msg',
queue_payload_type => 'message_type');
DBMS_AQADM.CREATE_QUEUE(queue_name => 'msgqueue',queue_table => 'msg');
DBMS_AQADM.START_QUEUE (queue_name => 'msgqueue');
END;
text VARCHAR2(2000));
/
Create the queue table
Define a queue in thequeue table
Start the queue
aq.pkg
The "operational package": DBMS_AQ DBMS_AQ is deceptively simple.
– Only two procedures, but lots of complexity buried inside theparameters of these procedures
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 119/269
PL/SQL Advanced Techniques - page 1197/10/2013 Copyright 2001 Steven Feuerstein
parameters of these procedures.
ENQUEUE puts a message into a specified queue, andreturns a RAW message handle
DEQUEUE extracts a message from a specified queue
Parameters control message properties such as: – Visibility (ON_COMMIT or IMMEDIATE)
– Priority
– Delay
– Expiration
– Locking behavior
aq.sql
Simple Enqueue Example
DECLAREqueueopts DBMS_AQ.ENQUEUE_OPTIONS_T;msgprops DBMS AQ MESSAGE PROPERTIES T;
Declare records tohold various enqueue
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 120/269
PL/SQL Advanced Techniques - page 1207/10/2013 Copyright 2001 Steven Feuerstein
msgprops DBMS_AQ.MESSAGE_PROPERTIES_T;
msgid aq.msgid_type; my_msg message_type;
BEGIN my_msg :=
message_type ('First Enqueue',
'May there be many more...');
DBMS_AQ.ENQUEUE ('msgqueue',queueopts,
msgprops, my_msg, msgid);
END;
hold various enqueueand msg properties.
Set up the payloadwith an object
constructor.
Place the message on thespecified queue and get a
msg ID in return.aqenq*.*
More Interesting Enqueue Example
DECLARE... Same setup as previous page ...
BEGINt (
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 121/269
PL/SQL Advanced Techniques - page 1217/10/2013 Copyright 2001 Steven Feuerstein
my_msg := message_type ('First Enqueue', 'May there be many more...');
msgprops.delay := 3 * 60 * 60 * 24;
DBMS_AQ.ENQUEUE ('msgqueue',queueopts, msgprops, my_msg, msgid1);
my_msg := message_type ('Second Enqueue','And this one goes first...');
queueopts.sequence_deviation := DBMS_AQ.BEFORE;queueopts.relative_msgid := msgid1;
DBMS_AQ.ENQUEUE ('msgqueue',queueopts, msgprops, my_msg, msgid2);
END;
Specify a delaybefore the payload
is available.
Modify the dequeue
sequence by changing thedeviation field and relative
msg ID.
Dequeue ExampleDECLARE
queueopts DBMS_AQ.DEQUEUE_OPTIONS_T; msgprops DBMS_AQ.MESSAGE_PROPERTIES_T;msgid aq msgid type;
Declare records tohold various dequeue
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 122/269
PL/SQL Advanced Techniques - page 1227/10/2013 Copyright 2001 Steven Feuerstein
msgid aq.msgid_type;/* defined in aq.pkg */
my_msg message_type;
PROCEDURE getmsg (mode_in IN INTEGER) ISBEGIN
queueopts.dequeue_mode := mode_in;
DBMS_AQ.DEQUEUE ('msgqueue', queueopts, msgprops, my_msg, msgid);
END;BEGIN
getmsg (DBMS_AQ.BROWSE);getmsg (DBMS_AQ.REMOVE);
getmsg (DBMS_AQ.REMOVE);END;
hold various dequeueand msg properties.
Dequeue operation
isolated in localmodule.
Demonstrates destructiveand non-destructivedequeuing.
aqdeq*.*
Prioritized Payloads You can assign priorities to individual payloads and then
dequeue according to those priorities.The lower the numeric priority value the higher the priority
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 123/269
PL/SQL Advanced Techniques - page 1237/10/2013 Copyright 2001 Steven Feuerstein
– The lower the numeric priority value, the higher the priority.
A stack implementation using AQ demonstrates this well.
PROCEDURE push (item IN VARCHAR2) ISqueueopts DBMS_AQ.ENQUEUE_OPTIONS_T;
msgprops DBMS_AQ.MESSAGE_PROPERTIES_T;
msgid aq.msgid_type;item_obj aqstk_objtype;BEGIN
item_obj := aqstk_objtype (item); msgprops.priority := g_priority;queueopts.visibility := DBMS_AQ.IMMEDIATE;g_priority := g_priority - 1;
DBMS_AQ.ENQUEUE (c_queue, queueopts, msgprops, item_obj, msgid);END;
aqstk.pkgaqstk2.pkg
priority.*
Defining Message Subscribers You can specify that a message is to be enqueued for a l ist
of subscribers.The message is then not removed from the queue until all
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 124/269
PL/SQL Advanced Techniques - page 1247/10/2013 Copyright 2001 Steven Feuerstein
– The message is then not removed from the queue until allsubscribers have dequeued the message.
Steps to working with a subscriber list: – 1. The queue table must be defined to support multiple subscribers
or consumers.
– 2. Add subscribers for the queue.
BEGINDBMS_AQADM.CREATE_QUEUE_TABLE (queue_table => 'major_qtable',queue_payload_type => 'student_major_t', multiple_consumers => TRUE);
DBMS_AQADM.ADD_SUBSCRIBER (c_queue, SYS.AQ$_AGENT (name_in, NULL, NULL)); aqmult*.*
Oracle AQ - Summary Very powerful and flexible architecture.
– Much more robust that DBMS_PIPE.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 125/269
PL/SQL Advanced Techniques - page 1257/10/2013 Copyright 2001 Steven Feuerstein
– Significant enhancements in Oracle8i, supporting apublish-subscribe model, improved security, LISTENcapability.
Considered by Oracle to be a core component of its
overall solution. – Crucial for Oracle to have a message-oriented
middleware in order to offer an all-Oracle solution.
– Should be strongly supported "down the road".
Achieving PL/SQL Excellence
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 126/269
PL/SQL Advanced Techniques - page 1267/10/2013 Copyright 2001 Steven Feuerstein
Managing
Large Objectswith DBMS_LOB
LOB Terms
LOB = Large OBject: a category of datatype allowingstorage of “unstructured” data up to 4 gigabytes
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 127/269
PL/SQL Advanced Techniques - page 1277/10/2013 Copyright 2001 Steven Feuerstein
LOB datatype can be: – Column in table
– Attribute in object type
– Element in nested table
Possible applications include office documents, Images,sounds, video, etc.
LOB datatypes are the successor to LONGs. – Oracle has announced deprecation of LONGs; they should no
longer be used, though they will probably not be actually de-
supported.
Types of Large Objects “Internal” LOBs
– BLOB: unstructured binarydata
“External” LOBs
– BFILE: pointer to anoperating system file
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 128/269
PL/SQL Advanced Techniques - page 1287/10/2013 Copyright 2001 Steven Feuerstein
– CLOB: single-byte fixed-width character data
– NCLOB: multi-byte fixed-width character data (or varying width in )
operating system file
Key programming differences:
– Internal LOBs participate in transactions; external do not
– External LOBs are read-only from within Oracle
Temporary LOBs
– Internal LOBs that do notparticipate in transactions,improving performance.
PL/SQL built-ins for LOBs Package DBMS_LOB
– Supports for all LOBs: Reading, substring and instring searches,comparison and length checking
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 129/269
PL/SQL Advanced Techniques - page 1297/10/2013 Copyright 2001 Steven Feuerstein
– For internal LOBs: Write, append, copy, erase, trim – For external LOBs: File existence test, open, close
Other built-in functions– LOADFROMFILE (load an external BFILE into a BLOB)
–EMPTY_LOB(), EMPTY_CLOB()
– BFILENAME
BLOB-typed column in a table
Deceptively simple example
CREATE TABLE incoming_faxes(fax id INTEGER
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 130/269
PL/SQL Advanced Techniques - page 1307/10/2013 Copyright 2001 Steven Feuerstein
Retrieve record with BLOB into PL/SQL variable
(fax_id INTEGER,received DATE,fax BLOB);
DECLARECURSOR fax_cur IS
SELECT fax FROM incoming_faxes;the_fax BLOB;
BEGINOPEN fax_cur;FETCH fax_cur INTO the_fax;
CLOSE fax_cur;END; Question:What‟s in the_fax?
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 131/269
Example: Piecewise CLOB programmatic insert
Create a table
CREATE TABLE web_pages (
1 of 2
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 132/269
PL/SQL Advanced Techniques - page 1327/10/2013 Copyright 2001 Steven Feuerstein
Must get a new LOB locator before writing into the LOB:
url VARCHAR2(512) PRIMARY KEY,htmlloc CLOB);
DECLAREthe_url web_pages.url%TYPE := 'http://www.oodb.com';the_loc CLOB;
BEGININSERT INTO web_pages VALUES (the_url, EMPTY_CLOB())
RETURNING htmlloc INTO the_loc;
...
Example: Piecewise CLOB programmatic insertDECLARE
the_url web_pages.url%TYPE := 'http://www.oodb.com';
the_loc CLOB;
html_tab UTL_HTTP.HTML_PIECES;
piece_length PLS_INTEGER;
running_total PLS_INTEGER := 1;
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 133/269
PL/SQL Advanced Techniques - page 1337/10/2013 Copyright 2001 Steven Feuerstein
BEGININSERT INTO web_pages VALUES (the_url, EMPTY_CLOB())
RETURNING htmlloc INTO the_loc;
html_tab := UTL_HTTP.REQUEST_PIECES(url => the_url);
FOR the_piece_no IN 1..html_tab.COUNTLOOP
piece_length := LENGTH(html_tab(the_piece_no));
DBMS_LOB.WRITE(lob_loc => the_loc,
amount => piece_length,
offset => running_total,
buffer => html_tab(the_piece_no));running_total := running_total + piece_length;
END LOOP;
END;
This blo ck retr iev es
and loads a web page
into a CLOB colum n
Note: We are igno ring
several l ikely except ion s
Example: Piecewise CLOB programmatic update
DECLARECURSOR hcur IS
SELECT htmllocFROM web_pages
Program mu st lock the record expl ic i t ly
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 134/269
PL/SQL Advanced Techniques - page 1347/10/2013 Copyright 2001 Steven Feuerstein
WHERE url = 'http://www.oodb.com'FOR UPDATE;
the_loc CLOB;str_offset INTEGER;
BEGINOPEN hcur; FETCH hcur INTO the_loc; CLOSE hcur;
str_offset := DBMS_LOB.INSTR(lob_loc => the_loc,pattern => 'oodb');
IF str_offset != 0THEN
DBMS_LOB.WRITE(lob_loc => the_loc,amount => 4,
offset => str_offset,buffer => 'cool');
END IF;END;
Preparing to use BFILEs You must first create an Oracle “DIRECTORY”
– Creates logical alias for full directory path
– Similar to LIBRARY (used for C "external procedures"), but
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 135/269
PL/SQL Advanced Techniques - page 1357/10/2013 Copyright 2001 Steven Feuerstein
DIRECTORY namespace is global
Syntax:
Example: CREATE DIRECTORY web_pixAS 'D:\bill\training\pix';
CREATE OR REPLACE DIRECTORY <directory name> AS
'<full path to directory>';
Using BFILE datatype in DDL In a table...
CREATE TABLE web_graphics (
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 136/269
PL/SQL Advanced Techniques - page 1367/10/2013 Copyright 2001 Steven Feuerstein
image_id INTEGER,image BFILE);
In an object type...
CREATE TYPE Business_card_t AS OBJECT (name Name_t,addresses Address_tab_t,phones Phone_tab_t,scanned_card_image BFILE
);
/
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 137/269
Loading File into Database BLOB
DECLARE
CREATE TABLE web_graphic_blobs (image_id INTEGER, image BLOB);
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 138/269
PL/SQL Advanced Techniques - page 1387/10/2013 Copyright 2001 Steven Feuerstein
pic_file BFILE := BFILENAME('WEB_PIX', 'prodicon.gif');pic_blob_loc BLOB := EMPTY_BLOB();
BEGININSERT INTO web_graphic_blobs
VALUES (1, pic_blob_loc)RETURNING image INTO pic_blob_loc;
DBMS_LOB.FILEOPEN(pic_file, DBMS_LOB.FILE_READONLY);
DBMS_LOB.LOADFROMFILE(dest_lob => pic_blob_loc,src_lob => pic_file,amount => DBMS_LOB.GETLENGTH(pic_file));
DBMS_LOB.FILECLOSE(pic_file);END;/
loadblob.sql
New DBMS_LOB APIs in 8i Support for temporary LOBs
– No logging or rollback faster!
Lif i ll t ti
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 139/269
PL/SQL Advanced Techniques - page 1397/10/2013 Copyright 2001 Steven Feuerstein
– Lifespan: session, call, or transaction
Ability to retrieve LOB “chunk size”
– Allows programmer to tune READs and WRITEs
For all internal LOBs– OPEN & CLOSE allow control over timing; that can mean
less I/O» Trigger will not fire until CLOSE
» Indexes will not update until CLOSE
–ISOPEN
HOT
Large Object - Summary LOB support in Oracle is now significantly
improved.
C l t t i PL/SQL ( d th API )
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 140/269
PL/SQL Advanced Techniques - page 1407/10/2013 Copyright 2001 Steven Feuerstein
COLD
– Complete support in PL/SQL (and other APIs) – Much better performance and control than with
LONGs
– Usable in object types
Some weaknesses... – LOB locator behavior slightly abstruse
– Inability to modify BFILEs directly from within PL/SQL.
Achieving PL/SQL Excellence
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 141/269
PL/SQL Advanced Techniques - page 1417/10/2013 Copyright 2001 Steven Feuerstein
Leveraging Java
Inside PL/SQL
Overview of Java interoperability Java inside or outside 8i server can call PL/SQL
– Standard JDBC and SQLJ calls with Oracle extensions
– Same Java on client, mid-tier, or server
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 142/269
PL/SQL Advanced Techniques - page 1427/10/2013 Copyright 2001 Steven Feuerstein
Not cov ered in th is s eminar
PL/SQL can call Java inside 8i server
– Command-line tools load Java classes – DDL extensions publish Java classes
– Writing stored procedures, functions, triggers in Java
– Distinct Java & PL/SQL namespaces
But first...a BRIEF introduction to Java...
Question 1: What is Java? Could it be...
– The end of programming history as we know it?
– The easiest, fastest, slickest piece of software ever designed by
human beings?
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 143/269
PL/SQL Advanced Techniques - page 1437/10/2013 Copyright 2001 Steven Feuerstein
human beings? – Just the latest in a series of "silver bullets" promoted by software
vendors in order to prop up quarterly sales?
– The first and only successful O-O language?
– None of the above?
We don't really need to take a vote.
– We just need to keep a firm grip on common sense and stay focusedon delivering solutions.
Question 2: Will Java Replace PL/SQL? While that scenario is certainly possible, it is very unlikely
and totally unthinkable for years to come.
PL/SQL will still be:
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 144/269
PL/SQL Advanced Techniques - page 1447/10/2013 Copyright 2001 Steven Feuerstein
PL/SQL will still be: – Faster and more productive than Java for database operations.
– A language in which hundreds of thousands of developers aretrained.
– Ubiquitous in thousands of production applications and millions of
lines of code. – Supported and improved by Oracle -- and very aggressively, to boot.
Some Important Things to Remember Java is a case sensitive language...
– string is definitely not the same as String.
Everything is a class (or an object instantiated from a
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 145/269
PL/SQL Advanced Techniques - page 1457/10/2013 Copyright 2001 Steven Feuerstein
Everything is a class (or an object instantiated from aclass)...
– Before you can call a (non-static) class method, you have toinstantiate an object from that class.
– Well, everything exception the primitive datatypes.
You don't have to know how to do everything with Java toget lots of value out of it... – Don't get overwhelmed by all the classes and all the strange quirks.
Building a Java Class
public class Hello {
Let's start from the very beginning...
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 146/269
PL/SQL Advanced Techniques - page 1467/10/2013 Copyright 2001 Steven Feuerstein
public static void main (String[] args) {System.out.println ("Hello world!");
}
}
CREATE OR REPLACE PROCEDURE hello ISBEGIN
DBMS_OUTPUT.PUT_LINE ('Hello world!');
END;
Oh, by the way:the PL/SQL
version
No members, no methods, except the "special" main
method. – Used to test or run stand-alone a class,
Compiling Classes Before you can use a class, you must compile it with the
javac command. – You must also either have set the CLASSPATH or include it in your
javac call
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 147/269
PL/SQL Advanced Techniques - page 1477/10/2013 Copyright 2001 Steven Feuerstein
javac call. – This will convert the .java file to a .class file.
– It will also automatically recompile any classes used by your classthat has not been compiled since last change.
D:> javac Hello.java -classpath d:\java
SET CLASSPATH = d:\Oracle\Ora81\jdbc\lib\classes111.zip;e:\jdk1.1.7b\lib\classes.zip;d:\java
Running a Class Run a class? What does that mean? It means that if your
class contains a method with this header:
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 148/269
PL/SQL Advanced Techniques - page 1487/10/2013 Copyright 2001 Steven Feuerstein
public static void main (String[] args)
d:\java> java Hello
d:\java> java Hello mom
then you can "run" the main method with the javacommand:
You can also pass one or more arguments on thecommand line:
Hello2.java
Using a Class The main method is handy for providing a built-in test
mechanism of your class.
Usually however you will use a class by instantiatingbj t f th l d th i ki l th d
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 149/269
PL/SQL Advanced Techniques - page 1497/10/2013 Copyright 2001 Steven Feuerstein
Usually, however, you will use a class by instantiatingobjects from the class and then invoking class methods onthe object.
Let's build a performance analyzer class to explore theseideas.
Compare Performance of Methods Use System.currentTimeMillis to calculate elapsed time to
nearest thousandth of a second.
class Tmr {
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 150/269
PL/SQL Advanced Techniques - page 1507/10/2013 Copyright 2001 Steven Feuerstein
private long Gstart = 0;
public void capture () {Gstart = System.currentTimeMillis(); }
public void showElapsed () {p.l ("Elapsed time ",
System.currentTimeMillis() - Gstart); }
public long elapsed () {return (System.currentTimeMillis() - Gstart); }
public void showElapsed (String context) {p.l ("Elapsed time for " + context, elapsed()); }}
p.javaTmr.java
InFile.java
Types of Classes There are several different kinds of classes in Java, besides
the "regular" kind we just saw...
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 151/269
PL/SQL Advanced Techniques - page 1517/10/2013 Copyright 2001 Steven Feuerstein
Abstract class – The class can contain members and methods, but at least one
method remains unimplemented.
Interface class – The class only contains unimplemented methods.
Inner class
– Classes that are defined inside other classes.
And Now for Some Scary Buzzwords! Inheritance
– Subclasses inherit methods and variables from extended superclasses.
Polymorphism
– An object of a class can have "multiple" forms, either as its own class or as
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 152/269
PL/SQL Advanced Techniques - page 1527/10/2013 Copyright 2001 Steven Feuerstein
j p ,any superclass.
– Dynamic polymorphism: form is determined at run-time.
– Static polymorphism: form is chosen at compile-time (PL/SQL overloading).
A ClassHierarchy
Person.java
Person
Citizen
Corporation
War Criminal
Employee
supertype/"wider" subtype/"narrower"
Hourly Worker
SalariedWorker
Management
Non-Management
Language Basics Comments // Single line comment
/* Blockcomment */
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 153/269
PL/SQL Advanced Techniques - page 1537/10/2013 Copyright 2001 Steven Feuerstein
Primitive datatypes
– So I lied; these are not objectsinstantiated from classes.
/** Documentation comment */
booleancharbyteshort
intlongfloatdouble
Strings – A String object is a read-only; if you
assign a new value to it, you areactually allocating a new object.
– Can't do a direct == comparison.
String myName;myName = "Steven";myName = "Feuerstein";
if (myName.equals(YourName))
foundFamily();
Writing Loops in Java Three kinds of loops: while, do-while and for
– Note: you need squiggly brackets only if there is more than onestatement in the loop body.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 154/269
PL/SQL Advanced Techniques - page 1547/10/2013 Copyright 2001 Steven Feuerstein
do {lostsaStuff
} while (expression);
while (expression) {lostsaStuff
}
for (initialize; expression; step) {lotsaStuff
}
for (indx indx=0;indx < args.length;indx++)
System.out.println (args[indx]);
static void processAll (Enumeration enum) {while (enum.hasMoreElements ()) {
processIt (enum.NextElement());System.out.println ((String)enum.nextElement()) } }
Examples:
Passing Parameters Some important differences from PL/SQL...
– No default values for arguments; you must supply a value for eachparameter.
– Only positional notation is supported.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 155/269
PL/SQL Advanced Techniques - page 1557/10/2013 Copyright 2001 Steven Feuerstein
y p pp – If a method has no arguments, you still include the open and close
parentheses.
class PuterLingo {private String mname;
public PuterLingo (String name) { mname = name; }public String name () { return mname; }
}class LotsALingos {
public static void main (String args[]) {PuterLingo Java = new PuterLingo("Java");
System.out.println (Java.name()); }}
Exception Handling in Java Very similar to PL/SQL; you "throw" and "catch" exceptions,
rather than raise and handle.
public static int numBytes (String filename) { Throwing my ownexception
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 156/269
PL/SQL Advanced Techniques - page 1567/10/2013 Copyright 2001 Steven Feuerstein
try {if (filename.equals(""))
throw new Exception ("Filename is NULL");
File myFile = new File (filename);
return myFile.length();}
catch (SecurityException e) {return -1;}
catch (Exception e) {System.out.println (e.toString());
}}
"WHEN OTHERS"
in Java
File-relatedexceptions
exception
Put insidetry clause
Differences Between Java & PL/SQL Exceptions are objects derived directly or indirectly from the
Exception class. – So you can pass them as arguments and do anything and everything
else you can do with objects.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 157/269
PL/SQL Advanced Techniques - page 1577/10/2013 Copyright 2001 Steven Feuerstein
You must inform users of your method of which exceptionsmay be thrown. – Use the throws clause in your specification, as in:
public static int numBytes (String filename)throws SecurityException, NoSuchFile {...
}
Java's Not So Tough! You can learn enough Java in less than a week to:
– Build simple classes
– Leverage Java inside PL/SQL
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 158/269
PL/SQL Advanced Techniques - page 1587/10/2013 Copyright 2001 Steven Feuerstein
Moving to the next level of expertise will be more of achallenge.
– Object oriented development (Java) is very different from procedural
coding (PL/SQL).
Now let's explore how you can put Java to work for youinside PL/SQL programs.
Java Stored Procedures (JSPs)
Oracle 8i server
Java applet or app. usingJDBC or
SQLJ
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 159/269
PL/SQL Advanced Techniques - page 1597/10/2013 Copyright 2001 Steven Feuerstein
Java virtual machine running
Java method
PL/SQL cover for Java
method
OracleDeveloper
client(PL/SQL)
OCI or Pro*Cclient
VB or C++
via OO4O or ODBC
Net8
JSPs: Some sample usesPL/SQL extender
– For example, better file I/O
– RMI callouts, network communication in/out
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 160/269
PL/SQL Advanced Techniques - page 1607/10/2013 Copyright 2001 Steven Feuerstein
PL/SQL replacement
– More standard language
– Good performer for numeric processing tasks
– Beware database I/O & string manipulation performance
Scaleable deployment of third party code
– Vertical application
– Web server – XML parser/generator
Creating JSP to call from PL/SQL 1.Create Java classes in your favorite IDE
2.Load into server using “loadjava” command-line
tool
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 161/269
PL/SQL Advanced Techniques - page 1617/10/2013 Copyright 2001 Steven Feuerstein
3.Publ ish PL/SQL cover using AS LANGUAGEJAVA... rather than BEGIN...END
4.Grant privileges as desired
5.Call from PL/SQL (or SQL) as if calling PL/SQL
Create Java class(es)
toString methodt ti ll d b
class Corporation extends Person {long layoffs;long CEOCompensation;
public Corporation (String Pname, long Playoffs, long PceoComp) {name = Pname;layoffs = Playoffs;
Notes on Javaclasses
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 162/269
PL/SQL Advanced Techniques - page 1627/10/2013 Copyright 2001 Steven Feuerstein
automatically used bySystem.out.println
main method is usedto test the class.
Entry points must bepublic static in mostcases
Classes may call other classes
Avoid GUI calls
CEOCompensation = PceoComp;}
public String toString () {return name +" is a transnational entity with " + layoffs +" laid-off employees, paying its" +" Chief Executive Officer " + CEOCompensation;
}
public static void main (String[] args) {// A very scary companyCorporation TheGlobalMonster =
new Corporation ("Northrup-Ford-Mattel-Yahoo-ATT",
5000000, 50000000);
System.out.println (TheGlobalMonster);}} person.java
Upload using “loadjava” utility Oracle 8i server
loadjava
Java
class
Java
resource
.class file
Java
resource
file
.jar file.java file
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 163/269
PL/SQL Advanced Techniques - page 1637/10/2013 Copyright 2001 Steven Feuerstein
Example:
loadjava options (abbreviated)-oci8 loadjava will connect using OCI driver
-resolve Resolves external class references atcompile time
-resolver (shown later) Search path like CLASSPATH
loadjava -user scott/tiger -oci8-resolve datacraft/bill/Hello.class
jJava
source
Publish Example (top-level
call spec)
CREATE OR REPLACE FUNCTION hello_emp(empno_in IN NUMBER)
RETURN VARCHAR2
AS LANGUAGE JAVANAME 'datacraft.bill.Hello.Emp(int)
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 164/269
PL/SQL Advanced Techniques - page 1647/10/2013 Copyright 2001 Steven Feuerstein
Syntax (simplified)
return java.lang.String';/
CREATE [ OR REPLACE ] { PROCEDURE | FUNCTION } <name > [ RETURN <sq l type > ]
[ ( <args > ) ] [ AUTHID { DEFINER | CURRENT_USER } ]
AS LANGUAGE JAVA
NAME '<method ful lname> (<Java type ful lname> , ...)[ return <Java typ e ful ln ame> ]';
Call the wrapped method Method 1: Call as if PL/SQL module
BEGINDBMS_OUTPUT.PUT_LINE(hello_emp(7499));
END;
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 165/269
PL/SQL Advanced Techniques - page 1657/10/2013 Copyright 2001 Steven Feuerstein
Method 2: Use 8i SQL CALL statement; for example, fromSQL*Plus:
– CALL avoids overhead of SELECT fn FROM DUAL
VARIABLE thename VARCHAR2(12)CALL hello_emp(7499) INTO :thename;PRINT :thename
jsp.sql
Publishing -- more conceptsShape mapping
– Java methods declared “void” become PL/SQLprocedures
– Signature mismatches detected only at runtime
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 166/269
PL/SQL Advanced Techniques - page 1667/10/2013 Copyright 2001 Steven Feuerstein
Type mapping (typical) java.lang.String VARCHAR2
java.sql.Timestamp DATE
java.math.BigDecimal NUMBER
oracle.sql.STRUCT user-defined object type
<named type> user-defined object type
oracle.sql.REF object REFerence
oracle.sql.ARRAY user-defined collection type
Publish in PL/SQL Package Spec Designate Java module in PL/SQL package spec...
CREATE OR REPLACE PACKAGE hello_pkgASFUNCTION hi ( i IN NUMBER)
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 167/269
PL/SQL Advanced Techniques - page 1677/10/2013 Copyright 2001 Steven Feuerstein
FUNCTION hi_emp (empno_in IN NUMBER)RETURN VARCHAR2AS LANGUAGE JAVA
NAME 'datacraft.util.Hello.Emp(int)
return java.lang.String';END;/
(No package body required in this case)
Publish as module in package body ...or in package body
CREATE OR REPLACE PACKAGE hello_pkg2AS
FUNCTION hi_emp (empno_in IN NUMBER)RETURN VARCHAR2;
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 168/269
PL/SQL Advanced Techniques - page 1687/10/2013 Copyright 2001 Steven Feuerstein
;END;/
CREATE OR REPLACE PACKAGE BODY hello_pkg2
ASFUNCTION hi_emp (empno_in IN NUMBER)RETURN VARCHAR2IS LANGUAGE JAVA
NAME 'datacraft.util.Hello.Emp(int)return java.lang.String';
END;/
Publish as object type method Either in
spec:
CREATE OR REPLACE TYPE foo_t AS OBJECT (bar VARCHAR2(30),MEMBER FUNCTION hello_emp RETURN VARCHAR2IS LANGUAGE JAVA
NAME 'datacraft.util.Hello.Emp(int)return java.lang.String');/
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 169/269
PL/SQL Advanced Techniques - page 1697/10/2013 Copyright 2001 Steven Feuerstein
/
CREATE OR REPLACE TYPE foo_t AS OBJECT (bar VARCHAR2(30),
MEMBER FUNCTION hello_emp RETURN VARCHAR2);/
CREATE OR REPLACE TYPE BODY foo_t ASMEMBER FUNCTION hello_emp RETURN VARCHAR2IS LANGUAGE JAVA
NAME 'datacraft.util.Hello.Emp(int)
return java.lang.String'; END;/
or in the
body:
New DDL Statements and Roles CREATE JAVA
– Alternative to “loadjava” utility
– Creates or replaces an Oracle “library unit” from Java source, class,or resource
– Can read file designated with BFILE() function
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 170/269
PL/SQL Advanced Techniques - page 1707/10/2013 Copyright 2001 Steven Feuerstein
ALTER JAVA: compiles Java source, resolves Javaclass references.
DROP JAVA: drops a named Java library unit
Several roles available for Java operations: – JAVAUSERPRIV, JAVASYSPRIV (needed for file IO operations),
JAVA_ADMIN, JAVAIDPRIV, JAVADEBUGPRIV
– You can also grant specific privileges.
Passing Oracle8 objects
Oracle8i server
Objectin O R
Java application
Javaobject
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 171/269
PL/SQL Advanced Techniques - page 1717/10/2013 Copyright 2001 Steven Feuerstein
Harder than you‟d think
Three different interfacing techniques– oracle.sql.STRUCT
– oracle.sql.CustomDatum
– oracle.jdbc2.SQLData
in O-Rtable
object
JPublisher utilityWhat does it do?
– Generates Java thatencapsulates type and
REF
Three types of mapping
Database server
Definition of type or REF in
data dictionary
User-suppliedJPublisher input file
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 172/269
PL/SQL Advanced Techniques - page 1727/10/2013 Copyright 2001 Steven Feuerstein
Three types of mappingsupported for methods
– “Oracle mapping”
– “JDBC mapping” – “Object JDBC mapping”
data dictionary
JPublisher
Generated Javafile(s) for use inJava programs
Passing object using JPub-generated Java After generating and uploading classes with JPub,
they become available to use in mapping
Example of passing an Account_t object:
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 173/269
PL/SQL Advanced Techniques - page 1737/10/2013 Copyright 2001 Steven Feuerstein
CREATE OR REPLACE PROCEDURE account_save(new_acct IN Account_t)
IS LANGUAGE JAVANAME
'datacraft.bill.AccountRuntime.save(datacraft.bill.Account_t)';
/
jspobj.sql
Example: Improving File I/O
You can read/write files in PL/SQL withUTL_FILE, but that package is very limited.
Java offers many file-related classes with much
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 174/269
PL/SQL Advanced Techniques - page 1747/10/2013 Copyright 2001 Steven Feuerstein
greater capabilities.
Let's see how we can make that great Java stuff
available from within PL/SQL.
Encapsulate Java Classes You won't generally access native Java methods in
your PL/SQL wrapper.
– Instead build a static method that instantiates a Javaobject from the class and then invokes the relevantmethod against that object
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 175/269
PL/SQL Advanced Techniques - page 1757/10/2013 Copyright 2001 Steven Feuerstein
method against that object.
Let's start with something simple...
– The File class offers a length method that returns thenumber of bytes in a file.
– This is not available through UTL_FILE (though you canget it through DBMS_LOB).
My Own Java Class for File Manipulation Accept the name of a file and return its length.
import java.io.File;public class JFile2 {
public static long length (String fileName) {File myFile = new File (fileName);
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 176/269
PL/SQL Advanced Techniques - page 1767/10/2013 Copyright 2001 Steven Feuerstein
return myFile.length(); }}
Take each of these steps:
– Import the File class to resolve reference.
– Instantiate a File object for the specified name.
– Call the method of choice against that object and returnthe value.
JFile2.java
Build a Package over Java Method Let's put it in a package; we will certainly want to
add more functionality over time.
– I translate the Java long to a PL/SQL NUMBER.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 177/269
PL/SQL Advanced Techniques - page 1777/10/2013 Copyright 2001 Steven Feuerstein
CREATE OR REPLACE PACKAGE xfileIS
FUNCTION length (file IN VARCHAR2) RETURN NUMBER;END;/
CREATE OR REPLACE PACKAGE BODY xfileIS
FUNCTION length (file IN VARCHAR2) RETURN NUMBERAS LANGUAGE JAVA
NAME 'JFile.length (java.lang.String) return long';END;/
xfile2.pkg
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 178/269
Translate Boolean to Number Accept the name of a file and return its length.
import java.io.File;
public class JFile3 {public static int canRead (String fileName) {
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 179/269
PL/SQL Advanced Techniques - page 1797/10/2013 Copyright 2001 Steven Feuerstein
File myFile = new File (fileName);boolean retval = myFile.canRead();if (retval) return 1; else return 0; }
}
Translate TRUE to 1 and FALSE to 0.
– And don't forget: this is a boolean primitive, not aBoolean class.
JFile3.java
Wrapper for Pseudo-Boolean function Simple translation back to PL/SQL Boolean.
– Avoid the hard-codings with named constants...
CREATE OR REPLACE PACKAGE xfile IS
FUNCTION canRead (file IN VARCHAR2) RETURN BOOLEAN;END;
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 180/269
PL/SQL Advanced Techniques - page 1807/10/2013 Copyright 2001 Steven Feuerstein
/CREATE OR REPLACE PACKAGE BODY xfileIS
FUNCTION IcanRead (file IN VARCHAR2) RETURN NUMBERAS LANGUAGE JAVA
NAME 'JFile3.canRead (java.lang.String) return int';
FUNCTION canRead (file IN VARCHAR2) RETURN BOOLEAN ASBEGIN
RETURN IcanRead (file) = 1;END;
END;/
xfile3.pkgJFile4.java
xfile4.pkgJFile.javaxfile.pkg
Passing Objects to Java with STRUCT You can pass Oracle object information to Java
without relying on JPub by using the STRUCT class.
public class UnionBuster {
public static void wageStrategy (STRUCT e)throws java.sql.SQLException {
Obtain attributes of the Oracle object.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 181/269
PL/SQL Advanced Techniques - page 1817/10/2013 Copyright 2001 Steven Feuerstein
// Get the attributes of the labor_source object.Object[] attribs = e.getAttributes();
// Access individual attributes by array index,
// starting with 0String laborType = (String)(attribs[0]); BigDecimal hourly_rate = (BigDecimal)(attribs[1]);
System.out.println ("Pay " + laborType + " $" +hourly_rate + " per hour");
}}
Extract individualattribute values from
the array.UnionBuster.java
passobj.tst
Wrapping a STRUCT-based Method You can pass Oracle object information to Java
without relying on JPub by using the STRUCT class.
CREATE TYPE labor_source_t AS OBJECT (
labor_type VARCHAR2(30),hourly_rate NUMBER);
/
The Oracle objecttype definition
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 182/269
PL/SQL Advanced Techniques - page 1827/10/2013 Copyright 2001 Steven Feuerstein
CREATE OR REPLACE PROCEDURE bust_em_with (labor_source_in IN labor_source_t)
AS LANGUAGE JAVA
NAME 'UnionBuster.wageStrategy (oracle.sql.STRUCT)';/
BEGINbust_em_with (
labor_source ('Workfare', 0));bust_em_with (
labor_source ('Prisoners', '5'));END;
Fully specify theSTRUCT class in
parameter list.
Viewing Output from Java Methods Java provides a "print line" method similar to
DBMS_OUTPUT.PUT_LINE: System.out.println. – Call it within methods and output will display in your Java
environment.public class HelloAll {
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 183/269
PL/SQL Advanced Techniques - page 1837/10/2013 Copyright 2001 Steven Feuerstein
When called within a PL/SQL wrapper, you can redirect theoutput to the DBMS_OUTPUT buffer.
– Here is a good nucleus for a login.sql file:
public static void lotsaText (int count) {for (int i = 0; i < count; i++) {
System.out.println (
"Hello Hello Hello Hello Hello All!"); }}}
SET SERVEROUTPUT ON SIZE 1000000CALL DBMS_JAVA.SET_OUTPUT (1000000);
HelloAll.javaHelloAll.tst
Error Handling with Java-PL/SQL Java offers a very similar, but more robust error handling
mechanism than PL/SQL. – Exceptions are objects instantiated from the Exception class or a
subclass of it, such as java.sql.SQLException. – Instead of raising and handling, you "throw" and "catch".
– Use two methods getErrorCode() and getMessage() to obtain
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 184/269
PL/SQL Advanced Techniques - page 1847/10/2013 Copyright 2001 Steven Feuerstein
– Use two methods, getErrorCode() and getMessage() to obtaininformation about the error thrown.
Any error not caught by the JVM (Java virtual machine) willbe thrown back to the PL/SQL block or SQL statement.
– And also spew out the entire Java error stack! (at least through8.1.5).
Trapping and Identifying Errors Currently, the entire Java stack is displayed on your screen,
and you have to do some digging to extract the Oracle error information.
SQL> BEGIN2 dropany ('TABLE', 'blip');3 EXCEPTION4 WHEN OTHERS
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 185/269
PL/SQL Advanced Techniques - page 1857/10/2013 Copyright 2001 Steven Feuerstein
5 THEN6 DBMS_OUTPUT.PUT_LINE (SQLCODE);7 DBMS_OUTPUT.PUT_LINE (SQLERRM);8 END;9 /
java.sql.SQLException: ORA-00942: table or view does not existat oracle.jdbc.kprb.KprbDBAccess.check_error(KprbDBAccess.java)at oracle.jdbc.kprb.KprbDBAccess.parseExecuteFetch(KprbDBAccess.java)at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java)at oracle.jdbc.driver.OracleStatement.doExecuteWithBatch(OracleStatement.java)at oracle.jdbc.driver.OracleStatement.doExecute(OracleStatement.java)at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java)at oracle.jdbc.driver.OracleStatement.executeUpdate(OracleStatement.java)at DropAny.object(DropAny.java:14)
-29532ORA-29532: Java call terminated by uncaught Java exception: java.sql.SQLException:ORA-00942: table or view does not exist
DropAny.java
dropany.tstgetErrInfo.spdropany2.tst
Achieving PL/SQL Excellence
External Procedures
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 186/269
PL/SQL Advanced Techniques - page 1867/10/2013 Copyright 2001 Steven Feuerstein
An external procedure is a 3GL routine that can serve asthe “body” of a PL/SQL function, procedure, or method.
– Must be a shared object library on Unix or a dynamically linkedlibrary (DLL) on Windows.
An Oracle8 feature that allowed relatively "native"callouts to C from PL/SQL for the first time.
External
Shared
Library
Application Net8
PL/SQL RuntimeEngine
Process & data flow
Cli t
External
Procedure
Listener Routine in
DLL or soCalls
Makes
request
spawns
calls
routine
f
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 187/269
PL/SQL Advanced Techniques - page 1877/10/2013 Copyright 2001 Steven Feuerstein
Client or
server-side
application
PL/SQL
body
extproc
.DLL or .so
file
spawnsfrom
returns
resultsreturns
results
returnsresults
External procedures: Sample uses Send email
Invoke operating system command
Invoke custom or legacy application
email.sql
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 188/269
PL/SQL Advanced Techniques - page 1887/10/2013 Copyright 2001 Steven Feuerstein
Call C runtime library function
Perform admin tasks
diskspace.sql
Determine free disk space on NT (1/4) Use pre-existing routine:
– GetDiskFreeSpaceA in kernel32.dl l
– For given drive letter, this function returns:
» sectors per cluster
» bytes per sector
» number of free clusters
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 189/269
PL/SQL Advanced Techniques - page 1897/10/2013 Copyright 2001 Steven Feuerstein
» total number of clusters
» “return code” indicating success or failure
First, create an Oracle8 “library”: CREATE OR REPLACE LIBRARY nt_kernelAS
'c:\winnt\system32\kernel32.dll';/
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 190/269
CREATE OR REPLACE PACKAGE BODY disk_util AS
FUNCTION get_disk_free_space
(root_path IN VARCHAR2,
sectors_per_cluster OUT PLS_INTEGER,
bytes_per_sector OUT PLS_INTEGER,
number_of_free_clusters OUT pls_integer,total_number_of_clusters OUT PLS_INTEGER)
RETURN PLS_INTEGER
Package body in Oracle 8.0 (3/4)
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 191/269
PL/SQL Advanced Techniques - page 1917/10/2013 Copyright 2001 Steven Feuerstein
IS EXTERNAL
LIBRARY nt_kernel
NAME "GetDiskFreeSpaceA"
LANGUAGE C
CALLING STANDARD PASCALPARAMETERS
(root_path STRING,
sectors_per_cluster BY REFERENCE LONG,
bytes_per_sector BY REFERENCE LONG,
number_of_free_clusters BY REFERENCE LONG,
total_number_of_clusters BY REFERENCE LONG,RETURN LONG);
END disk_util;
All the
magic is intheEXTERNAL section
Usage (4/4)DECLARE
lroot_path VARCHAR2(3) := 'C:\';
lsectors_per_cluster PLS_INTEGER;
lbytes_per_sector PLS_INTEGER;
lnumber_of_free_clusters PLS_INTEGER;ltotal_number_of_clusters PLS_INTEGER;
return_code PLS_INTEGER;
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 192/269
PL/SQL Advanced Techniques - page 1927/10/2013 Copyright 2001 Steven Feuerstein
free_meg REAL;
BEGIN
return_code := disk_util.get_disk_free_space (lroot_path,
lsectors_per_cluster, lbytes_per_sector,lnumber_of_free_clusters, ltotal_number_of_clusters);
free_meg := lsectors_per_cluster * lbytes_per_sector *
lnumber_of_free_clusters / 1024 / 1024;
DBMS_OUTPUT.PUT_LINE('free disk space, Mb = ' || free_meg);END; diskspace.sql
Creating your own external procedure 1. Identify or create shared library
2. Identify or CREATE LIBRARY within Oracle
3. Map the parameters using:
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 193/269
PL/SQL Advanced Techniques - page 1937/10/2013 Copyright 2001 Steven Feuerstein
– EXTERNAL clause (Oracle8)or
– LANGUAGE clause (Oracle8i )
1. Identify/create external routine Prerequ isi te: O/S mus t suppo rt shared l ibrar ies
Some useful routines are pre-built in C runtime library
– On Unix: /l ib /l ibc .s o – On NT: <systemroot>\system32\crtdl l .d l l
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 194/269
PL/SQL Advanced Techniques - page 1947/10/2013 Copyright 2001 Steven Feuerstein
Building a shared library of your own requires knowledge of: – Appropriate language (typically C)
– Compiler & linker
Syntax:
Assigns a programmer-defined alias to a specific sharedlibrary file
2. Create the Oracle libraryCREATE OR REPLACE LIBRARY <library name> AS
'<full path to file>';
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 195/269
PL/SQL Advanced Techniques - page 1957/10/2013 Copyright 2001 Steven Feuerstein
library file
Notes
– Requires CREATE LIBRARY privilege – Does not validate directory
– Can‟t use symbolic link
3. Map the parameters
– Must pass extraparameters to designate:» NULL/NOT NULL state
– Six choices of parameter mode» IN
This can get complicated, because…
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 196/269
PL/SQL Advanced Techniques - page 1967/10/2013 Copyright 2001 Steven Feuerstein
» String length
» Maximum allocated length
» RETURN
» IN BY REFERENCE
» RETURN BY REFERENCE» OUT
» IN OUT
These details are better suited for close reading…
Achieving PL/SQL Excellence
Oracle8i New Features
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 197/269
PL/SQL Advanced Techniques - page 1977/10/2013 Copyright 2001 Steven Feuerstein
Autonomous Transactions
Invoker Rights ModelRow Level Security
Oracle8i New Features Oracle8i offers a number of PL/SQL-specific features that
give you tremendous additional flexibility and capability. – And the learning curve to take advantage of these features is
generally not too steep.
Autonomous Transactions
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 198/269
PL/SQL Advanced Techniques - page 1987/10/2013 Copyright 2001 Steven Feuerstein
Autonomous Transactions
The Invoker Rights Model
Row level security
Autonomous Transactions Prior to Oracle8i, a COMMIT or ROLLBACK in any program
in your session committed or rolled back all changes in your session.
– There was only one transaction allowed per connection. With Oracle8i, you can now define a PL/SQL block to
execute as an "autonomous transaction"
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 199/269
PL/SQL Advanced Techniques - page 1997/10/2013 Copyright 2001 Steven Feuerstein
execute as an autonomous transaction .
– Any changes made within that block can be saved or reversedwithout affecting the outer or main transaction.
CREATE OR REPLACE PROCEDURE loginfo (code IN PLS_INTEGER,msg IN VARCHAR2)
ASPRAGMA AUTONOMOUS_TRANSACTION;
When to UseAutonomous Transactions
Reusable Application Components
– ATs are more or less required in the new distributed applicationarchitecture of the Internet.
– One component should not have any impact (esp. something like aCOMMIT) on other components.
Logging Mechanism
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 200/269
PL/SQL Advanced Techniques - page 2007/10/2013 Copyright 2001 Steven Feuerstein
– Commonly developers lot to database tables, which can cause allsorts of complications: your log entry becomes a part of your
transaction. – Now you can avoid the complexities (need for ROLLBACK TO
savepoints and so on).
Tracing Code Usage
– Build retry mechanisms, software usage meter, etc.
Call functions within SQL that change the database.
Logging with ATs Don't forget that ROLLBACK in the exception section!
CREATE OR REPLACE PACKAGE BODY logIS
PROCEDURE putline (code_in IN INTEGER, text_in IN VARCHAR2)
IS
Avoid inter-dependencies with
the main transaction.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 201/269
PL/SQL Advanced Techniques - page 2017/10/2013 Copyright 2001 Steven Feuerstein
logger.sp
log81.pkglog81*.tst
PRAGMA AUTONOMOUS_TRANSACTION; BEGININSERT INTO logtab
VALUES (code_in, text_in,SYSDATE, USER, SYSDATE, USER,rec.machine, rec.program
);
COMMIT;EXCEPTION WHEN OTHERS THEN ROLLBACK;END;
END;
While we're at it, let'sadd some session
information.
retry.pkgretry.tst
Tips and Gotchas with ATs An AT program mus t COMMIT or ROLLBACK before terminating, or an
error is raised.
The AT PRAGMA can be used only with individual programs and top-level anonymous blocks.
– You cannot define an entire package as an AT.
– You cannot define a nested anonymous block to be an AT.
The AT PRAGMA goes in the body of packages
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 202/269
PL/SQL Advanced Techniques - page 2027/10/2013 Copyright 2001 Steven Feuerstein
The AT PRAGMA goes in the body of packages.
– You cannot tell by looking at the package spec if you are calling ATs or not --and this info is not available in the data dictionary.
Any changes committed in an AT are visible in the outer transaction.
– You can use the SET TRANSACTION ISOLATION LEVEL SERIALIZABLE toindicate that you do not want the changes visible until the outer transactioncommits.
– Place the SET TRANSACTION statement in the outer transaction.
autonserial.sqlauton_in_sql.sqlautontrigger*.sql
The Invoker Rights Model
Prior to Oracle8i, whenever you executed a stored program,it ran under the privileges of the account in which theprogram was defined.
– This is called the …
Definer Rights Model
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 203/269
PL/SQL Advanced Techniques - page 2037/10/2013 Copyright 2001 Steven Feuerstein
With Oracle8i, you can now decide at compilation time
whether your program or package will execute in thedefiner's schema (the default) or the schema of the invoker of the code.
– This is called the … Invoker Rights Model
About Definer Rights
Allows you to centralizeaccess to and control of underlying datastructures.
Ignores roles and relieson directly-granted
OE Data
OE Code
Order_Mgt
Cancel
Sam_Sales
PlaceClose Old
Orders
X
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 204/269
PL/SQL Advanced Techniques - page 2047/10/2013 Copyright 2001 Steven Feuerstein
y gprivileges.
But it can be a source of confusion andarchitectural problems.
Orders
OE Data XCannot alter table directly.
Note: Oracle built-in packages have long had the capability of
running under the invoker's authority.
Problems with Definer Rights
Deployment & maintenance
– Must install module in all remote databases where needed
– In some databases, each user has own copy of table(s), requiringcopy of stored module
Security – No declarative way to restrict privileges on certain modules in a
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 205/269
PL/SQL Advanced Techniques - page 2057/10/2013 Copyright 2001 Steven Feuerstein
package -- it's all or nothing, unless you write code in the package toessentially recreate roles programmatically.
– Can bypass 8i ‟s “fine-grained” access features (see the DBMS_RLSpackage)
– Difficult to audit privileges
Sure would be nice to have a choice...and now you do!
For top level modules:
For modules with separate spec and body, AUTHID goesl i d t b t th k l l
Oracle8i Invoker Rights Syntax
CREATE [ OR REPLACE ] <module type>
[ AUTHID { DEFINER | CURRENT_USER } ]AS ...
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 206/269
PL/SQL Advanced Techniques - page 2067/10/2013 Copyright 2001 Steven Feuerstein
only in spec, and must be at the package level.
Synonyms may be necessary if modules use object names
not qualified by schema. – In other words, do what it takes to get the code to compile. You could
also create local, "dummy" objects.
– At run-time, the objects referenced may well be different from thoseagainst which it compiled.
"Reflection" Capability of Invoker Rights
With invoker rights, you can execute code owned by another schema, yet have all references to data structures "reflectback" into your own schema.
User/Data schemaCentral Code schema
PACKAGE acct_mgr
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 207/269
PL/SQL Advanced Techniques - page 2077/10/2013 Copyright 2001 Steven Feuerstein
accounts table
PROCEDURE mng_account ISBEGIN
...code.acct_mgr.destroy(...);
END;
_ g
...FROM accountsWHERE...
destroy
modify
make
AUTHID
CURRENT_USER
Tips and Gotchas for Invoker Rights
Does not apply to code objects, only data – When your stored code references another stored code element, the
definer rights model is always applied to resolve the reference.
– Both static and dynamic SQL is supported.
Once a definer rights program is called, all other calls instack are resolved according to definer rights. – AUTHID CURRENT_USER is ignored.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 208/269
PL/SQL Advanced Techniques - page 2087/10/2013 Copyright 2001 Steven Feuerstein
_ g
Information about the rights model is not available in the
data dictionary What if you want to maintain a single version of your code
for both pre-Oracle8i and Oracle8i installations, takingadvantage of the invoker rights model whenever possible? – A creative use of SQL*Plus substitution variables comes in very
handy. Note: cannot use with wrapped code. invdefinv.sqloneversion.sql
You want to reuse the same code among many users, butyou want their own directly-granted privileges to determineaccess.
When to Invoke Invoker Rights
stolenlives
ChicagoSchema
stolenlives
New YorkSchemaCheck CityStatistics
National HQ
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 209/269
PL/SQL Advanced Techniques - page 2097/10/2013 Copyright 2001 Steven Feuerstein
Especially handy with dynamic SQL.
– Share a program that uses dynamic SQL (whether DBMS_SQL or thenew native implementation) and you end up taking the mostunexpected DDL and DML detours.
authid.sqlwhichsch*.sql
Combining Invoker & Definer Rights
Rely on invoker rights to allow centralized code to work withschema-specific data.
Rely on definer rights to access centralized data from any
schema.
Chicago New YorkCh k Cit
HQ
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 210/269
PL/SQL Advanced Techniques - page 2107/10/2013 Copyright 2001 Steven Feuerstein
stolenlives
Chicago
stolenlives
New YorkCheck CityStatistics
perpetrators
AnalyzePattern
perp.sql
DBMS_RLSR L l
Row Level Security
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 211/269
PL/SQL Advanced Techniques - page 2117/10/2013 Copyright 2001 Steven Feuerstein
Row-Level
Security
Row-Level Security with DBMS_RLS
Oracle8i offers a new package, DBMS_RLS, with which toimplement automated row-level security (also referred to as"fine grained access control").
The establishment of security policies on(restricted access to)
Row Level Security
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 212/269
PL/SQL Advanced Techniques - page 2127/10/2013 Copyright 2001 Steven Feuerstein
individual rows of a table.
Prior to Oracle8i, you couldachieve this only partiallythrough the use of views.
The DBMS_RLS package(along with "systemcontexts") now allow you to
do so in a foo lp roo f manner.
Components Needed for RLS System Contexts
– A new feature in Oracle8i, the system context is a named set of attribute-value pairs global to your session.
Security Policy Packages
– You will need to write a package containing functions that establish thesecurity policies to be applied to a particular table.
Database Logon Triggers – I want to make sure that when a person logs in, their context information is
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 213/269
PL/SQL Advanced Techniques - page 2137/10/2013 Copyright 2001 Steven Feuerstein
p g ,set properly.
DBMS_RLS – Use programs in DBMS_RLS to associate your security policies with tables.
Let's step through a simple example to see how all these pieces tietogether.
A National Health Care System
The year is 2010.
– A massive, popular uprising in the United States has forced theestablishment of a national healthcare system. No more for-profithospitals pulling billions of dollars out of the system; no more
private insurance companies soaking up 30 cents on the dollar; allchildren are vaccinated; all pregnant women receive excellent pre-natal care.
W d t t h hi hl d t b f NHCS Th
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 214/269
PL/SQL Advanced Techniques - page 2147/10/2013 Copyright 2001 Steven Feuerstein
We need a top-notch, highly secure database for NHCS. Themain tables are patient, do cto r, cl in ic and regulator.
Here are some rules:
– Doctors can only see patients who are assigned to their clinic.
– Regulators can only see patients who reside in the same state.
– Patients can only see information about themselves.
fgac.sql
Set the Context
Define a context in the database, and create a procedurethat will set the context attributes (type and ID) upon login.
CREATE CONTEXT patient_restriction USING nhc_pkg;
PROCEDURE set_contextIS This is a simplification. See
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 215/269
PL/SQL Advanced Techniques - page 2157/10/2013 Copyright 2001 Steven Feuerstein
CURSOR doc_cur ISSELECT doctor_id FROM doctor
WHERE schema_name = USER;doc_rec doc_cur%ROWTYPE;BEGIN
OPEN doc_cur; FETCH doc_cur INTO doc_rec;DBMS_SESSION.SET_CONTEXT (
'patient_restriction', c_person_type_attr, 'DOCTOR');DBMS_SESSION.SET_CONTEXT (
'patient_restriction', c_person_id_attr, doc_rec.doctor_id);END;
pfgac.sql for logic that identifiesdifferent types of people and
sets the context accordingly.
Define the Predicate
A predicate is a string that will be appended to the WHEREclause of the table to which this security policy is associated(see next page).
FUNCTION person_predicate (schema_in VARCHAR2, name_in VARCHAR2) RETURN VARCHAR2
ISl context VARCHAR2(100) := Extract the context
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 216/269
PL/SQL Advanced Techniques - page 2167/10/2013 Copyright 2001 Steven Feuerstein
l_context VARCHAR2(100) :=SYS_CONTEXT (c_context, c_person_type_attr);
retval VARCHAR2(2000);
BEGINIF l_context = 'DOCTOR'THEN
retval := 'home_clinic_id IN(SELECT home_clinic_id FROM doctor WHERE doctor_id = SYS_CONTEXT (''' ||
c_context || ''', ''' ||
c_person_id_attr || '''))';
We need a different stringto modify the WHEREclause for each type of
person.
Extract the contextinformation for this
connection.
Create the Security Policy
Use the DBMS_RLS.ADD_POLICY procedure.
– The following procedure call specifies that the WHERE clause of anyquery, update or delete against the SCOTT.PATIENT table will bemodified by the string returned by the person_predicate function of
the SCOTT.nhc_pkg package.
BEGINDBMS RLS.ADD POLICY (
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 217/269
PL/SQL Advanced Techniques - page 2177/10/2013 Copyright 2001 Steven Feuerstein
_ _ (OBJECT_SCHEMA => 'SCOTT',OBJECT_NAME => 'patient',
POLICY_NAME => 'patient_privacy',FUNCTION_SCHEMA => 'SCOTT',POLICY_FUNCTION => 'nhc_pkg.person_predicate',STATEMENT_TYPES => 'SELECT,UPDATE,DELETE');
END;
Create Logon Trigger, Setting Context By setting the context in the logon trigger, we guarantee that
the context is set (and the predicate applied) no matter which product is the entry point to Oracle.
CREATE OR REPLACE TRIGGER set_id_on_logon AFTER LOGON ON DATABASE
BEGINh k t t t
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 218/269
PL/SQL Advanced Techniques - page 2187/10/2013 Copyright 2001 Steven Feuerstein
nhc_pkg.set_context;EXCEPTION
WHEN OTHERSTHEN
DBMS_OUTPUT.PUT_LINE ('Error ' || SQLCODE ||' setting context for ' || USER');
END;
Exception handling intrigger is critical! If you
allow an exception to gounhandled, logon is
disabled.
fgac.sql
Queries Transparently Filtered
What you see is determined automatically by who you are.
Context Information for "SWALLACE":Type: DOCTOR ID: 1060
Predicate:home_clinic_id IN(SELECT home_clinic_id FROM doctor WHERE doctor_id = SYS_CONTEXT ('patient_restriction', 'person_id'))
Patients Visible to "SWALLACE":
Doctor sees only her patients.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 219/269
PL/SQL Advanced Techniques - page 2197/10/2013 Copyright 2001 Steven Feuerstein
Patients Visible to SWALLACE :CSILVA - Chris Silva - IL
VSILVA - Veva Silva - IL
Context Information for "CSILVA":Type: PATIENTID:
Predicate: schema_name = 'CSILVA'
Patients Visible to "CSILVA":
CSILVA - Chris Silva - IL
Patient sees onlyhimself.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 220/269
Appendices(a.k.a., If time permits…)
Achieving PL/SQL Excellence
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 221/269
PL/SQL Advanced Techniques - page 2217/10/2013 Copyright 2001 Steven Feuerstein
UTL_FILE – file IO
DBMS_JOB – Job scheduling
DBMS_PIPE – Pipe-based communication
DBMS_UTILITY – the kitchen sink package
UTL_FILE
Server-sideFile I/O
Built-in Packages: UTL_FILE
Application
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 222/269
PL/SQL Advanced Techniques - page 2227/10/2013 Copyright 2001 Steven Feuerstein
FOPEN
GET_LINE
PUT_LINE
. . .Physical Files
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 223/269
UTL_FILE Module Outline
FCLOSE Close the specified file
FCLOSE_ALL Close all open files in your session
FFLUSH Flush all data from the UTL_FILE buffer to your file
FOPEN Open a file
GET_LINE Get the next line from a file
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 224/269
PL/SQL Advanced Techniques - page 2247/10/2013 Copyright 2001 Steven Feuerstein
IS_OPEN Returns TRUE if the file is open (sort of)
NEW_LINE Insert a new line character in file at the end of current line
PUT Puts text into the UTL_FILE buffer
PUT_LINE Puts text and new line character into UTL_FILE buffer.
PUTF Puts formatted text into the buffer
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 225/269
Test UTL_FILE Access
About the hardest part to working with UTL_FILE is simplygetting started.
So before you write anything fancy, modify your
initialization file, restar t you r database , and then run thefollowing test script (it can't get much simpler than this):
DECLAREfid UTL_FILE.FILE_TYPE;
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 226/269
PL/SQL Advanced Techniques - page 2267/10/2013 Copyright 2001 Steven Feuerstein
BEGIN/* Change the directory name to one to which you at least
|| THINK you have read/write access.*/fid := UTL_FILE.FOPEN ('c:\temp', 'test.txt', 'W');UTL_FILE.PUT_LINE (fid, 'hello');UTL_FILE.FCLOSE (fid);
END;/
utlfile.tst
Opening a File
Specify file location, name and operation type. – Types are 'R' for Read, 'W' for Write and 'A' for Append.
The FOPEN function returns a record ("file handle") basedth UTL FILE FILE TYPE
DECLAREfid UTL_FILE.FILE_TYPE;
BEGINfid := UTL_FILE.FOPEN ('c:\temp', 'test.txt', 'W');
END;
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 227/269
PL/SQL Advanced Techniques - page 2277/10/2013 Copyright 2001 Steven Feuerstein
on the UTL_FILE.FILE_TYPE. – Currently contains a single ID field.
Maximum of 10 files may be opened in each user session.
Test to see if file is open with the IS_OPEN function. – In actuality, this function simply returns TRUE if the file handle's id
field is NOT NULL. Not much of a test...
Reading from a File
Can only read from a file opened with the "R" mode.
Lines in the file cannot be longer than 1023 bytes in length
DECLAREfid UTL_FILE.FILE_TYPE;
BEGINfid := UTL_FILE.FOPEN ('c:\temp', 'test.txt', 'R');UTL_FILE.GET_LINE (fid, myline);
UTL_FILE.FCLOSE (fid);END;
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 228/269
PL/SQL Advanced Techniques - page 2287/10/2013 Copyright 2001 Steven Feuerstein
Lines in the file cannot be longer than 1023 bytes in length. – In Oracle8 Release 8.0.5 and above, the ceiling is raised to 32K.
The NO_DATA_FOUND exception is raised if you read pastthe end of the file. – You might want to build your own GET_LINE which handles the
exception and returns an EOF Boolean status flag.
getnext.sp
Writing to a FileDECLARE
fid UTL_FILE.FILE_TYPE;BEGIN
fid := UTL_FILE.FOPEN ('c:\temp', 'test.txt', 'W');UTL_FILE.PUT_LINE (fid, 'UTL_FILE');UTL_FILE.PUT (fid, 'is so much fun');
UTL_FILE.PUTF (fid, ' that I never\nwant to %s', '&1');UTL_FILE.FCLOSE (fid);
END;
UTL_FILEis so much fun that I never Resulting Text
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 229/269
PL/SQL Advanced Techniques - page 2297/10/2013 Copyright 2001 Steven Feuerstein
You can use PUT, PUT_LINE or PUTF. – PUTF is like the C printf program, allowing for some formatting.
Call FFLUSH to make sure that everything you have writtento the buffer is flushed out to the file.
– The file buffers are automatically flushed when you close a file or exityour session.
want to stop
g
Closing a File
DECLAREfid UTL_FILE.FILE_TYPE;
BEGINfid := UTL_FILE.FOPEN ('c:\temp', 'test.txt', 'R');UTL_FILE.GET_LINE (fid, myline);UTL_FILE.FCLOSE (fid);
EXCEPTION WHEN UTL_FILE.READ_ERROR THEN
UTL_FILE.FCLOSE (fid);END;
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 230/269
PL/SQL Advanced Techniques - page 2307/10/2013 Copyright 2001 Steven Feuerstein
If you do not close the file, you will not see the data you have(supposedly) written to that file.
You can close a single file with FCLOSE or all open files withFCLOSE_ALL.
You should close files in exception handlers to make sure that files arenot left "hanging" open.
Error Handling in UTL_FILE
PACKAGE UTL_FILEIS
invalid_path EXCEPTION;invalid_mode EXCEPTION;invalid_filehandle EXCEPTION;invalid_operation EXCEPTION;
read_error EXCEPTION; write_error EXCEPTION;internal_error EXCEPTION;
END;
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 231/269
PL/SQL Advanced Techniques - page 2317/10/2013 Copyright 2001 Steven Feuerstein
UTL_FILE relies on a combination of user-defined exceptions and
STANDARD exceptions to communicate errors. – NO_DATA_FOUND when you try to read past the end of the file.
– UTL_FILE-named exceptions in other cases.
You have to take special care to trap and handle the named exceptions. – They all share a common SQLCODE of 1.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 232/269
DBMS_JOBScheduled Execution
of Stored Procedures
Built-in Packages: DBMS_JOB
SUBMITApplication
Oracle Job QueueSubsystem
DBA JOBS
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 233/269
PL/SQL Advanced Techniques - page 2337/10/2013 Copyright 2001 Steven Feuerstein
RUN
REMOVE
. . .
BackgroundProcess
DBA_JOBS
Overview of DBMS_JOB
DBMS_JOB provides an API to the Oracle job queues, whichin turn offers job scheduling capabilities within the OracleServer.
Built by Oracle to support snapshots and replication. Made its debut in PL/SQL Release 2.1, but only “publicly
available” and supported in PL/SQL Release 2.2.
Y DBMS JOB t
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 234/269
PL/SQL Advanced Techniques - page 2347/10/2013 Copyright 2001 Steven Feuerstein
You can use DBMS_JOB to:
– Replicate data between different database instances. – Schedule regular maintenance on instances.
– Schedule large batch jobs to run on "off hours".
– Create a listener program to poll the contents of a pipe and takeaction.
– Spawn background processes to avoid blocking client process.
DBMS_JOB Module Outline
BROKEN Marks the job as either FIXED or BROKEN.Broken jobs will not run as scheduled.
CHANGE Changes one or all attributes of a job.
INTERVAL Changes the interval between executions of a job.
ISUBMIT Submits a job to the queue using a predefined job number.
NEXT_DATE Changes when a queued job will run.
REMOVE Removes the job from the queue
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 235/269
PL/SQL Advanced Techniques - page 2357/10/2013 Copyright 2001 Steven Feuerstein
REMOVE Removes the job from the queue.
RUN Forces immediate execution of the specified job number.
SUBMIT Submits a job to the queue returning a unique job number.
USER_EXPORT Returns the job string for a job number.
WHAT Changes the job string of a job.
Submitting a Job
A job is a call to a stored procedure or an anonymous block – It must end with a semi-colon and can contain “hard-coded”
arguments.
When you submit a job you specify the date on which it should
DECLAREjob# BINARY_INTEGER;
BEGINDBMS_JOB.SUBMIT
(job#, 'calculate_totals;', SYSDATE, 'SYSDATE + 1');END;
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 236/269
PL/SQL Advanced Techniques - page 2367/10/2013 Copyright 2001 Steven Feuerstein
When you submit a job, you specify the date on which it should
next execute, and then the job‟s execution interval (frequency of execution). – In the above example, I run calculate_totals immediately and then on a
daily basis thereafter. Notice that the start time is a DATE expression,while the interval is a string (this is dynamic PL/SQL!)
You can also call DBMS_JOB.ISUBMIT and supply the job number,
instead of having DBMS_JOB generate one for you.
Submit Job Example
DECLAREv_jobno INTEGER;
BEGINDBMS_JOB.submit (
job => v_jobno,
what => 'DBMS_DDL.ANALYZE_OBJECT ' ||'(''TABLE'',''LOAD1'',''TENK''' ||',''ESTIMATE'',null,estimate_percent=>50);',
next_date => TRUNC (SYSDATE + 1),interval => 'TRUNC(SYSDATE+1)');
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 237/269
PL/SQL Advanced Techniques - page 2377/10/2013 Copyright 2001 Steven Feuerstein
This block submits a job that uses a built-in procedure,DBMS_DDL.ANALYZE_OBJECT, to analyze a specific table
every evening at midnight.
p.l (v_jobno);
END;/
DBMS_JOB.ISubmit Job Example
BEGINDBMS_JOB.ISUBMIT
(job => 1,what => 'my_job1(''string_parm_value'',120);',next_date => SYSDATE + 1/24,interval => 'SYSDATE +1');
DBMS_JOB.ISUBMIT(2, 'my_job2(date_IN=>SYSDATE);'
,SYSDATE+1,'SYSDATE+10/1440');
DBMS_JOB.ISUBMIT(3,'BEGIN null; END;',SYSDATE,null);END;/
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 238/269
PL/SQL Advanced Techniques - page 2387/10/2013 Copyright 2001 Steven Feuerstein
This block submits three jobs to the job queue, numbered 1,2,and 3. – Job 1 passes a string and number into procedure MY_JOB1, runs it in one
hour and executes every day thereafter.
– Job 2 passes a date into procedure MY_JOB2, executes for the first timetomorrow and every 10 minutes thereafter.
– Job 3 is a PL/SQL block which does nothing, executes immediately, and
will be removed from the queue automatically.
Specifying Job Times & Frequencies
Probably the most complicated part of using DBMS_JOB is toget the string expression of the job interval right.
– Since it's a string, you must use 2 single quotes to embed strings.
– Use date arithmetic to request intervals smaller than a day.
Every hour 'SYSDATE + 1/24'
'NEXT_DAY (TRUNC (SYSDATE), ''SATURDAY'') +2/24'
Every Sunday at 2AM
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 239/269
PL/SQL Advanced Techniques - page 2397/10/2013 Copyright 2001 Steven Feuerstein
'NEXT_DAY ( ADD_MONTHS (TRUNC (SYSDATE, ''Q''), 3),''MONDAY'') + 9/24'
First Monday of each quarter, at 9AM
'TRUNC (LEAST ( NEXT_DAY (SYSDATE, ''MONDAY''), NEXT_DAY (SYSDATE, ''WEDNESDAY''), NEXT_DAY (SYSDATE, ''FRIDAY''))) + 18/24'
Every Monday,Wednesday andFriday at 6 PM
Other Job Queue Operations
Remove a job from the queue. – Only if the job was submitted from same schema
BEGINFOR rec IN (SELECT * FROM USER_JOBS) LOOP
DBMS_JOB.REMOVE (rec.job);END LOOP;
Run a job immediately. – Performs an implicit COMMIT in current session.
Remove all jobsfor currentschema.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 240/269
PL/SQL Advanced Techniques - page 2407/10/2013 Copyright 2001 Steven Feuerstein
Export jobs from the queue. – Produces a string that can be used to recreate an existing job in the
job queue.
– Uses DBMS_JOB.ISUBMIT, retaining current job number.
expjob.sql
DBMS_JOB.RUN (my_job#);
Job Queue Views
You can also view the job queue by looking at theDBA_JOBS_RUNNING, DBA_JOBS and USER_JOBS views.
– The following query blends job information with session informationto display currently-executing jobs, who owns them and when they
began.
SELECT jr.job job_id ,username username,jr.this_date start_date
h j b d fi i i
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 241/269
PL/SQL Advanced Techniques - page 2417/10/2013 Copyright 2001 Steven Feuerstein
,what job_definition
FROM DBA_JOBS_RUNNING jr,DBA_JOBS j,V$SESSION s
WHERE s.sid = jr.sid AND jr.job = j.job
ORDER BY jr.this_date;
showjobs.sql
Setting up the Job Facility
Make sure that the correct access is set up for theDBMS_JOB package. – The default is PUBLIC access. You will have to take special DBA
action if you want to restrict who can run jobs.
You will need to set three parameters in the init.ora(initialization) file for your database instance: – job_queue_processes=N where n is the number of concurrent
background processes permitted. The valid range is 0 through 36.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 242/269
PL/SQL Advanced Techniques - page 2427/10/2013 Copyright 2001 Steven Feuerstein
g p p g g
– job_queue_interval=N where N is the interval in seconds to checkthe job queue. The valid range is 1 to 3600 (a maximum, therefore, of one hour).
Error Handling with DBMS_JOB
What if your stored procedure fails? – After 16 attempts, the job facility will mark your job as broken.
– Do you want it to try 16 times?
– In addition, if your failure raises an unhandled exception, it may
cause the background processes to fail and no longer run any jobs at all.
To avoid unexpected and unhandled failures of scheduled jobs:
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 243/269
PL/SQL Advanced Techniques - page 2437/10/2013 Copyright 2001 Steven Feuerstein
– Always use the RUN built-in to execute your job in a “test” mode.Then you can go ahead and submit it.
– Always include a WHEN OTHERS exception handler in your jobprogram which traps any and all problems and automatically setsthe job status to broken.
Stopping the Job When It Fails
The WHEN OTHERS exception handler of the calc_totalsprocedure traps any kind of failure
PROCEDURE calc_totals ISBEGIN
...EXCEPTION WHEN OTHERSTHEN
job# := job_pkg.job (‘calc_totals’) DBMS_JOB.BROKEN (job#, TRUE);job_pkg.log (‘calc_totals’, ‘FAIL’);
END;
spacelog.sqlshowspc.sql
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 244/269
PL/SQL Advanced Techniques - page 2447/10/2013 Copyright 2001 Steven Feuerstein
procedure traps any kind of failure.
– Obtains the job number from a packaged function by passing thename of the procedure.
– Uses a call to BROKEN to set the status of the job to “broken”.
– Calls log program of package to record that failure took place.
– Now the job facility will no t try to run this program again. You can go
in and fix the problem.
"Good to Knows" for DBMS_JOB
You may find it useful to always wrap your stored procedure call (thewhat ) inside a BEGIN-END block.
– We've noticed some aberrant, difficult to reproduce behavior at times with"straight" procedure calls.
You will need to fully-qualify all database links (with user name andpassword) to get them to work properly.
If you find that you submit a job to run immediately and it does not start,perform a COMMIT after your submit.
When a job runs it picks up the current execution environment for the
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 245/269
PL/SQL Advanced Techniques - page 2457/10/2013 Copyright 2001 Steven Feuerstein
When a job runs, it picks up the current execution environment for the
user. You can use the DBMS_IJOB to manage the jobs of other users.
– DBMS_JOB only allows you to modify characteristics and behavior of jobssubmitted by the current schema.
DBMS_PIPEInter-session
Built-in Packages: DBMS_PIPE
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 246/269
PL/SQL Advanced Techniques - page 2467/10/2013 Copyright 2001 Steven Feuerstein
Communication
DBMS_PIPE Overview
Allows communication between different Oracle sessionsthrough a pipe in the RDBMS Shared Global Area. – Operates outside of database transaction limitations.
Uses for DBMS_PIPE include: – Parallelization of program execution. Oracle uses database pipes
to parallelize database operations. You can parallelize your owncode.
– More sophisticated debugging inside PL/SQL programs (work
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 247/269
PL/SQL Advanced Techniques - page 2477/10/2013 Copyright 2001 Steven Feuerstein
p gg g p g (around fundamental limitations of DBMS_OUTPUT).
– Interface PL/SQL-database activities with operating systemfunctions and programs written in other languages.
– Perform and commit DML in a separate transaction space fromyour main transaction.
Shared Global Area
Architecture of DBMS_PIPE
A pipe is a named object that uses the System Global Area
“Sue”
Session A
Message Buffer
Message Buffer
Session B
“Bob”
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 248/269
PL/SQL Advanced Techniques - page 2487/10/2013 Copyright 2001 Steven Feuerstein
A pipe is a named object that uses the System Global Area
to provide a non-transaction based conduit of information. – The pipe sends/receives a message, which can be composed of
one or more separate packets, using a maximum of 4096 bytes.
– Names can be up to 128 chars long (do not use names beginningwith “ORA$”. They are reserved for Oracle use).
Processing Flow of DBMS_PIPE
Construct a message from packets of information. – Each packet can be a string, date, number, ROWID or RAW.
– There is just one message buffer per session.
Send the message to a named pipe. – If there isn‟t currently room in the pipe, you can wait for up to
1000 days (or 86400000 seconds) for the pipe to be cleared.
– This is the default , so you should always specify a timeoutperiod.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 249/269
PL/SQL Advanced Techniques - page 2497/10/2013 Copyright 2001 Steven Feuerstein
Receive a message from that pipe. – You can wait for up to 1000 days for a message.
Unpack the message packets and take action. – Separate out the individual packets in the message (again:
string, date or number).pipex1.sqlpipex2.sql
DBMS_PIPE Module OutlineModule Name Description
CREATE_PIPE Creates a PUBLIC or PRIVATE pipe.
NEXT_ITEM_TYPE Returns the datatype of the next item in the piped message.
PACK_MESSAGE Packs an item into the message buffer for your session.
PURGE Empties the contents of a pipe into your local buffer freeing it for removal, making it a candidate for removal with a LRU algorithm.
RECEIVE_MESSAGE Receives a message from pipe and copies to local buffer.
REMOVE_PIPE Removes a pipe explicitly created via CREATE_PIPE.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 250/269
PL/SQL Advanced Techniques - page 2507/10/2013 Copyright 2001 Steven Feuerstein
RESET_BUFFER Clears your buffer so that PACK_MESSAGE and
UNPACK_MESSAGE can work from the first item.
SEND_MESSAGE Sends contents of message buffer to the specified pipe.
UNIQUE_SESSION_NAME Returns name that is unique among all sessions in the database.
UNPACK_MESSAGE
Unpacks the next item from the local message buffer and deposits it intothe specified local variable.
Creating Public and Private Pipes
There are two ways to create pipes: implicitly and explicitly. – Send messages to non-existent pipe impl ic i t ly create it.
– Use CREATE_PIPE to create a pipe expl ic i t ly .
PROCEDURE newpipe ISstat INTEGER;
BEGINstat := DBMS_PIPE.CREATE_PIPE (
pipename => 'bbs', maxpipesize => 20000, private => TRUE);
A li it i b i t ( ibl l t
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 251/269
PL/SQL Advanced Techniques - page 2517/10/2013 Copyright 2001 Steven Feuerstein
An explicit pipe can be pr ivate (accessible only tosessions with matching userID or SYSDBA privileges).
– Specify TRUE for private argument of CREATE_PIPE.
A publ ic pipe is accessible as long as you know its name. – Implicitly-created pipes are always public.
Sending a Message
FUNCTION send_message(pipename IN VARCHAR2,timeout IN INTEGER DEFAULT maxwait, maxpipesize IN INTEGER DEFAULT 8192)
RETURN INTEGER;
FOR month_num IN 1 .. 12LOOP
DBMS_PIPE.PACK_MESSAGE (total_sales (month_num));
END LOOP;
Provide pipe name,seconds you will wait,and new max pipe size
(you can make it bigger,but not smaller).
Fill your message buffer with packets of data.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 252/269
PL/SQL Advanced Techniques - page 2527/10/2013 Copyright 2001 Steven Feuerstein
pipe_stat :=DBMS_PIPE.SEND_MESSAGE (
‘monthly’, 60, 10 * 4096);
IF pipe_stat != 0THEN
RAISE could_not_send;
Send to "monthly" pipe,waiting up to 1 minute,expanding pipe size to 40
Kbytes.
Status of 0 means message was sent.
Receiving and Unpack a Message
First you pull the message from the pipe and place it in buffer with RECEIVE_MESSAGE. – Specify pipe and number of seconds you will wait before you time out.
– Pipe status of 0 means the message was read successfully.
FUNCTION receive_message(pipename IN VARCHAR2, timeout IN INTEGER DEFAULT maxwait)
RETURN INTEGER;
PROCEDURE unpack_message (item OUT VARCHAR2);
PROCEDURE unpack message (item OUT NUMBER);
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 253/269
PL/SQL Advanced Techniques - page 2537/10/2013 Copyright 2001 Steven Feuerstein
PROCEDURE unpack_message (item OUT NUMBER);
PROCEDURE unpack_message (item OUT DATE);
Then you call UNPACK_MESSAGE to extract individual packetsfrom the message. – You need to know the datatype of packet or check it using NEXT_ITEM_TYPE.
A Pipe-based Listener Program Program wakes up every N seconds to read the data from the pipe and
analyze results from assembly line (an intentional "infinite loop"!).
PROCEDURE analyze_assembly_data (every_n_secs IN INTEGER)IS pipe_status INTEGER; prod_total NUMBER;
BEGINLOOP pipe_status :=
DBMS_PIPE.RECEIVE_MESSAGE ('production', every_n_secs);
IF i t t 0
Wait up to N
seconds for thenext report.
If I got something,pass it on to the
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 254/269
PL/SQL Advanced Techniques - page 2547/10/2013 Copyright 2001 Steven Feuerstein
IF pipe_status = 0
THENDBMS_PIPE.UNPACK_MESSAGE (prod_total);analyze_production (SYSDATE, prod_total);
ELSERAISE_APPLICATION_ERROR (
-20000, 'Production data unavailable.');END IF;
END LOOP;END;
computationprogram.
Stop process if data not received.
Unpacking the Message
Since a message can be composed of packets of differentdatatypes you have to make sure that you unpack a
FUNCTION next_item_type RETURN INTEGER;
Value Description or Data type0 No more items in buffer 6 NUMBER9 VARCHAR211 ROWID12 DATE23 RAW
Returns one of the following values:
dbpipe.sqldbpipe.tst
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 255/269
PL/SQL Advanced Techniques - page 2557/10/2013 Copyright 2001 Steven Feuerstein
datatypes, you have to make sure that you unpack apacket into the right kind of variable. Either:
– You know the datatype and therefore can “hard-code” the correctvariable into the call to UNPACK_MESSAGE.
– Or you use the built-in NEXT_ITEM_TYPE to tell you in advance the datatype of the next packet in the message and takeappropriate action.
Parallelizing Your Code with Pipes
Oracle uses DBMS_PIPE to improve RDBMS performance;you can do the same for your application if: – You have multiple CPUs available.
– You have processes which can run in parallel.
Suppose I want to calculate my net profit. In order to do so Imust first compute total sales, total office expenses andtotal compensation. – These programs each take 15 minutes, but are not dependent on
each other.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 256/269
PL/SQL Advanced Techniques - page 2567/10/2013 Copyright 2001 Steven Feuerstein
Without pipes, I must execute them sequentially and incur an elapsed time of 45 minutes before I calculate the profits.
– The CEO is decidedly unhappy about the delay.
Sequential vs. Parallel Execution
Process A Process B Process C
Star t
End
Sequential Execution: Maximum Elapsed Time
S t a r t
Parallel Execution: Minimum Elapsed Time
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 257/269
PL/SQL Advanced Techniques - page 2577/10/2013 Copyright 2001 Steven Feuerstein
Process A Process B Process C
E n d
Parallelizing PL/SQL Execution
The “kick off” programs pass their messages to separatepipes. – Other programs running in the background grab the messages and start
BEGINkick_off_sales_calc;kick_off_exp_calc;kick_off_totcomp_calc;
wait_for_confirmation;calculate_net_profits;END;
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 258/269
PL/SQL Advanced Techniques - page 2587/10/2013 Copyright 2001 Steven Feuerstein
their corresponding calculation program. – When each program is complete, it puts a message (perhaps even a
value) into the pipe.
The “wait” program waits till it receives a message from eachprogram. Then net profits can be computed -- in a much-decreased elapsed time.
Code to Kick Off and Calculate
PROCEDURE kick_off_sales_calc ISstat INTEGER;
BEGINDBMS_PIPE.PACK_MESSAGE (1995);stat := DBMS_PIPE.SEND_MESSAGE (‘sales’);
END;
Send message to startcalculations.
PROCEDURE calculate_sales ISstat INTEGER;
BEGINstat := DBMS_PIPE.RECEIVE_MESSAGE (‘sales’); IF stat = 0THEN
lots of number crunching; Receive the year
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 259/269
PL/SQL Advanced Techniques - page 2597/10/2013 Copyright 2001 Steven Feuerstein
lots_of_number_crunching;
DBMS_PIPE.PACK_MESSAGE (sales$);stat := DBMS_PIPE.SEND_MESSAGE (‘sales’);
ELSEDBMS_PIPE.PACK_MESSAGE (NULL);stat := DBMS_PIPE.SEND_MESSAGE (‘sales’);
END IF;END;
Receive the year,
calculate sales, and sendback the results.
Waiting for Confirmation
PROCEDURE wait_for_confirmationIS
stat INTEGER;BEGINstat := DBMS_PIPE.RECEIVE_MESSAGE (‘sales’); DBMS_PIPE.UNPACK_MESSAGE (sales$);
stat := DBMS_PIPE.RECEIVE_MESSAGE (‘offexp’); DBMS_PIPE.UNPACK_MESSAGE (offexp$);
stat := DBMS_PIPE.RECEIVE_MESSAGE (‘comp’); DBMS_PIPE.UNPACK_MESSAGE (comp$);
END;
Wait for all calculations tofinish.
The order in which youwait is insignificant.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 260/269
PL/SQL Advanced Techniques - page 2607/10/2013 Copyright 2001 Steven Feuerstein
PROCEDURE calculate_net_profits ISBEGIN
net_profits := sales$ - offexp$ - comp$;END;
Perform finalcalculation.
parallel.sql
Other DBMS_PIPE Examples
Simple trace package that sends it output either to screen or to pipe.
– Demonstrates the use of toggles and switches in packages.
watch.pkgp_and_l.pkg
Implementation of a system-wide, in-memory cache. – A request for data is passed to a "central" pipe.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 261/269
PL/SQL Advanced Techniques - page 2617/10/2013 Copyright 2001 Steven Feuerstein
– A listener program grabs the request (including the return pipename), obtains the data, and sends it to the pipe.
– The requester reads the information from the pipe.
syscache.pkgsyscache.tst
DBMS_UTILITY
Built-in Packages: DBMS_UTILITY
GET_TIME
GET_HASH_VALUE
FORMAT_CALL_STACK
. . .
Application
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 262/269
PL/SQL Advanced Techniques - page 2627/10/2013 Copyright 2001 Steven Feuerstein
SCHEMAA „grab-bag‟ of miscellaneousoperations
DBMS_UTILITY Module Outline
ANALYZE_DATABASE Analyze objects in database
ANALYZE_PART_OBJECT Runs ANALYZE TABLE or ANALYZE INDEXfor each partition of the object (Oracle8).
COMMA_TO_TABLE Parses comma-delimited list to index-by table.
COMPILE_SCHEMA Recompile INVALID objects in specified schema.
DATA_BLOCK_ADDRESS_BLOCK Gets block number part of data block address.
DATA_BLOCK_ADDRESS_FILE Gets file number part of data block address.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 263/269
PL/SQL Advanced Techniques - page 2637/10/2013 Copyright 2001 Steven Feuerstein
DB_VERSION Returns database version (Oracle8)
EXEC_DDL_STATEMENT Executes DDL statement (Oracle8).
FORMAT_CALL_STACK Returns execution call stack.
FORMAT_ERROR_STACK Returns error stack.
GET_HASH_VALUE Returns hash value for string.
dbver.pkgdbparm.pkg
DBMS_UTILITY Module Outline, cont.
GET_PARAMETER_VALUE Retrieves value of database parameter (Oracle8).
GET_TIME Returns "current time" down to hundredth of second.
IS_PARALLEL_SERVER Returns TRUE if in parallel server mode.
MAKE_DATA_BLOCK_ADDRESS Creates data block address from block & file numbers.
NAME_RESOLVE Resolves name of object into component parts.
NAME_TOKENIZE Parses string object designator into components.
PORT_STRING Returns platform and version of database.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 264/269
PL/SQL Advanced Techniques - page 2647/10/2013 Copyright 2001 Steven Feuerstein
TABLE_TO_COMMA Converts list (in index-by-table) of elements into acomma-delimited list (string).
Sub-Second Timings with GET_TIME
GET_TIME returns the number of 100ths of seconds thathave elapsed since an arbitrary point in time.
– SYSDATE only reflects times down to the nearest second, soGET_TIME offers significant additional granularity.
– Useful when analyzing individual PL/SQL programs, especiallythose that run in sub-second time.
Compare results from consecutive calls to GET_TIME todetermine the elapsed time of PL/SQL code execution.
DECLARE
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 265/269
PL/SQL Advanced Techniques - page 2657/10/2013 Copyright 2001 Steven Feuerstein
v_start BINARY_INTEGER;BEGIN
v_start := DBMS_UTILITY.GET_TIME; calc_totals;
DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.GET_TIME - v_start);
END;
Basic steps necessaryto convert GET_TIME
into a performanceanalysis tool.
Building a Layer Over GET_TIME
PACKAGE PLVtmrIS
PROCEDURE turn_on;PROCEDURE turn_off;PROCEDURE set_factor (factor_in IN NUMBER);
PROCEDURE capture (context_in IN VARCHAR2 := NULL)
PROCEDURE show_elapsed (prefix_in IN VARCHAR2 := NULL,adjust_in IN NUMBER := 0,reset_in IN BOOLEAN := TRUE);
Partial packagespecification
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 266/269
PL/SQL Advanced Techniques - page 2667/10/2013 Copyright 2001 Steven Feuerstein
ovrhead.sqlplvtmr.spsplvtmr.spb
BEGINPLVtmr.capture; calc_totals;PLVtmr.show_elapsed;
END;
Clean and lean timing code
END PLVtmr;
EXCEPTION WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE (DBMS_UTILITY.FORMAT_CALL_STACK);
END;
Accessing the Execution Call Stack
----- PL/SQL Call Stack -----object line objecthandle number name
88ce3f74 8 package STEVEN.VALIDATE_REQUEST88e49fc4 2 function STEVEN.COMPANY_TYPE88e49390 1 procedure STEVEN.CALC_NET_WORTH88e2bd20 1 anonymous block
Use in theexception
section to showcontext of
error.
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 267/269
PL/SQL Advanced Techniques - page 2677/10/2013 Copyright 2001 Steven Feuerstein
"Little known facts" about FORMAT_CALL_STACK: – Contains embedded new-line characters, equivalent to CHR(10).
– Most recent program at beginning of "report".
– Does no t show package elements, only the package name.
Accessing Call Stack Contents
The call stack length can easily exceed 255 bytes, which means youcannot pass it to DBMS_OUTPUT directly. Instead, use a loop to readthrough the stack.
CREATE OR REPLACE PROCEDURE dispcs ISstk VARCHAR2(10000);next_newline INTEGER;next_line VARCHAR2(255);startpos INTEGER := 1;
BEGINstk := DBMS_UTILITY.FORMAT_CALL_STACK || CHR(10);LOOP
next_newline := INSTR (stk, CHR(10), startpos, 1);EXIT WHEN next_newline = 0;
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 268/269
PL/SQL Advanced Techniques - page 2687/10/2013 Copyright 2001 Steven Feuerstein
next_line := SUBSTR (stk, startpos, next_newline - startpos + 1);
DBMS_OUTPUT.PUT_LINE (next_line);
startpos := next_newline + 1;END LOOP;
END;
dispcs.spdispcs.tst
callstack.pkgplvcs.sps
Resolving Names of Stored Code
Code names have many components; the way they areattached also follows a complicated syntax.
– Use NAME_RESOLVE to break down an identifier string into itscomponents easily.
PROCEDURE DBMS_UTILITY.NAME_RESOLVE(name IN VARCHAR2,context IN NUMBER,schema OUT VARCHAR2, part1 OUT VARCHAR2, part2 OUT VARCHAR2,dblink OUT VARCHAR2,
Possible "Part 1" Types
5 Synonym
7 Procedure
8 Function
7/28/2019 Advanced Techniques.ppt
http://slidepdf.com/reader/full/advanced-techniquesppt 269/269
PL/SQL Advanced Techniques - page 2697/10/2013 Copyright 2001 Steven Feuerstein
part1_type OUT NUMBER,object_number OUT NUMBER); 9 Package
showcomp.sp
snc.pkg
What a chore! All those arguments...but don't see it as a problem,see it as an opportunity...for encapsulation!