Best of Oracle PLSQL 11g

download Best of Oracle PLSQL 11g

of 311

Transcript of Best of Oracle PLSQL 11g

  • 8/15/2019 Best of Oracle PLSQL 11g

    1/311

    Oracle PL/SQL Programming

    Sponsored by AMIS

    Steven [email protected]

    www.StevenFeuerstein.com

    The Best of Oracle PL/SQLMust Know Features,

    Best Practices andNew Features in Oracle Database 11g

    http://www.stevenfeuerstein.com/http://www.stevenfeuerstein.com/

  • 8/15/2019 Best of Oracle PLSQL 11g

    2/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 2

    Best of Oracle PL/SQL Agenda

    • Runtime Memory Management and PL/SQL• The Oracle Database 10g compiler

    – Optimization, warnings, conditional compilation

    • Collections: foundation for newest and bestfeatures• Bulk Processing

    – BULK COLLECT and FORALL• Table Functions• Dynamic SQL in PL/SQL

  • 8/15/2019 Best of Oracle PLSQL 11g

    3/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 3

    Best of Oracle PL/SQL Agenda - continued

    • "Must Know" error management features – DBMS_UTILITY functions – DBMS_ERRLOG and LOG ERRORS

    • Oracle Database 11g features – Function Result Cache – Trigger enhancements – Dynamic SQL enhancements

    • Say Goodbye to Hard-coding – Hide implementations – Extreme Modularization

  • 8/15/2019 Best of Oracle PLSQL 11g

    4/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 4

    How to benefit most from this training• Watch, listen, ask questions, focus on concepts and principles.• Download and use any of my training materials:

    You have my permission to use all these materials to dointernal trainings and build your own applications. – But remember: they are not production ready. – You must test them and modify them to fit your needs.

    filename_from_demo_zip.sql

    Download and use any of my scripts (examples,performance scripts, reusable code) from the samelocation: the demo.zip file.

    http://www.ToadWorld.com/SFPL/SQL Obsession

  • 8/15/2019 Best of Oracle PLSQL 11g

    5/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 5

    Websites for PL/SQL Developers

    www.plsqlchallenge.com Daily PL/SQL quiz with weekly andmonthly prizes

    www.plsqlchannel.com 27+ hours of detailed video training

    on Oracle PL/SQL

    www.stevenfeuerstein.com Monthly PL/SQL newsletter

    www.toadworld.com/SF Quest Software-sponsored portalfor PL/SQL developers

    http://www.plsqlchallenge.com/http://www.plsqlchannel.com/http://www.stevenfeuerstein.com/http://www.toadworld.com/SFhttp://www.toadworld.com/SFhttp://www.stevenfeuerstein.com/http://www.plsqlchannel.com/http://www.plsqlchallenge.com/

  • 8/15/2019 Best of Oracle PLSQL 11g

    6/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 6

    Analyze memory usage of PL/SQL code

    • It is certainly possible to write PL/SQL codethat consumes so much memory, it kills auser's session.

    – It's quite easy to do, in fact.• As you work with more advanced features, like

    collections and FORALL, you will need to pay

    attention to memory, and make adjustments.• First, let's review how Oracle managesmemory at run-time.

    memory_error.sql

  • 8/15/2019 Best of Oracle PLSQL 11g

    7/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 7

    System Global Area (SGA) of RDBMS Instance

    PL/SQL in Shared Memory

    Shared Pool

    Large Pool

    Reserved Pool

    show_empscalc_totals upd_salaries

    Select *from emp

    Shared SQL

    Pre-parsed

    Update empSet sal=...

    Library cache

    Session 1 memory(PGA/UGA)

    emp_rec emp%rowtype;tot_tab tottabtype;

    Session 2 memory(PGA/UGA)

    emp_rec emp%rowtype;tot_tab tottabtype;Session 1

    Session 2

  • 8/15/2019 Best of Oracle PLSQL 11g

    8/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 8

    How PL/SQL uses the SGA, PGA and UGA

    • The SGA contains information that can be sharedacross sessions connected to the instance. – In PL/SQL, this is limited to package static constants.

    • The User Global Area contains session-specific datathat persists across server call boundaries – Package-level data

    • The Process Global Area contains session-specificdata that is released when the current server callterminates: "local" data.

    PACKAGE Pkg is /* 11g feature! */ Nonstatic_Constant CONSTANT PLS_INTEGER := My_Sequence.Nextval;Static_Constant CONSTANT PLS_INTEGER := 42;

    END Pkg;

  • 8/15/2019 Best of Oracle PLSQL 11g

    9/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 9

    Calculating PGA and UGA Consumption

    • Oracle keeps track of and shows the PGA and

    UGA consumption for a session in thev_$sesstat dynamic view.• With the correct privileges, PL/SQL developers

    can analysis their code's memory usage.show_pga_uga.sql

    grantv$.sqlplsql_memory.pkg

    plsql_memory_demo.sql

    SELECT n.name, s.VALUE

    FROM sys.v_$sesstat s, sys.v_$statname nWHERE s.statistic# = n.statistic# AND s.sid = my_session.sidAND n.name IN ('session uga memory', 'session pga memory')

    BEGINplsql_memory.start_analysis;run_my_application;plsql_memory.show_memory_usage;

    END;

  • 8/15/2019 Best of Oracle PLSQL 11g

    10/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 10

    Tips for managing memory

    • Use LIMIT clause with BULK COLLECT.• Use varrays with BULK COLLECT to

    declaratively guard against "memory creep."•

    Use NOCOPY hint when passing IN OUTcollections.• Be very careful about defining variables at

    the package level. – Memory will not be released when the block

    terminates.• Use pipelined table functions.

    bulklimit.sqlvarray_collection_limit.sql

    nocopy*.tsttabfunc_pipelined.sql

  • 8/15/2019 Best of Oracle PLSQL 11g

    11/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 11

    Conclusions

    • Oracle takes responsibility for managing memoryused for data (user data and "metadata" – program code, table definitions, etc.) shared bymultiple connections. – Based on parameter set by DBAs.

    • It is up to developers and DBAs to determine howmuch PGA memory can be used per connection.

    • Then developers must make the necessarychanges in their code to conform to that limit.

  • 8/15/2019 Best of Oracle PLSQL 11g

    12/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 12

    Fully Leverage the Oracle10g PL/SQL Compiler

    • Oracle demonstrated its long-termcommitment to PL/SQL with the relesae ofOracle Database 10g – Many new features and a complete re-write of

    the compiler.• Automatic, transparent optimization of code• Compile-time warnings framework to help

    you improve the quality of your code.• Conditional compilation: you decide what

    code should be compiled/ignored!

  • 8/15/2019 Best of Oracle PLSQL 11g

    13/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 13

    The Optimizing Compiler• The PL/SQL compiler now has the ability to

    automatically optimize your code. – The compiler rearranges your code. – Compile time increases, runtime performance improves.

    • You choose the level of optimization : – 0 Pre-10g compilation without optimization – 1 Smaller scale change, less impact on compile times – 2 Most aggressive, maximum possible code transformations,

    biggest impact on compile time. [default]

    – 3 (Oracle11g) In-lining of local subprograms, in addition to all theoptimization performed at level 2

    • Stick with the default, unless you have a clear needfor an exception.

  • 8/15/2019 Best of Oracle PLSQL 11g

    14/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 14

    The PL/SQL Optimizer: High Level View•

    The optimizer takes advantage of "freedoms" to re-order the execution of statements. – In essence, changing the route that the runtime engine

    takes to get from point A to point B in your code.• Some examples:

    – Unless otherwise specified, the operands of an expressionoperator may be evaluated in any order.

    – Operands of a commutative operator may be commuted. – The actual arguments of a call or a SQL statement may be

    evaluated in any order (including default actualarguments).

    • Optimization does not change the logical behavior ofyour code. – Optimization should not, for example, cause any of your

    regression tests to suddenly fail!

  • 8/15/2019 Best of Oracle PLSQL 11g

    15/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 15

    Some Examples... A + B ......... A + B ...

    T := A + B;

    ... T ......

    ... T ...

    T is a generated variable. We never seeit. And one operation is saved.

    for i in 1 .. 10 loopA := B + C;...

    end loop;

    A := B + C;for i in 1 .. 10 loop

    ...end loop;

    Automatic relocation of a loop invariant. Avoid repetitive computations.

    10g_optimize_cfl.sql

    FOR rec in (SELECT ...)LOOP

    ... do stuffEND LOOP;

    SELECT ...BULK COLLECT INTO ...FROM ...

    Execute cursor FOR loopat BULK COLLECTlevels of performance.

  • 8/15/2019 Best of Oracle PLSQL 11g

    16/311

  • 8/15/2019 Best of Oracle PLSQL 11g

    17/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 17

    Changing the optimizer level

    • Oracle retains optimizer settings on amodule-by-module basis. – When you recompile a particular module with

    non-default settings, the settings will "stick,"allowing you to recompile later using REUSESETTINGS. For example:

    • and then:ALTER PROCEDURE bigproc COMPILE PLSQL_OPTIMIZE_LEVEL = 1;

    ALTER PROCEDURE bigproc COMPILE REUSE SETTINGS;

  • 8/15/2019 Best of Oracle PLSQL 11g

    18/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 18

    Oracle11g In-lining optimization•

    A new level, 3, tells Oracle to automatically searchout opportunities to "inline" code for nestedsubprograms. – This means that a pointer to the subprogram is replaced

    with the implementation of the subprogram.• Oracle's own tests have shown 10-20%

    performance improvement. – Depends on how many local modules you create and

    how often they are used.• Note: compile code size increases.

    ALTER SESSION SET PLSQL_OPTIMIZE_LEVEL = 3;

    11g_inline*.sql

    11g

  • 8/15/2019 Best of Oracle PLSQL 11g

    19/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 19

    Selective Inlining with PRAGMA

    • You can also keep the optimization level at 2 andrequest inlining explicitly for specific subprograminvocations with a new INLINE pragma.

    • Inlining applies to the following statements: – Assignment, CALL, conditional, CASE, CONTINUE-WHEN,

    EXECUTE IMMEDIATE, EXIT-WHEN, LOOP, RETURN• You can also request inlining for all executions of the

    subprogram by placing the PRAGMA before thedeclaration of the subprogram.• Inlining, like NOCOPY, is a request.

    – Under some circumstances, inlining will not take place.

    11g

    PRAGMA INLINE (subprogram, 'YES')

  • 8/15/2019 Best of Oracle PLSQL 11g

    20/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 20

    Inlining Could Slow Down Code

    • Oracle warns that inlining occurs early in theoptimization process and may "preclude later,more powerful optimizations."

    • If you find that inlining is slowing down aprogram unit, profile execution to identifysubprograms for which to turn off inlining. – Oracle recommends the new-to-11g hierarchical

    profiler, DBMS_HPROF.• Selectively disable inlining with pragma:

    PRAGMA INLINE (subprogram, 'NO')

    11g

  • 8/15/2019 Best of Oracle PLSQL 11g

    21/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 21

    Learn more about the PL/SQL optimizer

    • PL/SQL Just Got Faster – Explains the workings of the PL/SQL compiler and runtime system and

    shows how major improvements on this scale are indeed possible.

    • Freedom, Order, and PL/SQL Optimization – Intended for professional PL/SQL programmers, explores the use and

    behavior of the new compiler.

    • PL/SQL Performance — Debunking the Myths – Re-examines some old notions about PL/SQL performance.

    • PL/SQL Performance Measurement Harness – Describes a performance experiment whose conclusion is the large factors

    quoted above. Oracle provides a downloadable kit to enable you torepeat the experiment yourself.

    http://www.oracle.com/technology/tech/pl_sql/htdocs/new_in_10gr1.htm

    http://www.oracle.com/technology/tech/pl_sql/htdocs/new_in_10gr1.htmhttp://www.oracle.com/technology/tech/pl_sql/htdocs/new_in_10gr1.htmhttp://www.oracle.com/technology/tech/pl_sql/htdocs/new_in_10gr1.htmhttp://www.oracle.com/technology/tech/pl_sql/htdocs/new_in_10gr1.htmhttp://www.oracle.com/technology/tech/pl_sql/htdocs/new_in_10gr1.htmhttp://www.oracle.com/technology/tech/pl_sql/htdocs/new_in_10gr1.htmhttp://www.oracle.com/technology/tech/pl_sql/htdocs/new_in_10gr1.htmhttp://www.oracle.com/technology/tech/pl_sql/htdocs/new_in_10gr1.htmhttp://www.oracle.com/technology/tech/pl_sql/htdocs/new_in_10gr1.htmhttp://www.oracle.com/technology/tech/pl_sql/htdocs/new_in_10gr1.htmhttp://www.oracle.com/technology/tech/pl_sql/htdocs/new_in_10gr1.htmhttp://www.oracle.com/technology/tech/pl_sql/htdocs/new_in_10gr1.htmhttp://www.oracle.com/technology/tech/pl_sql/htdocs/new_in_10gr1.htmhttp://www.oracle.com/technology/tech/pl_sql/htdocs/new_in_10gr1.htmhttp://www.oracle.com/technology/tech/pl_sql/htdocs/new_in_10gr1.htmhttp://www.oracle.com/technology/tech/pl_sql/htdocs/new_in_10gr1.htmhttp://www.oracle.com/technology/tech/pl_sql/htdocs/new_in_10gr1.htmhttp://www.oracle.com/technology/tech/pl_sql/htdocs/new_in_10gr1.htmhttp://www.oracle.com/technology/tech/pl_sql/htdocs/new_in_10gr1.htm

  • 8/15/2019 Best of Oracle PLSQL 11g

    22/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 22

    Warnings help you build better code• Your code compiles without errors. Great, you

    can run that program!• But does it use the PL/SQL language optimally ?• In Oracle 10g, Oracle added a compile-time

    warnings framework. – Automatically informs you of ways to improve the

    quality or performance of your code.

    • All warnings shown in Error Messages manual,with the PLW prefix. http://tahiti.oracle.com

    O l SQ i

  • 8/15/2019 Best of Oracle PLSQL 11g

    23/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 23

    Enable and Disable Warnings• To use compiler warnings, you must turn them

    on for session or for a particular program unit. – By default, warnings are disabled.

    • Can specify individual warnings or categories.

    ALTER SESSION [ENABLE | DISABLE |ERROR]:[ALL|SEVERE|INFORMATIONAL|PERFORMANCE|warning_number]

    REM To enable all warnings in your session:ALTER SESSION SET plsql_warnings = 'enable:all ‘;

    REM If you want to enable warning message number 06002 and all warnings inREM the performance category, and treat 5005 as a "hard" compile error:ALTER PROCEDURE my_procedure SET plsql_warnings =

    'enable:06002', 'enable:performance', 'ERROR:05005';

    O l PL/SQL P i

  • 8/15/2019 Best of Oracle PLSQL 11g

    24/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 24

    Checking for Warnings

    • The USER_ERRORS data dictionary view showsboth "hard" errors and compilation warnings.

    • Use the SHOW ERRORS command in SQL*Plus.

    • IDEs will usually display warnings within theedit window.

    • Or run your own query against USER_ERRORS.

    O l PL/SQL P i

  • 8/15/2019 Best of Oracle PLSQL 11g

    25/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 25

    Example: check for unreachable code• There may be lines of code that could never, ever

    execute.SQL> CREATE OR REPLACE PROCEDURE unreachable_code IS2 x NUMBER := 10;3 BEGIN4 IF x = 10 THEN5 x := 20;6 ELSE7 x := 100; -- unreachable code8 END IF;9 END unreachable_code;10 /SP2-0804: Procedure created with compilation warnings

    SQL> show errErrors for PROCEDURE UNREACHABLE_CODE:

    LINE/COL ERROR-------- -------------------------------------7/7 PLW-06002: Unreachable code

    plw6002.sql

    O l PL/SQL P i11

  • 8/15/2019 Best of Oracle PLSQL 11g

    26/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 26

    New Warnings in Oracle Database 11g•

    PLW-6017: something's going to raise an error! – Such as VARCHAR2(1) := 'abc'....FINALLY!• PLW-6009: OTHERS exception handler does not re-

    raise an exception.• More feedback on impact of optimization

    – PLW-6007: Notification that entire subprograms wereremoved

    • PLW-7205: warning on mixed use of integer types – Namely, SIMPLE_INTEGER mixed with PLS_INTEGER and

    BINARY_INTEGER• PLW-7206: unnecessary assignments• Lots of PRAGMA INLINE-related warnings

    plw*.sql files

    11g

    O l PL/SQL P g i g11

  • 8/15/2019 Best of Oracle PLSQL 11g

    27/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 27

    Finally, Oracle warns me of too-large value

    • One big frustration I have had with compile-

    time warnings is that it did not flag code likeyou see above. What could be more basic?

    • This is finally addressed – sort of – in

    Oracle11g with the PLW-06017 warning.

    CREATE OR REPLACE PROCEDURE plw6017IS

    c VARCHAR2 (1) := 'abc';BEGIN

    plw6017.sql

    PLW-06017: an operation will raise an exception

    11g

  • 8/15/2019 Best of Oracle PLSQL 11g

    28/311

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    29/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 29

    Watch out for "false negatives" and"nuisances" warnings

    • The check for unreachable code is not veryuseful/reliable prior to Oracle11g.

    – Shows as "unreachable" code that is removed bythe optimizer.• You might be overwhelmed by warnings about

    which you don't really care. – Example: missing AUTHID clause

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    30/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 30

    Conclusions - Compile-time Warnings

    • Review the available warnings. Identify thosewhich of greatest importance to you. – And with each new release of Oracle check for

    additions.• Consider setting up scripts to enable different

    sets of warnings to match differentdevelopment scenarios and to ignore those"nuisance" warnings.

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    31/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 31

    Conditional Compilation• Compile selected parts of a program based on

    conditions you provide with various compilerdirectives .

    • Conditional compilation will allow you to: – Write code that will compile and run under different

    versions of Oracle (relevant for future releases). – Run different code for test, debug and production

    phases. That is, compile debug statements in and out ofyour code.

    –Expose private modules for unit testing.• First released in Oracle Database 10g Release 2

    – Also implemented in later patch sets of 10gR1, plus 9iR2(contact Oracle Support for details)

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    32/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 32

    A finely-nuanced feature of PL/SQL•

    Conditional compilation affects how your codeis compiled and therefore executed.• It is not something to employ casually.

    –This training will serve as an introduction .

    • Before using conditional compilation, check outOTN's detailed whitepaper on the topic. –

    100 pages covering all common use cases – See URL below or search for "conditionalcompilation white paper".

    http://bit.ly/eXxJ9Q

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    33/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 33

    Three types of compiler directives• Inquiry directives: $$identifier

    – Use the $$identifier syntax to refer to conditionalcompilation flags. These inquiry directives can bereferenced within an $IF directive, or usedindependently in your code.

    • Selection directives: $IF – Use the $IF directive to evaluate expressions and

    determine which code should be included or avoided. – Can reference inquiry directives and package static

    constants.•

    Error directives: $ERROR – Use the $ERROR directive to report compilation errorsbased on conditions evaluated when the preprocessorprepares your code for compilation.

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    34/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 34

    Example: toggle inclusion of tracing• Set up conditional compilation of debugging and

    tracing with special "CC" flags that are placed intothe compiler settings for a program. – Only integer and Boolean values are allowed.

    ALTER SESSION SET PLSQL_CCFLAGS = 'oe_debug:true, oe_trace_level:10'/

    CREATE OR REPLACE PROCEDURE calculate_totalsISBEGIN$IF $$oe_debug AND $$oe_trace_level >= 5$THEN

    DBMS_OUTPUT.PUT_LINE ('Tracing at level 5 or higher');$ENDapplication_logic;

    END calculate_totals;/

    cc_debug_trace.sqlcc_expose_private.sql

    cc_max_string.sqlcc_plsql_compile_settings.sql

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    35/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 35

    Access to post-processed code• You can display or retrieve post-processed code with the

    DBMS_PREPROCESSOR package. – Oracle is careful to preserve both horizontal and vertical

    whitespace so runtime stack and error informationcorrelates to your actual source code.

    CREATE OR REPLACE PROCEDUREpost_processed

    ISBEGIN

    IF PLSQL_OPTIMIZE_LEVEL = 1THEN

    -- Slow and easyNULL;

    ELSE-- Fast and modern and easyNULL;

    ENDEND post_processed;/

    BEGINDBMS_PREPROCESSOR.PRINT_POST_PROCESSED_SOURCE('PROCEDURE', USER, 'POST_PROCESSED');

    END;/

    PROCEDURE post_processedISBEGIN

    -- Fast and modern and easyNULL;

    END post_processed;

    cc_postprocessed.sql

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    36/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 36

    Error directive example• If my program has been compiled with

    optimization level 1 (less aggressive) or 0(disabled), then raise an error. – You can in this way add "meta-requirements" to

    your code definitions.SQL> CREATE OR REPLACE PROCEDURE long_compilation

    2 IS3 BEGIN4 $IF $$plsql_optimize_level < 25 $THEN

    6 $error 'Program must be compiled with full optimization' $end7 $END8 NULL;9 END long_compilation;

    10 /

    cc_opt_level_check.sql

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    37/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 37

    Using DBMS_DB_VERSION

    • This package, present in any Oracle Databaseversion supporting conditional compilation, containsa set of Boolean constants showing absolute andrelative version information.

    PROCEDURE insert_rows ( rows_in IN otn_demo_aat ) ISBEGIN$IF DBMS_DB_VERSION.VER_LE_10_1$THEN

    BEGIN...FORALL indx IN 1 .. l_dense.COUNT

    INSERT INTO otn_demo VALUES l_dense (indx);END;

    $ELSEFORALL indx IN INDICES OF rows_in

    INSERT INTO otn_demo VALUES rows_in (indx);$END

    cc_bf_or_number.sqlcc_version_check.sql

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    38/311

    Oracle PL/SQL Programming

    Copyright 2011 Feuerstein and Associates Page 38

    Conclusions – Conditional Compilation

    • Conditional compilation is a very powerful anduseful feature.

    • It is not terribly difficult to learn, but it is hard

    for developers to be confident of working withand maintaining code that contains "$" syntaxelements.

    • Most important: keep it in mind when youencounter a clear and compelling use case,such as writing code that must run undermultiple versions of Oracle.

  • 8/15/2019 Best of Oracle PLSQL 11g

    39/311

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    40/311

    Q g g

    Copyright 2011 Feuerstein and Associates Page 40

    PL/SQL Collections

    • Collections are single-dimensioned lists ofinformation, similar to 3GL arrays.• They are an invaluable data structure.

    – All PL/SQL developers should be very comfortablewith collections and use them often.

    • Collections take some getting used to. – They are not the most straightforward

    implementation of array-like structures. – Advanced features like string indexes and multi-

    level collections can be a challenge.

  • 8/15/2019 Best of Oracle PLSQL 11g

    41/311

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    42/311

    Q g g

    Copyright 2011 Feuerstein and Associates Page 42

    What is a collection?

    • A collection is an "orderedgroup of elements, all of thesame type." (PL/SQL UserGuide) – In short, a list of "stuff"

    • Collections are similar to single-dimensional arrays in other

    programming languages. – With lots of subtle differences, aswell.

    1 Apple

    22 Pear

    100 Orange

    10023 Apricot

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    43/311

    g g

    Copyright 2011 Feuerstein and Associates Page 43

    Why use collections?

    • Generally, to manipulate lists of information. – Of course, you can use relational tables, too. – Collection manipulation is generally much faster

    than using SQL to modify the contents of tables .• Collections enable other key features of PL/SQL

    – BULK COLLECT and FORALL use them to boostmulti-row SQL performance

    – Serve up complex datasets of information to non-PL/SQL host environments using table functions .

  • 8/15/2019 Best of Oracle PLSQL 11g

    44/311

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    45/311

    Copyright 2011 Feuerstein and Associates Page 45

    Memory Management and Collections•

    Memory for collections (and almost all PL/SQLdata structures) is allocated from the PGA(Process Global Area).

    • Accessing PGA memory is quicker than

    accessing SGA memory. – Sometimes much, much faster.• Collections represent a very clear tradeoff: use

    more memory (per session) to improve

    performance. – But you definitely need to keep an eye on your

    PGA memory consumption.plsql_memory*.*

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    46/311

    Copyright 2011 Feuerstein and Associates Page 46

    Different Types of Collections

    • Three types of collections – Associative array – Nested table –

    Varray (varying arrays)• Associative array is a PL/SQL-only datatype.• Nested tables and varrays can be used within

    PL/SQL blocks and also from within the SQLlayer.

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    47/311

    Copyright 2011 Feuerstein and Associates Page 47

    Glossary of Terms• Element

    – A collection is made up of one or more elements, all of the sametype. Also referred to as "row."

    – Can be of almost any valid PL/SQL type.• Index value

    – The "location" in the collection in which an element is found. Alsoreferred to as "row number." – Usually an integer, can also be a string (associative arrays only)

    • Dense – Every index value between lowest and highest has a defined

    element.• Sparse

    – One or more elements between lowest and highest index valuesmay be undefined (gaps).

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    48/311

    Copyright 2011 Feuerstein and Associates Page 48

    Defining collection types

    • Before you can manipulate a collection variable ,you need a collection type on which to declarethe variable.

    • Oracle pre-defines several collection types invarious supplied packages.

    • DBMS_SQL – Dynamic SQL-specific types –

    Generic types (list of strings, numbers, etc.).• DBMS_OUTPUT – List of strings

    $RDBMS_HOME\RDBMS\Admin\dbmssql.sql

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    49/311

    Copyright 2011 Feuerstein and Associates Page 49

    Defining collection types• Declare all collection type with a TYPE statement.• Associative arrays use IS TABLE OF and the INDEX BY

    clause.• Nested tables use IS TABLE OF, without any indexing

    clause.• Varrays use IS VARRAY OF syntax.

    TYPE coll_name IS TABLE OF element_type INDEX BY index_type;

    TYPE coll_name IS TABLE OF element_type;

    TYPE coll_name IS VARRAY ( limit ) OF element_type;

    Association array type

    Nested table type

    Varray type

  • 8/15/2019 Best of Oracle PLSQL 11g

    50/311

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    51/311

    Copyright 2011 Feuerstein and Associates Page 51

    Local collection types

    • TYPE statement found in declaration sectionof block (anonymous, nested, subprogram)• It is defined and then destroyed each time the

    block is executed.• You should avoid local types; it will likely lead

    to redundancies in your code.

    DECLARE

    TYPE strings_t IS TABLE OF VARCHAR2(100);

    PROCEDURE my_procedureIS

    TYPE strings_t IS TABLE OF VARCHAR2(100);

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    52/311

    Copyright 2011 Feuerstein and Associates Page 52

    Package-level Types

    • When defined in the package specification, itbecomes a "globally" available type. – Any session with EXECUTE authority on the package

    can use the type to declare collections.• In the package body, can only be used by

    subprograms of that package.• Excellent repository for application-specific types

    PACKAGE my_types

    ISTYPE strings_t IS TABLE OF VARCHAR2(100);

    colltypes.pks

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    53/311

    Copyright 2011 Feuerstein and Associates Page 53

    Schema-level Types

    • Defined in the schema, independent of anyPL/SQL program unit.

    • Any session with EXECUTE authority on type canuse it to declare collection variables. – Collections of this type can also be directly referenced

    inside SQL statements.• Can only be used with nested tables and varrays.

    – Associative arrays are PL/SQL-specific, cannot bedefined at the schema level (SQL layer).

    CREATE OR REPLACE TYPE strings_t IS TABLE OF VARCHAR2(100)

    GRANT EXECUTE ON strings_t TO PUBLIC

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    54/311

    Copyright 2011 Feuerstein and Associates Page 54

    Declaring collection variables

    • Once you have defined your collection type,you can define a variable based on that. – The same as for any type of data in PL/SQL

    CREATE TYPE hire_dates_t IS TABLE OF DATE;

    CREATE PACKAGE my_types ISTYPE strings_t IS TABLE OF VARCHAR2(100);

    END my_types;

    DECLAREl_names my_types.string_t;l_dates hire_dates_t;l_dates HR.hire_dates_t;l_strings DBMS_SQL.varchar2_table;

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    55/311

    Copyright 2011 Feuerstein and Associates Page 55

    Collection Methods• The term method is used to describe

    procedures and functions that defined in a classor object type. – You invoke a method by attaching it, using dot

    notation, to the name of the type/class or to aninstance of the class.• Collection methods are procedures and

    functions that are attached to a collectionvariable. – First introduction of object-oriented syntax in

    PL/SQL – way back in Oracle 7.3.4!

    method_vs_proc.sql

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    56/311

    Copyright 2011 Feuerstein and Associates Page 56

    Methods that retrieve information• COUNT: number of elements currently defined

    in collection.• EXISTS: TRUE if the specified index values is

    defined.

    • FIRST/LAST: lowest/highest index values ofdefined rows.• NEXT/PRIOR: defined index value after/before

    the specified index value .• LIMIT: max. number of elements allowed in a

    VARRAY.

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    57/311

    Copyright 2011 Feuerstein and Associates Page 57

    The COUNT Method

    • Returns 0 if the collection is empty.• Otherwise returns the number of defined

    index values.

    • You cannot ask for a count of elementsbetween a range of index values. Too bad...

    BEGIN

    IF my_collection.COUNT > 0THEN/* We have some data in the collection */...

    END IF;

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    58/311

    Copyright 2011 Feuerstein and Associates Page 58

    Checking for element existence

    • If you try to read an element at an undefinedindex value, Oracle raises theNO_DATA_FOUND exception. – A poor decision on Oracle's part.

    • Use the EXISTS method to check to see if theindex value is defined.BEGIN

    IF my_collection.EXISTS (l_index)THEN

    DBMS_OUTPUT.PUT_LINE (my_collection (l_index));END IF;

    collection_exists.sqlplsqlloops.sp

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    59/311

    Copyright 2011 Feuerstein and Associates Page 59

    Navigating Through Collections

    • One of the most common actions on collectionsis looping through the contents.

    • You can use WHILE, simple and FOR loops to

    perform this navigation.• The characteristics of your collection will

    determine which sort of loop to use.

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    60/311

    Copyright 2011 Feuerstein and Associates Page 60

    Choose the Right Loop

    • FOR loop – Only use this loop when you want to iterate

    through every element between the low and highindex values.

    – Do not use with sparse collections.• WHILE and simple loops

    – Best fit for sparse collections and when you wantto conditionally exit from your loop.

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    61/311

    Copyright 2011 Feuerstein and Associates Page 61

    Navigation methods and FOR loops

    • With FOR loops, you will use: – COUNT – when the first index value in thecollection is 1.

    – FIRST and LAST when FIRST may not be one.BEGIN

    FOR indx IN 1 .. my_collection.COUNTLOOP

    do_something_with (my_collection (indx));END LOOP;

    END;

    BEGINFOR indx IN my_collection.FIRST .. my_collection.LASTLOOP

    do_something_with (my_collection (indx));END LOOP;

    END;

    plsqlloops.sp

  • 8/15/2019 Best of Oracle PLSQL 11g

    62/311

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    63/311

    Copyright 2011 Feuerstein and Associates Page 63

    The LIMIT Method• Only the varray has a pre-defined upper limit

    on the number of elements that can definedin it. – Well, the other collections types theoretically have

    an upper limit, but you'll never reach it.• Use the LIMIT method to determine what that

    limit is.DECLARE

    TYPE max_of_five_t IS VARRAY (5) OF NUMBER;l_list max_of_five_t := max_of_five_t();

    BEGINDBMS_OUTPUT.put_line (l_list.LIMIT);

    END;

    varray_limit.sql

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    64/311

    Copyright 2011 Feuerstein and Associates Page 64

    Methods that change a collection•

    DELETE deletes one or more rows from anassociative array or nested table.• EXTEND adds rows to the end of a nested

    table or varray.• TRIM removes rows from a varray or nested

    table.

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    65/311

    Copyright 2011 Feuerstein and Associates Page 65

    The DELETE Method• You can delete one or more rows from an associative

    array or nested table using DELETE.• Try to DELETE from a varray and you will see "PLS-

    00306: wrong number or types of arguments in call

    to 'DELETE'"• Low and high index values do not have to exist.

    BEGIN-- Delete all rows

    myCollection.DELETE;-- Delete one (the last) rowmyCollection.DELETE (myCollection.LAST);

    -- Delete a range of rowsmyCollection.DELETE (1400, 17255);

    END;

    delete.sql

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    66/311

    Copyright 2011 Feuerstein and Associates Page 66

    Make room for new elements w/ EXTEND•

    Use EXTEND only with varrays and nestedtables.• Tell Oracle to add N number of new elements

    to the end of the collection.• "Bulk" extends faster than individual extends.

    – If you know you will need 10,000 elements, do theextend in a single step.

    • Optional: specify the value of all newelements from an existing element. – Default value is NULL.

    extend.sql

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    67/311

    Copyright 2011 Feuerstein and Associates Page 67

    Trimming elements from end of collection

    •Use TRIM only with varrays and nested tables. – Not to be confused with the TRIM function!

    • You can trim one or multiple elements.

    – Default is 1. – "ORA-06533: Subscript beyond count" error if you

    to trim more than is in the collection.• TRIM is the only way to remove elements from

    a varray. – DELETE is not supported.

    trim.sql

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    68/311

    Copyright 2011 Feuerstein and Associates Page 68

    Conclusions – Collection Methods

    • Methods make it much easier to work withcollections.

    • You can get information about the collections

    and also change their contents.• When you use the navigation methods, make

    sure you choose the appropriate type of loop

    to iterate through the elements.

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    69/311

    Copyright 2011 Feuerstein and Associates Page 69

    Associative Arrays

    • A variable declared from anassociative array type .

    • From the PL/SQL User Guide: – "An unbounded set of key-value pairs. – "Each key is unique, and serves as the

    subscript of the element that holdsthe corresponding value.

    – "You can access elements withoutknowing their positions in the array,and without traversing the array."

    1 Apple

    22 Pear

    100 Orange

    10023 Apricot

    DECLARETYPE list_of_names_t IS TABLE OF employees.last_name%TYPE

    INDEX BY PLS_INTEGER;

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    70/311

    Copyright 2011 Feuerstein and Associates Page 70

    Associative Array Background•

    It was the first type of collection available inPL/SQL.• First introduced in Oracle7 as a "PL/SQL table"

    (hence, the TABLE OFsyntax).• Renamed in Oracle8 to "index-by table" when

    nested tables and varrays were added.• In 9.2, renamed to "associative array" with the

    advent of string indexing.• Can only be used in PL/SQL blocks.

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    71/311

    Copyright 2011 Feuerstein and Associates Page 71

    Characteristics of Associative Arrays

    • TABLE OF datatypes can be almost any valid PL/SQLtype (details to follow).

    • INDEX BY type can be integer or string. – This means you can essentially index by anything! – But index values can never be NULL.

    •Associative arrays can be sparse. – Can populate elements in non-consecutive index values. – Easily used to emulate primary keys and unique indexes.

    DECLARE

    TYPE list_of_names_t IS TABLE OF employees.last_name%TYPEINDEX BY PLS_INTEGER;

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    72/311

    Copyright 2011 Feuerstein and Associates Page 72

    Simple associative array exampleDECLARE

    TYPE list_of_names_t IS TABLE OF VARCHAR2 (20)INDEX BY PLS_INTEGER;

    happyfamily list_of_names_t;l_index_value PLS_INTEGER := 88;

    BEGINhappyfamily (1) := 'Eli';happyfamily (-15070) := 'Steven';happyfamily (3) := 'Chris';happyfamily (l_index_value) := 'Veva';

    l_index_value := happyfamily.FIRST;WHILE (l_index_value IS NOT NULL)LOOP

    DBMS_OUTPUT.put_line ( 'Value at index '

    || l_index_value|| ' = '|| happyfamily (l_index_value)

    );l_index_value := happyfamily.NEXT (l_index_value);

    END LOOP;END;

    assoc_array_example.sql

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    73/311

    Copyright 2011 Feuerstein and Associates Page 73

    Associative array of records example

    • It is very easy to "emulate" a relational tableinside one's PL/SQL code. – Or use any other kind of record type.

    DECLARETYPE employees_aat IS TABLE OF employees%ROWTYPE

    INDEX BY PLS_INTEGER;

    l_employees employees_aat;BEGIN

    FOR employee_rec IN (SELECT * FROM employees)LOOP

    l_employees (l_employees.COUNT + 1) := employee_rec;END LOOP;

    END;

    collection_of_records.sql

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    74/311

    Copyright 2011 Feuerstein and Associates Page 74

    Valid TABLE OF datatypes

    •You can create an associative array of almost any PL/SQL or SQL datatype. – All scalar types, including Boolean – Collection of object types – Collection of other collections

    • There are some restrictions: – Cannot have a TABLE OF cursor variables or

    exceptions.

    aa_table_of_invalid_types.sql

  • 8/15/2019 Best of Oracle PLSQL 11g

    75/311

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    76/311

    Copyright 2011 Feuerstein and Associates Page 76

    More details on valid INDEX BY types

    •The INDEX BY clause defines the indexing forthe collection.

    • You can define the index datatype of your associativearray type to be: – BINARY_INTEGER and any sub-typederived from

    BINARY_INTEGER – VARCHAR2(n), where n is between 1 and 32767 – %TYPE against a database column that is consistent with

    the above rules – A SUBTYPE against any of the above.

    indexby_options.sql

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    77/311

    Copyright 2011 Feuerstein and Associates Page 77

    Nested Tables and Varrays

    •Added in Oracle8 as part of the object model.• Types can be defined in PL/SQL or a schema-level type (for use in SQL).

    • You must initialize before using the collection.• You must extend to make room for new

    elements.

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    78/311

    Copyright 2011 Feuerstein and Associates Page 78

    Nested Tables

    • A nested table is a type of collection,which, according to Oracle documentation,"models an unordered set of elements." – It is a "multiset": like a relational table, there is

    no inherent order to its elements, andduplicates are allowed/significant.

    • From a practical standpoint, you can access nested table elements through an

    integer index.• MULTISET operators allow set-level

    operations on nested tables.

    1 Apple2 Pear

    3 Orange

    4 Apricot

    CREATE OR REPLACE TYPE list_of_names_t IS TABLE OF NUMBER;

    5 Pear

    Unordered setof elements

    Integer indexalso available

    nested_table_example.sql

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    79/311

    Copyright 2011 Feuerstein and Associates Page 79

    Varrays

    • A varray (short for "variable size array)is a type of collection that has an upperbound on its number of elements.

    • This upper limit is set when the type isdefined, but can also be adjusted atruntime.

    • Always dense, can only trim from end

    of varray.• Other than that, quite similar to a

    nested table.

    1 Apple

    2 Pear

    3 Orange4 Apricot

    CREATE OR REPLACE TYPE list_of_names_t IS VARRAY (5) OF NUMBER;

    5 Pear

    And no moreelements can fit in

    this varray.

    varray_example.sql

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    80/311

    Copyright 2011 Feuerstein and Associates Page 80

    Initializing Nested Tables and Varrays• Before you can use a nested table, it must be

    initialized. – Initialize them explicitly with a constructor function, samename as type, provided by Oracle

    – No need to initialize if populated by BULK COLLECT query.• Provide a list of values or initialize it as empty.

    DECLARETYPE numbers_t IS VARRAY (5) OF NUMBER;salaries numbers_t := numbers_t (100, 200, 300);

    BEGIN

    DECLARETYPE numbers_t IS TABLE OF NUMBER;salaries numbers_t;

    BEGINsalaries := numbers_t (100, 200, 300);

    Initialize inexecution

    section

    Initialize indeclaration with

    values

    DECLARETYPE numbers_t IS TABLE OF NUMBER;salaries numbers_t := numbers_t ();

    Initialize emptyin declaration

  • 8/15/2019 Best of Oracle PLSQL 11g

    81/311

    Oracle PL/SQL Programming

    ll l

  • 8/15/2019 Best of Oracle PLSQL 11g

    82/311

    Copyright 2011 Feuerstein and Associates Page 82

    Collection as Column Type• If the type is defined at schema level, it can be used as

    a column type.• Must also provide a STORE AS clause.• The order of elements in the column is not preserved.• Can specify storage characteristics of collection.• See separate lesson for details on using collections inSQL.

    CREATE TABLE family(

    surname VARCHAR2 (1000)

    , parent_names parent_names_t, children_names child_names_t)NESTED TABLE children_names

    STORE AS parent_names_tbl [ storage_clause ]NESTED TABLE parent_names

    STORE AS children_names_tbl [ storage_clause ]

    nested_table_example.sqlvarray_example.sql

    Oracle PL/SQL Programming

    Ch i i i

  • 8/15/2019 Best of Oracle PLSQL 11g

    83/311

    Copyright 2011 Feuerstein and Associates Page 83

    Changing Upper Limit on Varray

    •You specify an upper limit at the time thevarray type is define.

    • You can also change this limit at runtime withan ALTER TYPE command.

    ALTER TYPE my_varray_t MODIFY LIMIT 100 INVALIDATE/

    BEGINEXECUTE IMMEDIATE

    'ALTER TYPE my_varray_t MODIFY LIMIT 100 CASCADE';END;/

    varray_change_limit.sql

    Oracle PL/SQL Programming

    U i C ll i I id SQL

  • 8/15/2019 Best of Oracle PLSQL 11g

    84/311

    Copyright 2011 Feuerstein and Associates Page 84

    Using Collections Inside SQL• When you define your collection type at the schema

    level , collections declared with that type can bereferenced in the SQL layer. – As a column in a relational table – By selecting from that collection in a SELECT statement.

    • This feature only applies to nested tables andvarrays. – Associative arrays are PL/SQL-only structures.

    • Oracle offers ways to "translate" between acollection format and a relational table format. – TABLE: collection -> relational table – MULTISET: relational table -> collection

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    85/311

    Copyright 2011 Feuerstein and Associates Page 85

    Using the TABLE Operator• Use TABLE to work with data in a collection

    as if it were data in a database table. – Oracle refers to this as "un-nesting". – Especially useful when you would like to apply

    SQL operations to a PL/SQL collection (ie, onenot stored in a database table).• You do not need to explicitly CAST the

    collection. – Oracle will figure out the type automatically.

    collections_in_sql.sql

    Oracle PL/SQL Programming

    Ch i ll i i h TABLE

  • 8/15/2019 Best of Oracle PLSQL 11g

    86/311

    Copyright 2011 Feuerstein and Associates Page 86

    Changing collection contents with TABLE

    •You can use TABLE to query the contents of acollection inside SQL.

    • You can also change the contents of a nestedtable column value with TABLE. – But varrays have to be changed "en masse" – the

    while varray is replace; cannot modify individualelements.

    UPDATE TABLE (SELECT children_namesFROM family

    WHERE surname = 'Feuerstein')SET COLUMN_VALUE = 'Eli Silva'

    WHERE COLUMN_VALUE = 'Eli'/ nested_table_change.sql

    Oracle PL/SQL Programming

    U i th MULTISET O t

  • 8/15/2019 Best of Oracle PLSQL 11g

    87/311

    Copyright 2011 Feuerstein and Associates Page 87

    Using the MULTISET Operator• MULTISET is the inverse of TABLE, converting a set of

    table, view, query) into a VARRAY or nested table. – Use MULTISET to emulate or transform relational joins into

    collections, 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.genusAND 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;

    collections_in_sql_multiset.sql

    Oracle PL/SQL Programming

    N S ti l I d i

  • 8/15/2019 Best of Oracle PLSQL 11g

    88/311

    Copyright 2011 Feuerstein and Associates Page 88

    Non-Sequential Indexing

    • Sometimes you simply want to add items to theend of a list. – This makes sense if the order in which items were

    added is significant .

    • But how do you find a specific element in the list? – With sequential indexing, you have to scan through

    the contents to find a match.

    • And what if you want to find elements in acollection using more than one "index"? – Collections have just one index. No way around that.

    string_tracker0.*

    Oracle PL/SQL Programming

  • 8/15/2019 Best of Oracle PLSQL 11g

    89/311

    Copyright 2011 Feuerstein and Associates Page 89

    Taking advantage of non-sequential indexing• Associative arrays can be sparse.

    – Certainly, any string-indexed collection is notsequentially filled.

    • Valid index values for an associative array

    cover a very wide range of integers. – Very often primary keys of tables are sequence-

    generated integers that fall within this range.• Combine these two features and you have a

    powerful and relatively simple mechanism foremulating relational table keys.

    collection_of_records.sql

    Oracle PL/SQL Programming

    l ll

  • 8/15/2019 Best of Oracle PLSQL 11g

    90/311

    Copyright 2011 Feuerstein and Associates Page 90

    Emulating Primary Key in Collection• Many tables rely on sequence-generated integer

    values for their primary keys. – It is possible that this sequence value could exceed

    2**31-1, but it is rarely the case.

    • Primary keys generally are not "densely"allocated. – Sequences are allocated in groups, rows are deleted.

    • These scenarios mesh perfectly with the featuresof an integer-indexed associative array.

    emulate_primary_key1.sqlemulate_primary_key2.sql

    Oracle PL/SQL Programming

    "M lti l I d " C ll ti

  • 8/15/2019 Best of Oracle PLSQL 11g

    91/311

    Copyright 2011 Feuerstein and Associates Page 91

    "Multiple Indexes" on a Collection

    •Most relational tables have multiple indexesdefined in order to optimize queryperformance (for various WHERE clauses).

    • What if I need to do the same thing in acollection?

    • You can only have a single index on anassociative array (INDEX BY...). – But you could create other collections that serve

    as indexes into the "original" collection.emulate_indexes.sql

    genaa.sql

    Oracle PL/SQL Programming

    Expanded indexing capabilities for

  • 8/15/2019 Best of Oracle PLSQL 11g

    92/311

    Copyright 2011 Feuerstein and Associates Page 92

    Expanded indexing capabilities forassociative arrays

    • Prior to Oracle9i Release 2, you could only index byBINARY_INTEGER.

    • You can now define the index on your associativearray to be: – Any sub-type derived from BINARY_INTEGER – VARCHAR2(n), where n is between 1 and 32767 – %TYPE against a database column that is consistent with

    the above rules – A SUBTYPE against any of the above.

    • This means that you can now index on string values!(and concatenated indexes and...)

    Oracle PL/SQL Programming

    Examples of New TYPE Variants

  • 8/15/2019 Best of Oracle PLSQL 11g

    93/311

    Copyright 2011 Feuerstein and Associates Page 93

    Examples of New TYPE Variants• All of the following are valid TYPE declarations in

    Oracle9i Release 2 and higher – You cannot use %TYPE against an INTEGER column, because

    INTEGER isnot a subtype of BINARY_INTEGER.

    DECLARETYPE array_t1 IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;TYPE array_t2 IS TABLE OF NUMBER INDEX BY PLS_INTEGER;TYPE array_t3 IS TABLE OF NUMBER INDEX BY POSITIVE;TYPE array_t4 IS TABLE OF NUMBER INDEX BY NATURAL;TYPE array_t5 IS TABLE OF NUMBER INDEX BY VARCHAR2(64);TYPE array_t6 IS TABLE OF NUMBER INDEX BY VARCHAR2(32767);TYPE array_t7 IS TABLE OF NUMBER INDEX BY

    employee.last_name%TYPE;TYPE array_t8 IS TABLE OF NUMBER INDEX BY

    types_pkg.subtype_t;

    Oracle PL/SQL Programming

    W ki i h i i d d ll i

  • 8/15/2019 Best of Oracle PLSQL 11g

    94/311

    Copyright 2011 Feuerstein and Associates Page 94

    Working with string-indexed collections•

    The syntax for using string indexing is thesame. – And all the same methods are available.

    • But the type of data returned by FIRST, LAST,NEXT and PRIOR methods is VARCHAR2.

    • The longer the string values, the more time it takesOracle to "hash" or convert that string to the integerthat is actually used as the index value. – Relatively small strings, say under 100 characters, do not

    incur too large a penalty.

    assoc_array*.sqlassoc_array_perf.tst

    Oracle PL/SQL Programming

    Practical application for string indexing

  • 8/15/2019 Best of Oracle PLSQL 11g

    95/311

    Copyright 2011 Feuerstein and Associates Page 95

    Practical application for string indexing• I need to keep track of names used in my program.

    – Specifically, in Quest Code Tester, we generate test codeand declare variables. So I need to make sure that I do notdeclare the same variable more than once.

    • There are lots of ways to do this, but string-indexedcollections make it really easy!

    FOR indx IN 1 .. l_variables.COUNTLOOP

    If varname_already_used

    THEN-- DO NOTHINGELSE

    add_variable_declaration;mark_varname_as_used;

    END IF;END LOOP;

    string_tracker0.*

    Oracle PL/SQL Programming

    String Tracker without string indexing

  • 8/15/2019 Best of Oracle PLSQL 11g

    96/311

    Copyright 2011 Feuerstein and Associates Page 96

    String Tracker without string indexing

    •Two subprograms are needed.... – string_in_use: returns TRUE if the string was

    previously used. – mark_as_used: mark the specified string as being

    used.• Most "obvious" implementation: add each

    string to a list of used strings.• Then search through the list for a match.

    string_tracker0.*

    Oracle PL/SQL Programming

    String Tracker with string indexing

  • 8/15/2019 Best of Oracle PLSQL 11g

    97/311

    Copyright 2011 Feuerstein and Associates Page 97

    String Tracker with string indexing

    • Rather than add each string to a list of usedstrings, why not use the string as the index ?CREATE OR REPLACE PACKAGE BODY string_trackerIS

    TYPE used_aat IS TABLE OF BOOLEAN INDEX BY VARCHAR2(32767);

    g_names_used used_aat;

    FUNCTION string_in_use ( value_in IN VARCHAR2 )RETURN BOOLEAN

    IS BEGINRETURN g_names_used.EXISTS ( value_in );

    END string_in_use;

    PROCEDURE mark_as_used (value_in IN VARCHAR2) ISBEGIN

    g_names_used ( value_in ) := TRUE;END mark_as_used;

    END string_tracker;

    string_tracker1.*

    Oracle PL/SQL Programming

    Converting from Integer to String Indexing

  • 8/15/2019 Best of Oracle PLSQL 11g

    98/311

    Copyright 2011 Feuerstein and Associates Page 98

    Converting from Integer to String Indexing

    • Suppose I am emulating my primary key in acollection index for a batch job. – Much better performance! – But my primary key values are approaching

    2**31-1 (the maximum allowed in an collection).• Must I abandon the collection technique?• No! You can convert to a string index.

    – Now the only limitation is the number of elements

    defined in the collection. – You are much more likely to run out of memorybefore you get anywhere near 2**31-1 elements.

    emulate_primary_key.sqlint_to_string_indexing.sql

    Oracle PL/SQL Programming

    Multilevel (a k a Nested) Collections

  • 8/15/2019 Best of Oracle PLSQL 11g

    99/311

    Copyright 2011 Feuerstein and Associates Page 99

    Multilevel (a.k.a., Nested) Collections

    •A multilevel collection type is a type whoseelement is, directly or indirectly, anothercollection.

    • Usages for multilevel collections: – Model normalized data structures in PL/SQL

    collections – Emulate multidimensional arrays.

    • The syntax for working with multilevelcollections can be hard to parse (in yourhead).

    multilevel_collections.sql

    Oracle PL/SQL Programming

    String Tracker Version 2

  • 8/15/2019 Best of Oracle PLSQL 11g

    100/311

    Copyright 2011 Feuerstein and Associates Page 100

    String Tracker Version 2• I introduced the string_tracker package in

    "Working with String-Indexed Collections." – Keeps track of the names of variables already

    generated in test code.

    – That worked fine for a single list. What if I need tokeep track of multiple lists, and lists within lists?• Let's extend the first version to support

    multiple lists by using a string-indexed, multi-level collection. A list of lists....

    string_tracker1.*string_tracker2.*

    string_tracker3*.*

    List 1: 1-10000 List 2: 10001-20000 List 2: 20001-30000

    The hard way: segmenting one big collection

    Oracle PL/SQL Programming

    Emulate multidimensional arrays

  • 8/15/2019 Best of Oracle PLSQL 11g

    101/311

    Copyright 2011 Feuerstein and Associates Page 101

    Emulate multidimensional arrays

    • Collections are always single dimensioned.• But a collection of collections is "kinda like" a

    two-dimensional array. – You can extrapolate from there.

    CREATE OR REPLACE PACKAGE multdimIS

    TYPE dim1_t IS TABLE OF VARCHAR2 (32767)INDEX BY PLS_INTEGER;

    TYPE dim2_t IS TABLE OF dim1_t

    INDEX BY PLS_INTEGER;

    TYPE dim3_t IS TABLE OF dim2_tINDEX BY PLS_INTEGER;

    multdim*.*

    Oracle PL/SQL Programming

    Complex example: four-levels of nesting

  • 8/15/2019 Best of Oracle PLSQL 11g

    102/311

    Copyright 2011 Feuerstein and Associates Page 102

    Complex example: four-levels of nesting• The most complicated structure I ever built

    was a four-level nested collection structure.• I used it to build a utility to analyze packages

    for potentially ambiguous overloading.• The next several slides explore the

    implementation. – It is too complex to fully explain in this lesson. –

    Visit stevenfeuerstein.com/read/read-steven tocheck out an 8-part article series I wrote toexplain it.

    Oracle PL/SQL Programming

    Multilevel collections as a kind of

  • 8/15/2019 Best of Oracle PLSQL 11g

    103/311

    Copyright 2011 Feuerstein and Associates Page 103

    normalized database design

    • I have found that coming up with the rightmodel of multilevel collections is very similarto normalizing data in relational tables. – Avoid redundancy – Accurately reflect relationships – Simply resulting application code

    • Let's take a look at an example of such aprocess.

    Oracle PL/SQL Programming

    The problem of ambiguous overloading

  • 8/15/2019 Best of Oracle PLSQL 11g

    104/311

    Copyright 2011 Feuerstein and Associates Page 104

    The problem of ambiguous overloading• Oddly and sadly, it is possible to compile

    overloadings which are not usable. – You see an obvious example below, but there are many

    more subtle circumstances, usually involving defaultedparameters.

    • So I will build a utility to identify such ambiguousoverloadings. But how can I do this?

    BEGINsalespkg.calc_total ('ABC');

    END;

    PACKAGE salespkgIS

    PROCEDURE calc_total (dept_in IN VARCHAR2);

    PROCEDURE calc_total (dept_in IN CHAR);

    END salespkg;

    ?ambig_overloading.sql

    Oracle PL/SQL Programming

    ALL ARGUMENTS to the rescue!

  • 8/15/2019 Best of Oracle PLSQL 11g

    105/311

    Copyright 2011 Feuerstein and Associates Page 105

    ALL_ARGUMENTS to the rescue!• Parsing is too complicated for me, but the

    ALL_ARGUMENTS data dictionary view containsinformation about all the arguments of all theprocedures and functions to which I have access. – That sounds pretty good!

    • As usual, Oracle offers us a whole lot of pleasure,mixed with a little bit of pain. – The organization of data in ALL_ARGUMENTS is a bit

    bizarre, plus it is incomplete, necessitating the use also of

    DBMS_DESCRIBE.DESCRIBE_COLUMNS.

    all_arguments.tstall_arguments.sql

    allargs.*

    Oracle PL/SQL Programming

    First Inclination: Same Old Same Old

  • 8/15/2019 Best of Oracle PLSQL 11g

    106/311

    Copyright 2011 Feuerstein and Associates Page 106

    First Inclination: Same Old, Same Old• All right then, I will grab all the information from

    ALL_ARGUMENTS and dump it into a collectionbased on that view! Very easy...

    CREATE OR REPLACE PROCEDURE get_all_arguments (package_in IN VARCHAR2)

    ISTYPE all_arguments_tt IS TABLE OF all_arguments%ROWTYPE

    INDEX BY BINARY_INTEGER;l_arguments all_arguments_tt;

    BEGINFOR rec IN (

    SELECT * FROM all_arguments

    WHERE owner = USER AND package_name = package_in)LOOPl_arguments (SQL%ROWCOUNT) := rec;

    END LOOP;END;

    Load it up!

    Emulate theview.

  • 8/15/2019 Best of Oracle PLSQL 11g

    107/311

    Oracle PL/SQL Programming

    Discovery: there is a hierarchy within

  • 8/15/2019 Best of Oracle PLSQL 11g

    108/311

    Copyright 2011 Feuerstein and Associates Page 108

    Discovery: there is a hierarchy withinthe ALL_ARGUMENTS data!

    • Each program has zero ormore overloadings, eachoverloading has Narguments, and eachargument can have

    multiple "breakouts" (myterm - applies to non-scalar parameters, such asrecords or object types).

    RUN_TEST

    SHOW_RESULTS

    RESET_FLAGS

    Program name

    Overloading 1

    Overloading 2

    Overloading

    Argument 1

    Argument 2

    Argument 3

    Argument 4

    Argument 5

    ArgumentBreakout 1

    Breakout 1

    Breakout 2

    Breakout 3

    Breakout

    Oracle PL/SQL Programming

    What if I reflect this hierarchy in

  • 8/15/2019 Best of Oracle PLSQL 11g

    109/311

    Copyright 2011 Feuerstein and Associates Page 109

    What if I reflect this hierarchy ina multilevel collection?

    • Have to build from the bottom up:

    TYPE breakouts_t IS TABLE OF all_arguments%ROWTYPEINDEX BY PLS_INTEGER;

    TYPE arguments_t IS TABLE OF breakouts_tINDEX BY PLS_INTEGER;

    TYPE overloadings_t IS TABLE OF arguments_tINDEX BY PLS_INTEGER;

    TYPE programs_t IS TABLE OF overloadings_tINDEX BY all_arguments.object_name%type;

    1. Set of rows from ALL_ARGUMENTS

    String-based index

    2. All the "breakout" infofor a single argument

    3. All the argument infofor a single overloading

    4. All the overloadings fora distinct program name

    Oracle PL/SQL Programming

    Then I can populate it very easily

  • 8/15/2019 Best of Oracle PLSQL 11g

    110/311

    Copyright 2011 Feuerstein and Associates Page 110

    Then I can populate it very easily• Assigning a single record to the "lowest" level also

    defines each of the upper levels.• Notice the automatic "SELECT DISTINCT" on program

    name that results!

    FOR rec IN (SELECT * FROM all_arguments)LOOP

    l_arguments ( NVL ( l_arguments . LAST, 0) + 1) := rec ;

    l_programs ( rec . object_name )

    ( NVL ( rec . overload , 0)) ( rec . position )

    ( rec . data_level ) := rec ; END LOOP;

    I can still do thetypical sequential

    load.

    But I will now alsoadd the multi-level

    load in singleassignment

    show_all_arguments.spshow_all_arguments.tst

    cc_smartargs.pkb/load_arguments

    Oracle PL/SQL Programming

    And then I can "query" the contents

  • 8/15/2019 Best of Oracle PLSQL 11g

    111/311

    Copyright 2011 Feuerstein and Associates Page 111

    q ywith a minimum of code

    l_programs ('TOP_SALES') (2).EXISTS (0)

    Is the TOP_SALESprogram overloaded?

    l_programs ('TOP_SALES') (2)(0)(0).datatype

    l_programs ('TOP_SALES').COUNT > 1

    Is the 2ndoverloading of

    TOP_SALES afunction?

    What is the datatypeof the RETURN

    clause of the 2ndoverloading ofTOP_SALES?

    And, of course, I know the beginning and end points ofeach program, overloading, and argument. I just use the

    FIRST and LAST methods on those collections!

    Oracle PL/SQL Programming

    Conclusions Nested Collections

  • 8/15/2019 Best of Oracle PLSQL 11g

    112/311

    Copyright 2011 Feuerstein and Associates Page 112

    Conclusions – Nested Collections•

    The nested collection is a powerful, butpotentially very complicated, feature of PL/SQL.• Used correctly, it can hide complexity in the

    underlying data structure, and greatly simplifyyour algorithms.

    • If you find yourself saying "It shouldn't be thishard," take a look at how you are using your

    collections (or SQL). – Perhaps multilevel collections can come to the rescue!

    Oracle PL/SQL Programming

    Manipulating Nested Tables as Multisets

  • 8/15/2019 Best of Oracle PLSQL 11g

    113/311

    Copyright 2011 Feuerstein and Associates Page 113

    Manipulating Nested Tables as Multisets• Nested tables are, from a theoretical standpoint,

    "multisets." – There is no inherent order to the elements. – Duplicates are allowed and are significant. –

    Relational tables are multisets as well.• If a set has no order, then it has no index, so itmust be manipulated as a set .

    • In Oracle Database 10g, Oracle added MULTISETset operators to manipulate the contents ofnested tables (only). – Use in both PL/SQL blocks and SQL statements.

    Oracle PL/SQL Programming

    Set-Oriented Features for Nested Tables

  • 8/15/2019 Best of Oracle PLSQL 11g

    114/311

    Copyright 2011 Feuerstein and Associates Page 114

    Set Oriented Features for Nested Tables• Determine if...

    – two nested tables are equal/unequal – a nested table has duplicates, and remove duplicates – one nested table contains another –

    an element is a member of a nested table• Perform set operations. – Join contents of two nested tables: MULTISET UNION. – Return common elements of two nested tables with

    MULTISET INTERSECT. – Take away the elements of one nested table from

    another with MULTISET EXCEPT (oddly, not MINUS).

    Oracle PL/SQL Programming

    Check for equality and inequality

  • 8/15/2019 Best of Oracle PLSQL 11g

    115/311

    Copyright 2011 Feuerstein and Associates Page 115Copyright 2000-2008 Steven Feuerstein - Page 115

    Check for equality and inequality• You can use = and to compare the contents of two

    nested tables. – But watch out! NULLs have the usual disruptive impact.

    • This is an enormous advantage over writing a programto compare the contents of two collections.

    DECLARETYPE clientele IS TABLE OF VARCHAR2 (64);group1 clientele := clientele ('Customer 1', 'Customer 2');group2 clientele := clientele ('Customer 1', 'Customer 3');group3 clientele := clientele ('Customer 3', 'Customer 1');

    BEGINIF group1 = group2 THEN

    DBMS_OUTPUT.put_line ('Group 1 = Group 2');ELSE

    DBMS_OUTPUT.put_line ('Group 1 != Group 2');END IF;

    END; 10g_compare.sql10g_compare_nulls.sql10g_compare_old.sql

    Oracle PL/SQL Programming

    Nested table duplicates – detection and removal

  • 8/15/2019 Best of Oracle PLSQL 11g

    116/311

    Copyright 2011 Feuerstein and Associates Page 116Copyright 2000-2008 Steven Feuerstein - Page 116

    p• Use the SET operator to work with distinct values, and

    determine if you have a set of distinct values.DECLARE

    keep_it_simple strings_nt := strings_nt ();BEGIN

    keep_it_simple := SET (favorites_pkg.my_favorites);

    favorites_pkg.show_favorites ('FULL SET', favorites_pkg.my_favorites);

    p.l (favorites_pkg.my_favorites IS A SET, 'My favorites distinct?');p.l (favorites_pkg.my_favorites IS NOT A SET,

    'My favorites NOT distinct?');

    favorites_pkg.show_favorites (

    'DISTINCT SET', keep_it_simple);

    p.l (keep_it_simple IS A SET, 'Keep_it_simple distinct?');p.l (keep_it_simple IS NOT A SET, 'Keep_it_simple NOT distinct?');

    END;

    authors.pkg

    10g_set.sql

    Oracle PL/SQL Programming

    Determine if value is in nested table

  • 8/15/2019 Best of Oracle PLSQL 11g

    117/311

    Copyright 2011 Feuerstein and Associates Page 117

    • Use the MEMBER OF syntax to determine if avalue is in the nested table. – Much simpler than scanning the contents of a

    collection.

    – Performs an equality check for the entire element;you cannot compare individual fields of records,and so on.

    •The implementation in SQL itself is quite slow.

    • Performance in PL/SQL is fast.

    in_clause.*10g_member_of.sql

    Oracle PL/SQL Programming

    Does one nested table contains another?

  • 8/15/2019 Best of Oracle PLSQL 11g

    118/311

    Copyright 2011 Feuerstein and Associates Page 118

    • The SUBMULTISET OF operator determines ifall the elements of one nested table are inanother.

    DECLARE

    TYPE nested_typ IS TABLE OF NUMBER;

    nt1 nested_typ := nested_typ (1, 2);nt2 nested_typ := nested_typ (3, 2, 1);

    BEGINIF nt1 SUBMULTISET OF nt3THEN

    ...END IF;

    END;/

    authors.pkg10g_submultiset.sql

  • 8/15/2019 Best of Oracle PLSQL 11g

    119/311

  • 8/15/2019 Best of Oracle PLSQL 11g

    120/311

    Oracle PL/SQL Programming

    Take away the elements of one nested table

  • 8/15/2019 Best of Oracle PLSQL 11g

    121/311

    Copyright 2011 Feuerstein and Associates Page 121

    yfrom another

    • Use EXCEPT (not MINUS!) to take all elementsin one nested table out of another.

    • Duplicates are preserved unless you includethe DISTINCT modifier. – And the ALL modifier is the default.

    • The resulting collection is either empty orsequentially filled from index value 1. – You do not need to initialize or extend first.

    10g_except.sql

    Oracle PL/SQL Programming

    Conclusions – MULTISET operators

  • 8/15/2019 Best of Oracle PLSQL 11g

    122/311

    Copyright 2011 Feuerstein and Associates Page 122

    Conclusions MULTISET operators

    •When you need to manipulate the contents ofa collection as a set, use a nested table.

    • The MULTISET operators offer a powerful,simple way to avoid writing lots of code.

    • The SET, SUBMULTISET and MEMBERoperators also can come in very handy.

    •Watch out for results when your nested tablemay contain NULL elements.

    Oracle PL/SQL Programming

    Collection Best Practices

  • 8/15/2019 Best of Oracle PLSQL 11g

    123/311

    Copyright 2011 Feuerstein and Associates Page 123

    •Watch the PGA memory.• Hide the implementation details.

    • Use subtypes to self-document element and

    index by types.• Choosing the best type of collection

    Oracle PL/SQL Programming

    Watch the PGA memory

  • 8/15/2019 Best of Oracle PLSQL 11g

    124/311

    Copyright 2011 Feuerstein and Associates Page 124

    y• Memory for collections is allocated from the

    PGA (Process Global Area). – There is a PGA for each session connected to the

    instance.• Large collections constructed by programs run

    by many simultaneously-connected users cancause memory errors.

    • Use the plsq_memory package to analyze theamount of memory used. – Or at least make sure your DBA knows you are

    making extensive use of collections.

    plsql_memory*.*

    Oracle PL/SQL Programming

    Hide the implementation details.

  • 8/15/2019 Best of Oracle PLSQL 11g

    125/311

    Copyright 2011 Feuerstein and Associates Page 125

    • Collections, especially multi-level collections,are very complex structures.

    • Hide the way you to set and get elements in acollection behind an API. – Procedure to set, function to get. – When you have change the implement, you

    change in one place (single point of definition).• The "Say Goodbye to Hard-Coding" section

    offers more examples on the idea and practiceof information hiding.

    multdim.sqlcc_smartargs.sql

    Oracle PL/SQL Programming

    Use subtypes to self-document datatypes

  • 8/15/2019 Best of Oracle PLSQL 11g

    126/311

    Copyright 2011 Feuerstein and Associates Page 126

    • You should avoid using base datatypes in boththe TABLE OF and INDEX BY clauses. – Especially when working with string-indexed

    associative arrays.

    • Use SUBTYPEs to provide application-specificnames that self-document both contents andintention. – Constants can also come in handy.

    string_tracker3.*

    Oracle PL/SQL Programming

    Choosing the best type of collection

  • 8/15/2019 Best of Oracle PLSQL 11g

    127/311

    Copyright 2011 Feuerstein and Associates Page 127

    g yp• Use associative arrays when you need to...

    – Work within PL/SQL code only – Sparsely fill and manipulate the collection – Take advantage of negative index values or string indexing

    • Use nested tables when you need to... – Access the collection inside SQL (table functions, columns in

    tables, or utilize SQL operations) – Want or need to perform high level set operations

    (MULTISET)

    • Use varrays when you need to... – If you need to specify a maximum size to your collection – Optimize performance of storing collection as column

    Oracle PL/SQL Programming

    Collections vs. Global Temporary Tables

  • 8/15/2019 Best of Oracle PLSQL 11g

    128/311

    Copyright 2011 Feuerstein and Associates Page 128

    p y• Global temporary tables cut down on the

    overhead of working with persistent tables. – And you can use the full power of SQL, which is

    their main advantage over collections.

    • GTTs still require interaction with the SGA.• So collections will still be faster, but they will

    use more memory. – GTTs consume SGA memory.

    global_temp_tab_vs_coll.sql

    Oracle PL/SQL Programming

    Dealing with Mutating Table errors

  • 8/15/2019 Best of Oracle PLSQL 11g

    129/311

    Copyright 2011 Feuerstein and Associates Page 129

    g g

    • Row level triggers cannot query from or change thecontents of the table to which it is attached; it is"mutating".

    • But statement level triggers do not have thisrestriction.

    • So what are you supposed to do when a row-leveloperation needs to "touch" that table?

    UPDATE row 1

    UPDATE row N

    UPDATE emp SET sal = 1000

    Database triggers can be associated with both the DML

    statement as a whole and individual rows affected by thatstatement.

    Note: you can useautonomous

    transactions to relaxrestrictions associated

    with queries.

    mutating.sql

    Statement level

    Row level

    Oracle PL/SQL Programming

    A Collection-Based Solution

  • 8/15/2019 Best of Oracle PLSQL 11g

    130/311

    Copyright 2011 Feuerstein and Associates Page 130

    • Since you cannot perform the processing desired in the

    row-level trigger, you need to defer the action until youget to the statement level.• If you are going to defer the work, you have to remember

    what you needed to do. – An associative array is an ideal repository for this reminder list.

    1st row trigger fires

    Nth row trigger fires

    Work List(collection)

    Statement Trigger

    Writes to list

    Writes to list

    Process datain the list.mutating_trigger.pkg

    ranking.pkg

    Oracle PL/SQL Programming

    Collections: Don't start coding without them.

  • 8/15/2019 Best of Oracle PLSQL 11g

    131/311

    Copyright 2011 Feuerstein and Associates Page 131

    g• It is impossible to write efficient, high quality PL/SQL

    code, taking full advantage of new features, unless you use collections. – From array processing to table functions, collections are

    required.• Learn collections thoroughly and apply them

    throughout your backend code. – Your code will get faster and in many cases much simpler

    than it might have been (though not always!).

    Hands-On Collection seminarwww.ToadWorld.com/SF

    Oracle PL/SQL Programming

    Bulk Processing of SQL in PL/SQL

  • 8/15/2019 Best of Oracle PLSQL 11g

    132/311

    Copyright 2011 Feuerstein and Associates Page 132

    • The central purpose of PL/SQL is to provide aportable, fast, easy way to write and executeSQL against an Oracle database.

    • Unfortunately, this means that mostdevelopers take SQL for granted when writingSQL...and just assume Oracle has fully(automagically) optimized how SQL will run

    from within PL/SQL.

  • 8/15/2019 Best of Oracle PLSQL 11g

    133/311

    Oracle PL/SQL Programming

    Repetitive statement processing from PL/SQL

  • 8/15/2019 Best of Oracle PLSQL 11g

    134/311

    Copyright 2011 Feuerstein and Associates Page 134

    Oracle server

    PL/SQL Runtime Engine SQL Engine

    PL/SQL blockProceduralstatementexecutor SQL

    statementexecutor

    FOR rec IN emp_cur LOOPUPDATE employee

    SET salary = ...WHERE employee_id =

    rec.employee_id;END LOOP;

    Performance penaltyfor many “contextswitches”

    Oracle PL/SQL Programming

    Bulk Processing in PL/SQL

  • 8/15/2019 Best of Oracle PLSQL 11g

    135/311

    Copyright 2011 Feuerstein and Associates Page 135

    • The goal is straightforward: reduce the number of

    context switches and you improver performance.• To do this, Oracle "bundles up" the requests for data

    (or to change data) and then passes them with asingle context switch.

    •FORALL speeds up DML. – Use with inserts, updates, deletes and merges. – Move data from collections to tables.

    • BULK COLLECT speeds up queries. –

    Can be used with all kinds of queries: implicit, explicit,static and dynamic. – Move data from tables into collections.

    Oracle PL/SQL Programming

    Bulk processing with FORALL

  • 8/15/2019 Best of Oracle PLSQL 11g

    136/311

    Copyright 2011 Feuerstein and Associates Page 136

    Oracle server

    PL/SQL Runtime Engine SQL Engine

    PL/SQL blockProceduralstatement

    executor SQLstatementexecutor

    FORALL indx INlist_of_emps.FIRST..list_of_emps.LAST

    UPDATE employeeSET salary = ...

    WHERE employee_id =list_of_emps(indx);

    Fewer context switches,same SQL behavior

    Update...

    Update...

    Update...Update...

    Update...Update...

    Update...

    Update...

    Update...Update...

    Update...Update...

    Oracle PL/SQL Programming

    Impact of Bulk Processing in SQL layer

  • 8/15/2019 Best of Oracle PLSQL 11g

    137/311

    Copyright 2011 Feuerstein and Associates Page 137

    • The bulk processing features of PL/SQL change the

    way the PL/SQL engine communicates with the SQLlayer.• For both FORALL and BULK COLLECT, the processing

    in the SQL engine is almost completely unchanged. –

    Same transaction and rollback segment management – Same number of individual SQL statements will beexecuted.

    • Only one difference: BEFORE and AFTER statement-level triggers only fire once per FORALL INSERTstatements. – Not for each INSERT statement passed to the SQL engine

    from the FORALL statement.

    statement_trigger_and_forall.sql

    Oracle PL/SQL Programming

    BULK COLLECT Agenda

  • 8/15/2019 Best of Oracle PLSQL 11g

    138/311

    Copyright 2011 Feuerstein and Associates Page 138

    • Introduction to BULK COLLECT• Unlimited BULK COLLECTs• Using the LIMIT clause•

    When to convert to BULK COLLECT

    Oracle PL/SQL Programming

    BULK COLLECT for multi-row querying

  • 8/15/2019 Best of Oracle PLSQL 11g

    139/311

    Copyright 2011 Feuerstein and Associates Page 139

    • Retrieve multiple rows into a collection with a

    single fetch (context switch to the SQL engine).• Deposit the multiple rows of data into one or

    more collections .

    SELECT * BULK COLLECT INTO collection(s) FROM table ;

    FETCH cur BULK COLLECT INTO collection(s) ;EXECUTE IMMEDIATE query BULK COLLECT INTO collection(s) ;

    Oracle PL/SQL Programming

    "Good to Know" about BULK COLLECT

  • 8/15/2019 Best of Oracle PLSQL 11g

    140/311

    Copyright 2011 Feuerstein and Associates Page 140

    • NO_DATA_FOUND is not raised when no rowsare fetched; instead, the collection is empty.

    • The "INTO" collections are filled sequentiallyfrom index value 1. – There are no "gaps" between 1 and the index

    value returned by the COUNT method.• Only integer-indexed collections may be used.• No need to initialize or extend nested tables

    and varrays. Done automatically by Oracle.

    Oracle PL/SQL Programming

    An "unlimited" BULK COLLECT

  • 8/15/2019 Best of Oracle PLSQL 11g

    141/311

    Copyright 2011 Feuerstein and Associates Page 141

    DECLARETYPE employees_aat IS TABLE OF

    employees%ROWTYPE;

    l_employees employees_aat;BEGIN

    SELECT *

    BULK COLLECT INTO l_employeesFROM employees;

    FOR indx IN 1 .. l_employees.COUNTLOOP

    process_employee (l_employees(indx));END LOOP;

    END;

    bulkcoll.sqlbulkcollect.tst

    Declare a nestedtable of records tohold the queried

    data.

    Fetch all rows intocollection

    sequentially,starting with 1.

    Iterate throughthe collection

    contents with aloop. But what if I need to fetch and process

    millions of rows?This approach could consume unacceptable

    amounts of PGA memory.

    Oracle PL/SQL Programming

    Limiting retrieval with BULK COLLECT

  • 8/15/2019 Best of Oracle PLSQL 11g

    142/311

    Copyright 2011 Feuerstein and Associates Page 142

    • If you are certain that your table with neverhave more than N rows, use a VARRAY (N) tohold the fetched data. – If that limit is exceeded, Oracle will raise an error. – This is not, however, a very common scenario.

    • If you do not know in advance how many rowsyou might retrieve, you should: – 1. Declare an explicit cursor. – 2. Fetch BULK COLLECT with the LIMIT clause.

    Oracle PL/SQL Programming

    Limit rows returned by BULK COLLECT

  • 8/15/2019 Best of Oracle PLSQL 11g

    143/311

    Copyright 2011 Feuerstein and Associates Page 143

    CREATE OR REPLACE PROCEDURE bulk_with_limit(deptno_in IN dept.deptno%TYPE)

    ISCURSOR emps_in_dept_cur IS

    SELECT * FROM empWHERE deptno = deptno_in;

    TYPE emp_tt IS TABLE OF emps_in_dept_cur%ROWTYPE;

    emps emp_tt;BEGINOPEN emps_in_dept_cur;LOOP

    FETCH emps_in_dept_curBULK COLLECT INTO emps LIMIT 1000;

    EXIT WHEN emps.COUNT = 0;

    process_emps (emps);END LOOP;CLOSE emps_in_dept_cur;

    END bulk_with_limit;

    Use the LIMIT clause with theINTO to manage the amount ofmemory used with the BULKCOLLECT operation.

    Definitely the preferred approachin production applications withlarge or varying datasets.

    bulklimit.sql

    Oracle PL/SQL Programming

    Details on that LIMIT clause

  • 8/15/2019 Best of Oracle PLSQL 11g

    144/311

    Copyright 2011 Feuerstein