Professional Documents
Culture Documents
OracleProf - 2004 - 05
OracleProf - 2004 - 05
Welcome to the
World of Oracle10g
PL/SQL!
Steven Feuerstein and Chip Dawes
In this article, Steven Feuerstein and Chip Dawes offer an overview of the new
Oracle10g PL/SQL features. In future issues of Oracle Professional, they’ll explore
the most interesting or non-trivial of these in more detail.
N
OW is the time for all PL/SQL developers to take a deep breath, let it
out slowly, and thank their lucky stars they’re not DBAs. Oracle has
announced some sweeping changes in database administration with
Oracle10g—namely, that it’s on its way to being a self-managing database! May 2004
While it’s doubtful that many experienced DBAs are worried about Oracle10g Volume 11, Number 5
making them redundant any time soon, it’s not a particularly good sign when
Oracle more or less declares “feature war” on your area of expertise. 1 Welcome to the World of
And even if the self-managing part is a ways off, Oracle10g still (as is the Oracle10g PL/SQL!
Steven Feuerstein and Chip Dawes
case with every new version of the database) requires significant re-tooling
of a DBA’s brains and scripts. Not so for PL/SQL developers. Oracle10g 7 Object Types and Inheritance,
certainly offers us some interesting new features and major new architectural Part 2: Input Channels and
improvements, but almost everything we’ve learned over the years remains Data Transformation
Gary Menchen
relevant—and there isn’t too much new content to absorb.
Oracle10g has several new features that PL/SQL programmers can use 12 Using the Oracle Trace Facility
to improve their programs. The new quoting mechanism will enable you to Dan Hotka
write string literals having embedded quotation marks in a more easily
16 May 2004 Downloads
readable structure. There are new floating point datatypes that offer improved
performance for non-financial calculations. Integer datatypes have a more
efficient internal representation that should improve performance of programs
using them. Compilation has been improved to provide compile-time
warnings, improved optimization, and native compilation. Indicates accompanying files are available online at
www.pinnaclepublishing.com.
There’s a series of new nested table functions that give you, the
programmer, much greater capabilities to use nested that are concerned with rounding errors or require
tables in relational ways. Bulk binds have been improved decimal precision should probably not use these floating
so that you can use sparse collections with them. Regular point datatypes.
expressions have been introduced in Oracle10g and are a
powerful addition to the PL/SQL programmer’s toolkit. You gotta love it: Compile-time warnings!
Oracle10g lets you enable additional compile-time
Programmer-defined quoting mechanism warnings to help make your programs more robust. These
Oracle10g allows you to define your own quoting warnings highlight potential problems that aren’t severe
mechanism for string literals in both SQL and PL/SQL. enough to raise an exception, but may result in runtime
Use the characters q' (q followed by a single quote) to errors or poor performance.
note the programmer-defined delimiter for your string To enable these warnings, you need to set the
literal. Oracle will interpret the character following database initialization parameter plsql_warnings. This
the q' as the delimiter for your string. NCHAR and parameter can be set globally in the spfile, in your session
NVARCHAR delimiters are preceded with the letters with the ALTER SESSION command, or with the built-in
nq, as in nq'^nchar string^'. procedure dbms_warning. The plsql_warnings parameter
This technique can simplify your code when single is a comma-delimited list of values, each of which has
quotes appear within a string, such as the literals in a SQL the syntax:
statement. If you define your delimiter with one of the
four bracketing characters—( [ { <—then you’ll need to [ENABLE | DISABLE | ERROR]:
[ALL|SEVERE|INFORMATIONAL|PERFORMANCE|warning_number]
use the right-hand version of that bracketing character as
the closing delimiter. For example, q' [ will need to be For example, to enable all warnings in your
closed with ]'. Table 1 displays some examples of using session, execute:
this new quoting mechanism.
ALTER SESSION SET plsql_warnings = 'enable:all'
Integer and floating point datatype improvements
Oracle provides a variety of datatypes to store 32-bit If you want to enable warning message number
whole numbers: BINARY_INTEGER, INTEGER, INT, 06002 and all warnings in the performance category
SMALLINT, NATURAL, NATURALN, POSITIVE, except warning number 07202, execute:
POSITIVEN, SIGNTYPE, and PLS_INTEGER. Prior to
ALTER SESSION SET plsql_warnings = 'enable:06002'
Oracle10g, all of these, except PLS_INTEGER, were ,'enable:performance'
manipulated using the same C-language arithmetic ,'disable:07202';
NATURALN and POSITIVEN. SIGNTYPE is restricted to SQL> CREATE OR REPLACE PACKAGE create_policy IS
2 PROCEDURE process_dec_page ( dec_page IN OUT CLOB );
three values (-1, 0, 1). PLS_INTEGER is an unconstrained 3 END create_policy;
subtype (alias) of BINARY_INTEGER. 4 /
Oracle10g introduced IEEE 754 compliant floating SP2-0808: Package created with compilation warnings
point numbers to both SQL and PL/SQL. These subtypes SQL> show err
are the single precision BINARY_FLOAT and the double Errors for PACKAGE CREATE_POLICY:
precision BINARY_DOUBLE. These datatypes require less LINE/COL ERROR
memory and use native machine arithmetic, thus -------- --------------------------------------------
2/32 PLW-07203: parameter 'DEC_PAGE' may benefit from
performing better for scientific or engineering use of the NOCOPY compiler hint
applications that are computation-
intensive or require comparison to Table 1. Examples of using the new quoting mechanism.
infinity or NaN (Not a Number).
These two datatypes have binary Literal using old quoting mechanism Literal using new quoting mechanism Actual value
'TZ=''CDT6CST''' q'(TZ='CDT6CST')' TZ='CDT6CST'
precision instead of the decimal
'''' q'-'-' '
precision used in the NUMBER 'It''s here' q'[It's here]' It's here
family. So, financial applications '''''' nq'^''^' ''
SQL> show err To view all of the compiler settings for your modules,
Errors for PROCEDURE DEAD_CODE:
including optimizer level, interpreted vs. native, and
LINE/COL ERROR compiler warning levels, query the USER_PLSQL_
-------- --------------------------------------------
7/7 PLW-06002: Unreachable code OBJECT_SETTINGS view.
operators, and expressions are demonstrated as follows: IF nt1 SUBMULTISET nt3 THEN
dbms_output.put_line('nt1 is a subset of nt3');
END IF;
DECLARE
TYPE nested_type IS TABLE OF NUMBER; IF SET(nt3) IN (nt1,nt2,nt3) THEN
nt1 nested_type := nested_type(1,2,3); dbms_output.put_line(
nt2 nested_type := nested_type(3,2,1); 'expression is IN the list of nested tables');
nt3 nested_type := nested_type(2,3,1,3); END IF;
nt4 nested_type := nested_type(1,2,4); END;
answer nested_type;
BEGIN
answer := nt1 MULTISET UNION nt4; -- (1,2,3,1,2,4) Improvements to bulk binds
answer := nt1 MULTISET UNION nt3; -- (1,2,3,2,3,1,3) You can use collections to improve the performance of
answer := nt1 MULTISET UNION DISTINCT nt3; -- (1,2,3) SQL operations executed iteratively by using bulk binds.
CARDINALITY(x) NUMBER Returns the number of elements in varray or nested table x. Returns NULL if the collection
is atomically NULL (not initialized).
CAST(k AS t) TYPE t Changes the data type of k to type t—used in conjunction with collect or multiset.
COLLECT (Oracle10g) NESTED TABLE Used in conjunction with CAST to map a column to a collection.
MULTISET NESTED TABLE Used in conjunction with CAST to map a subquery to a collection.
x MULTISET EXCEPT [DISTINCT] y NESTED TABLE Performs a MINUS set operation on nested tables x and y, returning a nested table whose
elements are in x, but not in y. x, y, and the returned nested table must all be of the
same type. The DISTINCT keyword forces the elimination of duplicates from the
returned nested table.
x MULTISET INTERSECT [DISTINCT] y NESTED TABLE Performs an INTERSECT set operation on nested tables x and y, returning a nested table
whose elements are in both x and y. x, y, and the returned nested table must all be of the
same type. The DISTINCT keyword forces the elimination of duplicates from the returned
nested table.
x MULTISET UNION [DISTINCT] y NESTED TABLE Performs a UNION set operation on nested tables x and y, returning a nested table whose
elements include all those in x as well as those in y. x, y, and the returned nested table
must all be of the same type. The DISTINCT keyword forces the elimination of duplicates
from the returned nested table.
SET(x) NESTED TABLE Returns nested table x without duplicate elements.
x IS [NOT]A SET BOOLEAN Returns TRUE [FALSE] if the nested table x is composed of unique elements.
x IS [NOT] EMPTY BOOLEAN Returns TRUE [FALSE] if the nested table x is empty.
e [NOT] MEMBER [OF] x BOOLEAN Returns TRUE[FALSE] if an expression e is a member of the nested table x.
y [NOT] SUBMULTISET [OF] x BOOLEAN Returns TRUE [FALSE] if nested table y contains only elements that are also in nested
table x.
4 Oracle Professional May 2004 www.pinnaclepublishing.com
Bulk binds reduce the number of context switches allow you to specify a subset of rows in a driving
between the PL/SQL engine and the SQL engine. Two collection that will be used in the FORALL statement. To
PL/SQL language constructs implement bulk binds: match the row numbers in the data collection with the
FORALL and BULK COLLECT INTO. row numbers in the driving collection, use the INDICES
The syntax for the FORALL statement is: OF clause. To match the row numbers in the data
collection with the values found in the defined rows of
FORALL bulk_index IN [lower_bound..upper_bound
| INDICES OF collection_variable
the driving collection, use the VALUES OF clause.
[BETWEEN lower_bound AND upper_bound]
| VALUES OF collection_variable ]
[SAVE EXCEPTIONS] Regular expressions
sql_statement; As we mentioned earlier in this article, Oracle10g
supports the use of regular expressions via four new
Bulk_index can be used only in the sql_statement and
built-in functions: REGEXP_LIKE, REGEXP_INSTR,
only as a collection index (subscript). When PL/SQL
REGEXP_SUBSTR, and REGEXP_REPLACE. This
processes this statement, the whole collection, instead of
section provides only a brief description of how regular
each individual collection element, is sent to the database
expressions work; for a tutorial and quick reference, see
server for processing. To delete all of the accounts in the
the Oracle Regular Expressions Pocket Reference, by Jonathan
collection inactives from the table ledger, do this:
Gennick and Peter Linsley (O’Reilly).
FORALL i IN inactives.FIRST..inactives.LAST
DELETE FROM ledger WHERE acct_no = inactives(i); Metacharacters
Regular expressions are found in Unix utilities such as
With Oracle10g, if there are non-consecutive index grep, sed, and the ex editor, in the Perl scripting language,
values due to deletions, you’ll need to use the INDICES and in many other tools. Regular expressions are a
OF syntax to skip over the deleted elements, like this: powerful and popular means of processing text, mainly
because they use metacharacters to facilitate searching for
FORALL i IN INDICES OF inactives
DELETE FROM ledger WHERE acct_no = inactives(i); strings. The metacharacters supported by Oracle are
shown in the Table 3.
With Oracle10g, if you’re interested in the values of a
sparse collection of integers instead of the indices, you’ll REGEXP_LIKE
need to use the VALUES OF syntax, such as: The REGEXP_LIKE function determines whether a
specific column, variable, or text literal contains text
FORALL i IN VALUES OF inactives_list
-- inactives_list is a collection of index values from matching a regular expression. It returns Boolean TRUE if
-- the inactives table which are earmarked for the regular expression is found in the source_string and
deletion
DELETE FROM ledger WHERE acct_no = inactives(i); FALSE if the regular expression isn’t found. The syntax is:
These new INDICES OF and VALUES OF keywords REGEXP_LIKE (source_string, pattern [,match_modifier])
I
N the April 2004 issue of Oracle Professional, I varchar2),
member function getNewLineTokens return stringList,
developed a hierarchy of object types that performed final member procedure initInputChannel
streaming output to various kinds of destinations— ) NOT INSTANTIABLE NOT FINAL
CLOB, BLOB, DBMS_OUTPUT, and so on—and ended /
G
ENERALLY, you need a trace when you’re variables and wait event information):
debugging a particular issue, or trying to solve an
DBMS_SYSTEM.set_sql_trace_in_session
application performance problem. The trace file (<sid>, <serial#>, true);
contains all of the captured SQL, depending on the type DBMS_SUPPORT.start_trace_in_session
( <sid>, <serial#>, waits=>true, binds=>false);
of trace you initiate. Trace files can contain the SQL bind DBMS_SUPPORT.stop_trace_in_session(<sid>, <serial#>);
variables and Oracle wait event information (I covered
wait events in my article “Understanding Oracle Events” OTF also allows you to put an “identifier” into the
in the July 2001 issue). name, which makes finding your trace file much easier
Oracle creates raw trace files in the USER_DUMP_ (see Figure 1). I first learned to use Oracle Trace with
DEST location. Oracle always generates a trace file Oracle7, as this was the only way to see the row counts
upon startup and shutdown. You can initiate a trace for the intermediate explain plan steps at the time.
session at the database level, at the session level, Imagine several people creating trace files around the
programmatically out of a program, for another active same time—more than once, I tried to find my problem
session, and so forth. SQL in the wrong trace file! Use ALTER SESSION SET
Make sure that TIMED_STATISTICS = TRUE is set, TRACE_FILE_IDENTIFIER = 'xxx' to add some text
either for your session that you’re going to run traces to the trace file name. This identifier can be up to 60
from or at the system level. TIMED_STATISTICS doesn’t characters long.
have the extreme overhead it used to. I’d set this to true at To initiate SQL collections (10046 trace) with various
the database level. At the session level, you can enter options, you need to use the syntax shown in Listing 1.
ALTER SESSION SET TIMED_STATISTICS = TRUE for 10046 traces have several options (levels):
the duration of your trace. • 0 = No statistics
Issuing an ALTER SYSTEM SET SQL_TRACE = • 1 = Trace with parse, execute, and fetch statistics
TRUE creates a 10046 dump of all SQL being presented • 4 = Trace with option 1 with the SQL bind
to Oracle. Make sure you have plenty of room in your variable contents
USER_DUMP_DEST location for a dump like this. • 8 = Trace with option 1 with the Oracle wait
Optionally, you can ALTER SESSION SET SQL_TRACE = event information
TRUE at your session level. Then you’d run the SQL • 12 = Options 1, 4, and 8
on which you want to collect
information. ALTER SESSION SET
SQL_TRACE = FALSE turns the trace
facility off and closes the trace file.
A 10046 dump is a trace
containing information about SQL
statements. Later in this article, I’ll
identify several other kinds of traces.
A 10046 extended trace includes
bind variables and/or wait event
information.
Setting trace on for a different
session from yours takes a bit more Figure 1. Oracle trace files in USER_DUMP_DEST.
12 Oracle Professional May 2004 www.pinnaclepublishing.com
The syntax in Listing 1 shows how to set a 10046
enhanced SQL trace. Substitute your SQL for the “Hello
World” SQL example. This example will make a trace file
in the USER_DUMP_DEST with the identifier 'HOTKA' in
the file name and collect both bind variables and Oracle
wait events for the SQL presented in the session for which
this was initiated.
Figure 8. TKPROF sort options. Figure 9. Final TOAD Tkprof Interface wizard step.
Pinnacle, A Division of Lawrence Ragan Communications, Inc. ▲ 800-493-4867 x.4209 or 312-960-4100 ▲ Fax 312-960-4106
For access to current and archive content and source code, log in at www.pinnaclepublishing.com.
Subscription rates This publication is intended as a general guide. It covers a highly technical and complex
subject and should not be used for making decisions concerning specific products or
applications. This publication is sold as is, without warranty of any kind, either express or
United States: One year (12 issues): $199; two years (24 issues): $348 implied, respecting the contents of this publication, including but not limited to implied
Other:* One year: $229; two years: $408 warranties for the publication, performance, quality, merchantability, or fitness for any particular
purpose. Lawrence Ragan Communications, Inc., shall not be liable to the purchaser or any
Single issue rate: other person or entity with respect to any liability, loss, or damage caused or alleged to be
caused directly or indirectly by this publication. Articles published in Oracle Professional
$27.50 ($32.50 outside United States)* reflect the views of their authors; they may or may not reflect the view of Lawrence Ragan
Communications, Inc. Inclusion of advertising inserts does not constitute an endorsement by
* Funds must be in U.S. currency. Lawrence Ragan Communications, Inc., or Oracle Professional.