Oracle Database Advanced Application Developer’s Guide Developer
User Manual:
Open the PDF directly: View PDF .
Page Count: 576
Download | |
Open PDF In Browser | View PDF |
[1] Oracle® Database Advanced Application Developer's Guide 11g Release 2 (11.2) E41502-06 December 2014 Oracle Database Advanced Application Developer's Guide, 11g Release 2 (11.2) E41502-06 Copyright © 1996, 2014, Oracle and/or its affiliates. All rights reserved. Primary Author: Sheila Moore Contributing Authors: D. Adams, L. Ashdown, P. Huey, S. Moore, E. Paapanen, R. Strohm, R. Ward Contributors: D. Alpern, G. Arora, T. Chang, B. Cheng, R. Day, R. Decker, G. Doherty, D. Elson, A. Ganesh, M. Hartstein, Y. Hu, J. Huang, C. Iyer, N. Jain, V. Krishnaswamy, R. Kumar, S. Kumar, C. Lei, B. Llewellyn, K. Mohan, V. Moore, K. Muthukkaruppan, J. Muller, R. Murthy, R. Pang, B. Sinha, S. Vemuri, W. Wang, D. Wong This software and related documentation are provided under a license agreement containing restrictions on use and disclosure and are protected by intellectual property laws. Except as expressly permitted in your license agreement or allowed by law, you may not use, copy, reproduce, translate, broadcast, modify, license, transmit, distribute, exhibit, perform, publish, or display any part, in any form, or by any means. Reverse engineering, disassembly, or decompilation of this software, unless required by law for interoperability, is prohibited. The information contained herein is subject to change without notice and is not warranted to be error-free. If you find any errors, please report them to us in writing. If this is software or related documentation that is delivered to the U.S. Government or anyone licensing it on behalf of the U.S. Government, then the following notice is applicable: U.S. GOVERNMENT END USERS: Oracle programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, delivered to U.S. Government end users are "commercial computer software" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations. As such, use, duplication, disclosure, modification, and adaptation of the programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, shall be subject to license terms and license restrictions applicable to the programs. No other rights are granted to the U.S. Government. This software or hardware is developed for general use in a variety of information management applications. It is not developed or intended for use in any inherently dangerous applications, including applications that may create a risk of personal injury. If you use this software or hardware in dangerous applications, then you shall be responsible to take all appropriate fail-safe, backup, redundancy, and other measures to ensure its safe use. Oracle Corporation and its affiliates disclaim any liability for any damages caused by use of this software or hardware in dangerous applications. Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners. Intel and Intel Xeon are trademarks or registered trademarks of Intel Corporation. All SPARC trademarks are used under license and are trademarks or registered trademarks of SPARC International, Inc. AMD, Opteron, the AMD logo, and the AMD Opteron logo are trademarks or registered trademarks of Advanced Micro Devices. UNIX is a registered trademark of The Open Group. This software or hardware and documentation may provide access to or information about content, products, and services from third parties. Oracle Corporation and its affiliates are not responsible for and expressly disclaim all warranties of any kind with respect to third-party content, products, and services unless otherwise set forth in an applicable agreement between you and Oracle. Oracle Corporation and its affiliates will not be responsible for any loss, costs, or damages incurred due to your access to or use of third-party content, products, or services, except as set forth in an applicable agreement between you and Oracle. Contents Preface ............................................................................................................................................................ xxvii Audience.................................................................................................................................................. xxvii Documentation Accessibility ................................................................................................................ xxvii Related Documents ............................................................................................................................... xxviii Conventions ........................................................................................................................................... xxviii What's New in Application Development? ................................................................................ xxix Oracle Database 11g Release 2 (11.2.0.4) Feature................................................................................ xxix Oracle Database 11g Release 2 (11.2.0.2) Feature................................................................................ xxix Oracle Database 11g Release 2 Features............................................................................................... xxx Oracle Database 11g Release 1 Features.............................................................................................. xxxii Part I SQL for Application Developers 1 Using SQL Data Types in Database Applications Overview of SQL Data Types ................................................................................................................ 1-1 Representing Character Data ................................................................................................................. 1-2 Specifying Column Lengths as Bytes or Characters ..................................................................... 1-2 Choosing Between CHAR and VARCHAR2 Data Types ............................................................ 1-3 Representing Numeric Data................................................................................................................... 1-4 Floating-Point Number Components.............................................................................................. 1-5 Floating-Point Number Formats...................................................................................................... 1-5 Binary Floating-Point Formats.................................................................................................. 1-6 Special Values for Native Floating-Point Formats ................................................................. 1-7 Comparison Operators for Native Floating-Point Data Types ................................................... 1-8 Arithmetic Operations with Native Floating-Point Data Types ................................................. 1-8 Conversion Functions for Floating-Point Data Types .................................................................. 1-9 Client Interfaces for Native Floating-Point Data Types ............................................................ 1-10 OCI Native Floating-Point Data Types SQLT_BFLOAT and SQLT_BDOUBLE............ 1-10 Native Floating-Point Data Types Supported in ADTs ..................................................... 1-10 Pro*C/C++ Support for Native Floating-Point Data Types .............................................. 1-10 Representing Date and Time Data..................................................................................................... 1-10 Displaying Current Date and Time .............................................................................................. 1-11 Displaying and Inserting Dates in Nondefault Formats ........................................................... 1-12 Displaying and Inserting Times in Nondefault Formats .......................................................... 1-13 iii Arithmetic Operations with Datetime Data Types .................................................................... Conversion Functions for Datetime Data Types ........................................................................ Importing, Exporting, and Comparing Datetime Types ........................................................... Representing Specialized Data........................................................................................................... Representing Geographic Data ..................................................................................................... Representing Multimedia Data ..................................................................................................... Representing Large Amounts of Data.......................................................................................... Large Objects (LOBs) ............................................................................................................... LONG and LONG RAW Data Types .................................................................................... Representing Searchable Text........................................................................................................ Representing XML Data ................................................................................................................. Representing Dynamically Typed Data....................................................................................... Representing ANSI, DB2, and SQL/DS Data ............................................................................. Representing Conditional Expressions as Data .............................................................................. Identifying Rows by Address ............................................................................................................. Querying the ROWID Pseudocolumn ......................................................................................... ROWID Data Type .......................................................................................................................... Restricted Internal ROWID Format....................................................................................... Extended Internal ROWID Format........................................................................................ External Binary Internal ROWID Format............................................................................. UROWID Data Type ....................................................................................................................... How Oracle Database Converts Data Types.................................................................................... Data Type Conversion During Assignments .............................................................................. Data Type Conversion During Expression Evaluation ............................................................. Metadata for SQL Operators and Functions .................................................................................... ARGn Data Type ............................................................................................................................. DISP_TYPE Data Type ................................................................................................................... Data Type Families ......................................................................................................................... 1-14 1-15 1-15 1-16 1-16 1-16 1-16 1-17 1-17 1-18 1-18 1-19 1-21 1-21 1-22 1-23 1-24 1-24 1-24 1-25 1-25 1-25 1-25 1-27 1-27 1-27 1-28 1-28 2 SQL Processing for Application Developers Description of SQL Statement Processing .......................................................................................... 2-1 Grouping Operations into Transactions.............................................................................................. 2-4 Deciding How to Group Operations in Transactions ................................................................... 2-4 Improving Transaction Performance .............................................................................................. 2-4 Committing Transactions.................................................................................................................. 2-5 Managing Commit Redo Action ...................................................................................................... 2-5 Rolling Back Transactions................................................................................................................. 2-7 Defining Transaction Savepoints ..................................................................................................... 2-7 Ensuring Repeatable Reads with Read-Only Transactions ............................................................. 2-8 Using Cursors............................................................................................................................................ 2-9 How Many Cursors Can a Session Have? ...................................................................................... 2-9 Using a Cursor to Reexecute a Statement....................................................................................... 2-9 Scrollable Cursors ........................................................................................................................... 2-10 Closing a Cursor.............................................................................................................................. 2-10 Canceling a Cursor.......................................................................................................................... 2-10 Locking Tables Explicitly .................................................................................................................... 2-11 Privileges Required to Acquire Table Locks ............................................................................... 2-11 iv Choosing a Locking Strategy......................................................................................................... When to Lock with ROW SHARE MODE and ROW EXCLUSIVE MODE .................... When to Lock with SHARE MODE....................................................................................... When to Lock with SHARE ROW EXCLUSIVE MODE .................................................... When to Lock with EXCLUSIVE MODE.............................................................................. Letting Oracle Database Control Table Locking......................................................................... Explicitly Acquiring Row Locks ................................................................................................... Examples of Concurrency Under Explicit Locking.................................................................... Using Oracle Lock Management Services (User Locks) ................................................................ When to Use User Locks ................................................................................................................ Viewing and Monitoring Locks .................................................................................................... Using Serializable Transactions for Concurrency Control ........................................................... Transaction Interaction and Isolation Level................................................................................ Setting Isolation Levels................................................................................................................... Serializable Transactions and Referential Integrity ................................................................... READ COMMITTED and SERIALIZABLE Isolation Levels .................................................... Transaction Set Consistency Differences.............................................................................. Choosing Transaction Isolation Levels ................................................................................. Autonomous Transactions................................................................................................................... Examples of Autonomous Transactions ...................................................................................... Ordering a Product .................................................................................................................. Withdrawing Money from a Bank Account......................................................................... Defining Autonomous Transactions ............................................................................................ Resuming Execution After Storage Allocation Errors.................................................................... What Operations Have Resumable Storage Allocation?........................................................... Handling Suspended Storage Allocation .................................................................................... Using an AFTER SUSPEND Trigger in the Application .................................................... Checking for Suspended Statements..................................................................................... 2-12 2-12 2-13 2-14 2-14 2-14 2-15 2-15 2-22 2-22 2-23 2-23 2-24 2-26 2-27 2-28 2-29 2-29 2-30 2-32 2-33 2-33 2-36 2-37 2-37 2-37 2-38 2-39 3 Using Regular Expressions in Database Applications Overview of Regular Expressions......................................................................................................... 3-1 Oracle SQL Support for Regular Expressions .................................................................................... 3-2 Oracle SQL and POSIX Regular Expression Standard ..................................................................... 3-4 Operators in Oracle SQL Regular Expressions .................................................................................. 3-4 POSIX Operators in Oracle SQL Regular Expressions ................................................................. 3-4 Oracle SQL Multilingual Extensions to POSIX Standard............................................................. 3-7 Oracle SQL PERL-Influenced Extensions to POSIX Standard..................................................... 3-7 Using Regular Expressions in SQL Statements: Scenarios .............................................................. 3-9 Using a Constraint to Enforce a Phone Number Format ............................................................. 3-9 Using Back References to Reposition Characters ....................................................................... 3-10 4 Using Indexes in Database Applications Guidelines for Managing Indexes ........................................................................................................ Managing Indexes .................................................................................................................................... When to Use Domain Indexes ............................................................................................................... When to Use Function-Based Indexes .................................................................................................. 4-1 4-2 4-2 4-2 v Advantages of Function-Based Indexes.......................................................................................... 4-3 Disadvantages of Function-Based Indexes..................................................................................... 4-4 Examples of Function-Based Indexes.............................................................................................. 4-5 5 Maintaining Data Integrity in Database Applications Enforcing Business Rules with Constraints........................................................................................ 5-2 Enforcing Business Rules with Both Constraints and Application Code..................................... 5-3 Creating Indexes for Use with Constraints ......................................................................................... 5-4 When to Use NOT NULL Constraints.................................................................................................. 5-4 When to Use Default Column Values .................................................................................................. 5-5 Choosing a Primary Key for a Table (PRIMARY KEY Constraint)................................................ 5-6 When to Use UNIQUE Constraints....................................................................................................... 5-7 Enforcing Referential Integrity with FOREIGN KEY Constraints................................................. 5-8 FOREIGN KEY Constraints and NULL Values.......................................................................... 5-10 Defining Relationships Between Parent and Child Tables ....................................................... 5-10 Rules for Multiple FOREIGN KEY Constraints ......................................................................... 5-11 Deferring Constraint Checks ......................................................................................................... 5-11 Minimizing Space and Time Overhead for Indexes Associated with Constraints .................. 5-13 Guidelines for Indexing Foreign Keys.............................................................................................. 5-13 Referential Integrity in a Distributed Database ............................................................................. 5-13 When to Use CHECK Constraints...................................................................................................... 5-14 Restrictions on CHECK Constraints ............................................................................................ 5-14 Designing CHECK Constraints..................................................................................................... 5-15 Rules for Multiple CHECK Constraints....................................................................................... 5-15 Choosing Between CHECK and NOT NULL Constraints........................................................ 5-15 Examples of Defining Constraints..................................................................................................... 5-16 Privileges Needed to Define Constraints..................................................................................... 5-17 Naming Constraints ....................................................................................................................... 5-17 Enabling and Disabling Constraints ................................................................................................. 5-17 Why Disable Constraints?.............................................................................................................. 5-18 Creating Enabled Constraints (Default)....................................................................................... 5-18 Creating Disabled Constraints ...................................................................................................... 5-19 Enabling Existing Constraints ....................................................................................................... 5-19 Disabling Existing Constraints...................................................................................................... 5-20 Guidelines for Enabling and Disabling Key Constraints .......................................................... 5-20 Fixing Constraint Exceptions......................................................................................................... 5-21 Modifying Constraints ......................................................................................................................... 5-21 Renaming Constraints.......................................................................................................................... 5-22 Dropping Constraints........................................................................................................................... 5-23 Managing FOREIGN KEY Constraints ............................................................................................ 5-24 Data Types and Names for Foreign Key Columns .................................................................... 5-24 Limit on Columns in Composite Foreign Keys .......................................................................... 5-24 Foreign Key References Primary Key by Default....................................................................... 5-24 Privileges Required to Create FOREIGN KEY Constraints ...................................................... 5-24 Choosing How Foreign Keys Enforce Referential Integrity ..................................................... 5-24 Viewing Information About Constraints ......................................................................................... 5-25 vi Part II PL/SQL for Application Developers 6 Coding PL/SQL Subprograms and Packages Overview of PL/SQL Units..................................................................................................................... 6-1 Anonymous Blocks ............................................................................................................................ 6-2 Stored PL/SQL Units......................................................................................................................... 6-4 Naming Subprograms ................................................................................................................ 6-5 Subprogram Parameters ............................................................................................................ 6-5 Creating Subprograms ............................................................................................................... 6-8 Altering Subprograms................................................................................................................ 6-9 Dropping Subprograms and Packages .................................................................................... 6-9 External Subprograms................................................................................................................ 6-9 PL/SQL Function Result Cache................................................................................................ 6-9 PL/SQL Packages .................................................................................................................... 6-10 PL/SQL Object Size Limits..................................................................................................... 6-13 Creating Packages.................................................................................................................... 6-13 Naming Packages and Package Objects ............................................................................... 6-14 Package Invalidations and Session State .............................................................................. 6-14 Packages Supplied with Oracle Database ............................................................................ 6-15 Overview of Bulk Binding ...................................................................................................... 6-15 When to Use Bulk Binds ......................................................................................................... 6-16 Triggers...................................................................................................................................... 6-18 Compiling PL/SQL Subprograms for Native Execution................................................................ 6-18 Cursor Variables.................................................................................................................................... 6-18 Declaring and Opening Cursor Variables ................................................................................... 6-19 Examples of Cursor Variables ...................................................................................................... 6-19 Handling PL/SQL Compile-Time Errors .......................................................................................... 6-21 Handling Runtime PL/SQL Errors ..................................................................................................... 6-22 Declaring Exceptions and Exception Handlers .......................................................................... 6-23 Unhandled Exceptions ................................................................................................................... 6-24 Handling Errors in Distributed Queries ...................................................................................... 6-25 Handling Errors in Remote Subprograms................................................................................... 6-25 Debugging Stored Subprograms........................................................................................................ 6-26 PL/Scope .......................................................................................................................................... 6-26 PL/SQL Hierarchical Profiler........................................................................................................ 6-26 Oracle JDeveloper ........................................................................................................................... 6-27 DBMS_OUTPUT Package .............................................................................................................. 6-27 Privileges for Debugging PL/SQL and Java Stored Subprograms ......................................... 6-27 Writing Low-Level Debugging Code........................................................................................... 6-28 DBMS_DEBUG_JDWP Package.................................................................................................... 6-28 DBMS_DEBUG Package................................................................................................................. 6-28 Invoking Stored Subprograms ........................................................................................................... 6-28 Privileges Required to Invoke a Subprogram............................................................................. 6-29 Invoking a Subprogram Interactively from Oracle Tools ......................................................... 6-30 Invoking a Subprogram from Another Subprogram................................................................. 6-31 Invoking a Subprogram from a 3GL Application ...................................................................... 6-32 vii Invoking Remote Subprograms ......................................................................................................... Synonyms for Remote Subprograms............................................................................................ Committing Transactions............................................................................................................... Invoking Stored PL/SQL Functions from SQL Statements .......................................................... Why Invoke Stored PL/SQL Subprograms from SQL Statements? ........................................ Where PL/SQL Functions Can Appear in SQL Statements ..................................................... When PL/SQL Functions Can Appear in SQL Expressions..................................................... Controlling Side Effects.................................................................................................................. Restrictions................................................................................................................................ Declaring a Function................................................................................................................ Parallel Query and Parallel DML .......................................................................................... PRAGMA RESTRICT_REFERENCES for Backward Compatibility ................................ Returning Large Amounts of Data from a Function....................................................................... Coding Your Own Aggregate Functions........................................................................................... 6-32 6-33 6-34 6-35 6-35 6-36 6-36 6-37 6-38 6-38 6-40 6-41 6-44 6-44 7 Using PL/Scope Specifying Identifier Collection............................................................................................................ 7-1 PL/Scope Identifier Data for STANDARD and DBMS_STANDARD.......................................... 7-2 How Much Space is PL/Scope Data Using? ........................................................................................ 7-4 Viewing PL/Scope Data .......................................................................................................................... 7-4 Static Data Dictionary Views............................................................................................................ 7-5 Unique Keys................................................................................................................................. 7-5 Context.......................................................................................................................................... 7-5 Signature ...................................................................................................................................... 7-7 Demo Tool ........................................................................................................................................... 7-7 SQL Developer.................................................................................................................................... 7-7 Identifier Types that PL/Scope Collects .............................................................................................. 7-7 Usages that PL/Scope Reports................................................................................................................ 7-9 Sample PL/Scope Session .................................................................................................................... 7-10 8 Using the PL/SQL Hierarchical Profiler Overview of PL/SQL Hierarchical Profiler ......................................................................................... 8-1 Collecting Profile Data ............................................................................................................................ 8-2 Understanding Raw Profiler Output.................................................................................................... 8-3 Namespaces of Tracked Subprograms............................................................................................ 8-6 Special Function Names .................................................................................................................... 8-6 Analyzing Profile Data............................................................................................................................ 8-6 Creating Hierarchical Profiler Tables.............................................................................................. 8-7 Understanding Hierarchical Profiler Tables .................................................................................. 8-8 Hierarchical Profiler Database Table Columns ...................................................................... 8-8 Distinguishing Between Overloaded Subprograms ........................................................... 8-10 Hierarchical Profiler Tables for Sample PL/SQL Procedure............................................. 8-10 Examples of Calls to DBMS_HPROF.analyze with Options ............................................. 8-11 plshprof Utility ...................................................................................................................................... 8-13 plshprof Options ............................................................................................................................. 8-13 HTML Report from a Single Raw Profiler Output File ............................................................. 8-14 First Page of Report ................................................................................................................. 8-14 viii Function-Level Reports ........................................................................................................... Module-Level Reports............................................................................................................. Namespace-Level Reports ...................................................................................................... Parents and Children Report for a Function........................................................................ HTML Difference Report from Two Raw Profiler Output Files .............................................. Difference Report Conventions.............................................................................................. First Page of Difference Report .............................................................................................. Function-Level Difference Reports........................................................................................ Module-Level Difference Reports ......................................................................................... Namespace-Level Difference Reports................................................................................... Parents and Children Difference Report for a Function .................................................... 8-15 8-16 8-16 8-17 8-18 8-19 8-19 8-20 8-21 8-22 8-22 9 Developing PL/SQL Web Applications Overview of PL/SQL Web Applications.............................................................................................. 9-1 Implementing PL/SQL Web Applications .......................................................................................... 9-2 PL/SQL Gateway............................................................................................................................... 9-2 mod_plsql..................................................................................................................................... 9-2 Embedded PL/SQL Gateway ................................................................................................... 9-3 PL/SQL Web Toolkit ......................................................................................................................... 9-3 Using mod_plsql Gateway to Map Client Requests to a PL/SQL Web Application .................. 9-4 Using Embedded PL/SQL Gateway...................................................................................................... 9-4 How Embedded PL/SQL Gateway Processes Client Requests .................................................. 9-5 Installing Embedded PL/SQL Gateway......................................................................................... 9-6 Configuring Embedded PL/SQL Gateway.................................................................................... 9-6 Configuring Embedded PL/SQL Gateway: Overview ......................................................... 9-6 Configuring User Authentication for Embedded PL/SQL Gateway.................................. 9-8 Invoking PL/SQL Stored Subprograms Through Embedded PL/SQL Gateway................. 9-17 Securing Application Access with Embedded PL/SQL Gateway ........................................... 9-17 Restrictions in Embedded PL/SQL Gateway ............................................................................. 9-18 Using Embedded PL/SQL Gateway: Scenario ........................................................................... 9-18 Generating HTML Output with PL/SQL.......................................................................................... 9-20 Passing Parameters to PL/SQL Web Applications.......................................................................... 9-21 Passing List and Dropdown-List Parameters from an HTML Form....................................... 9-21 Passing Option and Check Box Parameters from an HTML Form.......................................... 9-22 Passing Entry-Field Parameters from an HTML Form.............................................................. 9-22 Passing Hidden Parameters from an HTML Form .................................................................... 9-24 Uploading a File from an HTML Form........................................................................................ 9-24 Submitting a Completed HTML Form......................................................................................... 9-24 Handling Missing Input from an HTML Form .......................................................................... 9-25 Maintaining State Information Between Web Pages ................................................................. 9-25 Performing Network Operations in PL/SQL Subprograms.......................................................... 9-26 Sending Email from PL/SQL ........................................................................................................ 9-26 Getting a Host Name or Address from PL/SQL........................................................................ 9-27 Using TCP/IP Connections from PL/SQL.................................................................................. 9-27 Retrieving HTTP URL Contents from PL/SQL.......................................................................... 9-27 Using Tables, Image Maps, Cookies, and CGI Variables from PL/SQL ............................... 9-29 ix 10 Developing PL/SQL Server Pages (PSP) What Are PL/SQL Server Pages and Why Use Them? ................................................................... Prerequisites for Developing and Deploying PL/SQL Server Pages .......................................... PL/SQL Server Pages and the HTP Package .................................................................................... PL/SQL Server Pages and Other Scripting Solutions .................................................................... Developing PL/SQL Server Pages...................................................................................................... Specifying Basic Server Page Characteristics .............................................................................. Specifying the Scripting Language........................................................................................ Returning Data to the Client Browser................................................................................... Handling Script Errors ............................................................................................................ Accepting User Input...................................................................................................................... Naming the PL/SQL Stored Procedure....................................................................................... Including the Contents of Other Files .......................................................................................... Declaring Global Variables in a PSP Script ............................................................................... Specifying Executable Statements in a PSP Script.................................................................... Substituting Expression Values in a PSP Script........................................................................ Using Quotation Marks and Escaping Strings in a PSP Script............................................... Including Comments in a PSP Script ......................................................................................... Loading PL/SQL Server Pages into the Database ......................................................................... Querying PL/SQL Server Page Source Code.................................................................................. Running PL/SQL Server Pages Through URLs ............................................................................. Examples of PL/SQL Server Pages ................................................................................................... Setup for PL/SQL Server Pages Examples................................................................................ Printing the Sample Table with a Loop ..................................................................................... Allowing a User Selection............................................................................................................ Using an HTML Form to Invoke a PL/SQL Server Page........................................................ Including JavaScript in a PSP File............................................................................................... Debugging PL/SQL Server Pages..................................................................................................... Putting PL/SQL Server Pages into Production .............................................................................. 10-1 10-2 10-3 10-3 10-4 10-5 10-6 10-6 10-7 10-8 10-9 10-9 10-10 10-10 10-11 10-12 10-12 10-13 10-14 10-15 10-16 10-16 10-17 10-18 10-19 10-20 10-21 10-22 11 Using Continuous Query Notification (CQN) Object Change Notification (OCN) ................................................................................................... Query Result Change Notification (QRCN) .................................................................................... Guaranteed Mode ........................................................................................................................... Best-Effort Mode ............................................................................................................................. Events that Generate Notifications.................................................................................................... Committed DML Transactions...................................................................................................... Committed DDL Statements ......................................................................................................... Deregistration .................................................................................................................................. Global Events ................................................................................................................................... Notification Contents ........................................................................................................................... Good Candidates for CQN .................................................................................................................. Creating CQN Registrations ............................................................................................................. PL/SQL CQN Registration Interface ......................................................................................... CQN Registration Options........................................................................................................... Notification Type Option...................................................................................................... QRCN Mode (QRCN Notification Type Only) ................................................................. x 11-2 11-2 11-3 11-3 11-4 11-5 11-5 11-6 11-6 11-7 11-7 11-10 11-10 11-11 11-11 11-11 ROWID Option....................................................................................................................... Operations Filter Option (OCN Notification Type Only)................................................ Transaction Lag Option (OCN Notification Type Only) ................................................. Notification Grouping Options............................................................................................ Reliable Option....................................................................................................................... Purge-on-Notify and Timeout Options .............................................................................. Prerequisites for Creating CQN Registrations.......................................................................... Queries that Can Be Registered for Object Change Notification (OCN) .............................. Queries that Can Be Registered for Query Result Change Notification (QRCN)................ Queries that Can Be Registered for QRCN in Guaranteed Mode................................... Queries that Can Be Registered for QRCN Only in Best-Effort Mode........................... Queries that Cannot Be Registered for QRCN in Either Mode....................................... Using PL/SQL to Register Queries for CQN ............................................................................ Creating a PL/SQL Notification Handler .......................................................................... Creating a CQ_NOTIFICATION$_REG_INFO Object..................................................... Identifying Individual Queries in a Notification .............................................................. Adding Queries to an Existing Registration ...................................................................... Best Practices for CQN Registrations ......................................................................................... Troubleshooting CQN Registrations.......................................................................................... Querying CQN Registrations............................................................................................................ Interpreting Notifications.................................................................................................................. Interpreting a CQ_NOTIFICATION$_DESCRIPTOR Object................................................. Interpreting a CQ_NOTIFICATION$_TABLE Object ............................................................. Interpreting a CQ_NOTIFICATION$_QUERY Object ............................................................ Interpreting a CQ_NOTIFICATION$_ROW Object ................................................................ Deleting Registrations........................................................................................................................ Configuring CQN: Scenario.............................................................................................................. Creating a PL/SQL Notification Handler ................................................................................. Registering the Queries ................................................................................................................ Part III 11-12 11-12 11-13 11-13 11-14 11-14 11-15 11-15 11-15 11-16 11-16 11-17 11-18 11-18 11-19 11-22 11-22 11-23 11-23 11-24 11-25 11-25 11-26 11-26 11-27 11-27 11-27 11-28 11-30 Advanced Topics for Application Developers 12 Using Oracle Flashback Technology Overview of Oracle Flashback Technology ..................................................................................... Application Development Features.............................................................................................. Database Administration Features ............................................................................................... Configuring Your Database for Oracle Flashback Technology ................................................... Configuring Your Database for Automatic Undo Management.............................................. Configuring Your Database for Oracle Flashback Transaction Query ................................... Configuring Your Database for Flashback Transaction ............................................................ Enabling Oracle Flashback Operations on Specific LOB Columns.......................................... Granting Necessary Privileges ...................................................................................................... Using Oracle Flashback Query (SELECT AS OF)........................................................................... Example of Examining and Restoring Past Data........................................................................ Guidelines for Oracle Flashback Query....................................................................................... Using Oracle Flashback Version Query............................................................................................ 12-1 12-2 12-3 12-3 12-3 12-4 12-4 12-5 12-5 12-6 12-6 12-7 12-8 xi Using Oracle Flashback Transaction Query .................................................................................... Using Oracle Flashback Transaction Query with Oracle Flashback Version Query............. Using DBMS_FLASHBACK Package ............................................................................................. Using Flashback Transaction ............................................................................................................ Dependent Transactions............................................................................................................... TRANSACTION_BACKOUT Parameters................................................................................. TRANSACTION_BACKOUT Reports ....................................................................................... *_FLASHBACK_TXN_STATE ............................................................................................. *_FLASHBACK_TXN_REPORT .......................................................................................... Using Flashback Data Archive (Oracle Total Recall)................................................................... Creating a Flashback Data Archive ............................................................................................ Altering a Flashback Data Archive............................................................................................. Dropping a Flashback Data Archive .......................................................................................... Specifying the Default Flashback Data Archive ....................................................................... Enabling and Disabling Flashback Data Archive..................................................................... DDL Statements on Tables Enabled for Flashback Data Archive .......................................... Viewing Flashback Data Archive Data ...................................................................................... Flashback Data Archive Scenarios.............................................................................................. Scenario: Using Flashback Data Archive to Enforce Digital Shredding ........................ Scenario: Using Flashback Data Archive to Access Historical Data............................... Scenario: Using Flashback Data Archive to Generate Reports ....................................... Scenario: Using Flashback Data Archive for Auditing .................................................... Scenario: Using Flashback Data Archive to Recover Data............................................... General Guidelines for Oracle Flashback Technology ............................................................... Performance Guidelines for Oracle Flashback Technology ....................................................... 12-9 12-10 12-12 12-13 12-14 12-14 12-15 12-15 12-15 12-16 12-17 12-17 12-18 12-19 12-19 12-20 12-21 12-21 12-21 12-22 12-22 12-22 12-23 12-23 12-25 13 Choosing a Programming Environment Overview of Application Architecture.............................................................................................. Client/Server Architecture ............................................................................................................ Server-Side Programming.............................................................................................................. Two-Tier and Three-Tier Architecture......................................................................................... Overview of the Program Interface.................................................................................................... User Interface................................................................................................................................... Stateful and Stateless User Interfaces........................................................................................... Overview of PL/SQL............................................................................................................................. Overview of Oracle Database Java Support..................................................................................... Overview of Oracle JVM ................................................................................................................ Overview of Oracle JDBC .............................................................................................................. Oracle JDBC Drivers ................................................................................................................ Sample JDBC 2.0 Program ...................................................................................................... Sample Pre-2.0 JDBC Program ............................................................................................... Overview of Oracle SQLJ ............................................................................................................... Benefits of SQLJ........................................................................................................................ SQLJ Stored Subprograms in the Server............................................................................. Comparing Oracle JDBC and Oracle SQLJ................................................................................ Overview of Oracle JPublisher.................................................................................................... Overview of Java Stored Subprograms...................................................................................... xii 13-2 13-2 13-2 13-2 13-3 13-3 13-3 13-4 13-4 13-5 13-5 13-6 13-7 13-8 13-8 13-9 13-10 13-10 13-11 13-11 Overview of Oracle Database Web Services ............................................................................. Choosing PL/SQL or Java .................................................................................................................. Similarities of PL/SQL and Java................................................................................................. PL/SQL Advantages Over Java .................................................................................................. Java Advantages Over PL/SQL .................................................................................................. Overview of Precompilers ................................................................................................................. Overview of the Pro*C/C++ Precompiler................................................................................. Overview of the Pro*COBOL Precompiler................................................................................ Overview of OCI and OCCI.............................................................................................................. Advantages of OCI and OCCI..................................................................................................... OCI and OCCI Functions ............................................................................................................. Procedural and Nonprocedural Elements of OCI and OCCI Applications ......................... Building an OCI or OCCI Application....................................................................................... Choosing a Precompiler or OCI........................................................................................................ Overview of Oracle Data Provider for .NET (ODP.NET)............................................................ Overview of OraOLEDB .................................................................................................................... Overview of Oracle Objects for OLE (OO4O)............................................................................... OO4O Automation Server ........................................................................................................... OO4O Object Model ..................................................................................................................... OraSession............................................................................................................................... OraServer ................................................................................................................................ OraDatabase............................................................................................................................ OraDynaset ............................................................................................................................. OraField................................................................................................................................... OraMetaData and OraMDAttribute.................................................................................... OraParameter and OraParameters ...................................................................................... OraParamArray...................................................................................................................... OraSQLStmt............................................................................................................................ OraAQ ..................................................................................................................................... OraAQMsg.............................................................................................................................. OraAQAgent........................................................................................................................... Support for Oracle LOB and Object Data Types ...................................................................... OraBLOB and OraCLOB ....................................................................................................... OraBFILE................................................................................................................................. Oracle Data Control ...................................................................................................................... Oracle Objects for OLE C++ Class Library................................................................................ 13-12 13-13 13-13 13-14 13-14 13-14 13-14 13-16 13-18 13-19 13-19 13-19 13-20 13-21 13-21 13-22 13-22 13-23 13-24 13-25 13-25 13-25 13-26 13-26 13-26 13-26 13-26 13-27 13-27 13-27 13-27 13-27 13-28 13-28 13-28 13-29 14 Developing Applications with Multiple Programming Languages Overview of Multilanguage Programs.............................................................................................. What Is an External Procedure? .......................................................................................................... Overview of Call Specification for External Procedures............................................................... Loading External Procedures .............................................................................................................. Loading Java Class Methods ......................................................................................................... Loading External C Procedures .................................................................................................... Define the C Procedures ......................................................................................................... Set Up the Environment.......................................................................................................... Identify the DLL....................................................................................................................... 14-1 14-2 14-3 14-3 14-4 14-4 14-5 14-5 14-7 xiii Publish the External Procedures............................................................................................ Publishing External Procedures ......................................................................................................... AS LANGUAGE Clause for Java Class Methods ..................................................................... AS LANGUAGE Clause for External C Procedures ................................................................ LIBRARY ................................................................................................................................ NAME ..................................................................................................................................... LANGUAGE .......................................................................................................................... CALLING STANDARD ........................................................................................................ WITH CONTEXT .................................................................................................................. PARAMETERS ...................................................................................................................... AGENT IN .............................................................................................................................. Publishing Java Class Methods ........................................................................................................ Publishing External C Procedures ................................................................................................... Locations of Call Specifications ....................................................................................................... Example: Locating a Call Specification in a PL/SQL Package ............................................... Example: Locating a Call Specification in a PL/SQL Package Body..................................... Example: Locating a Call Specification in an ADT Specification........................................... Example: Locating a Call Specification in an ADT Body ........................................................ Example: Java with AUTHID ...................................................................................................... Example: C with Optional AUTHID .......................................................................................... Example: Mixing Call Specifications in a Package................................................................... Passing Parameters to External C Procedures with Call Specifications ................................... Specifying Data Types .................................................................................................................. External Data Type Mappings .................................................................................................... Passing Parameters BY VALUE or BY REFERENCE............................................................... Declaring Formal Parameters...................................................................................................... Overriding Default Data Type Mapping ................................................................................... Specifying Properties .................................................................................................................... INDICATOR ........................................................................................................................... LENGTH and MAXLEN....................................................................................................... CHARSETID and CHARSETFORM.................................................................................... Repositioning Parameters..................................................................................................... SELF ......................................................................................................................................... BY REFERENCE..................................................................................................................... WITH CONTEXT ................................................................................................................... Interlanguage Parameter Mode Mappings ........................................................................ Running External Procedures with CALL Statements................................................................. Preconditions for External Procedures ...................................................................................... Privileges of External Procedures........................................................................................ Managing Permissions .......................................................................................................... Creating Synonyms for External Procedures..................................................................... CALL Statement Syntax ............................................................................................................... Calling Java Class Methods ......................................................................................................... Calling External C Procedures .................................................................................................... Handling Errors and Exceptions in Multilanguage Programs ................................................... Using Service Routines with External C Procedures.................................................................... OCIExtProcAllocCallMemory..................................................................................................... xiv 14-9 14-9 14-10 14-10 14-10 14-10 14-10 14-11 14-11 14-11 14-11 14-11 14-12 14-12 14-13 14-13 14-13 14-14 14-14 14-14 14-14 14-15 14-16 14-17 14-19 14-19 14-20 14-20 14-22 14-22 14-22 14-23 14-23 14-25 14-26 14-26 14-26 14-27 14-27 14-28 14-28 14-28 14-28 14-29 14-29 14-30 14-30 OCIExtProcRaiseExcp .................................................................................................................. OCIExtProcRaiseExcpWithMsg .................................................................................................. Doing Callbacks with External C Procedures................................................................................ OCIExtProcGetEnv ....................................................................................................................... Object Support for OCI Callbacks .............................................................................................. Restrictions on Callbacks ............................................................................................................. Debugging External Procedures ................................................................................................. Example: Calling an External Procedure ................................................................................... Global Variables in External C Procedures ............................................................................... Static Variables in External C Procedures ................................................................................. Restrictions on External C Procedures....................................................................................... 14-34 14-35 14-36 14-36 14-37 14-38 14-39 14-39 14-39 14-40 14-40 15 Developing Applications with Oracle XA X/Open Distributed Transaction Processing (DTP) ....................................................................... DTP Terminology............................................................................................................................ Required Public Information ......................................................................................................... Oracle XA Library Subprograms........................................................................................................ Oracle XA Library Subprograms .................................................................................................. Oracle XA Interface Extensions..................................................................................................... Developing and Installing XA Applications ................................................................................... DBA or System Administrator Responsibilities ......................................................................... Application Developer Responsibilities ...................................................................................... Defining the xa_open String .......................................................................................................... Syntax of the xa_open String.................................................................................................. Required Fields for the xa_open String ................................................................................ Optional Fields for the xa_open String ................................................................................. Using Oracle XA with Precompilers .......................................................................................... Using Precompilers with the Default Database ................................................................ Using Precompilers with a Named Database .................................................................... Using Oracle XA with OCI .......................................................................................................... Managing Transaction Control with Oracle XA....................................................................... Examples of Precompiler Applications...................................................................................... Migrating Precompiler or OCI Applications to TPM Applications....................................... Managing Oracle XA Library Thread Safety ............................................................................ Specifying Threading in the Open String........................................................................... Restrictions on Threading in Oracle XA ............................................................................. Using the DBMS_XA Package..................................................................................................... Troubleshooting XA Applications................................................................................................... Accessing Oracle XA Trace Files................................................................................................. xa_open String DbgFl ............................................................................................................ Trace File Locations ............................................................................................................... Managing In-Doubt or Pending Oracle XA Transactions ....................................................... Using SYS Account Tables to Monitor Oracle XA Transactions ............................................ Oracle XA Issues and Restrictions ................................................................................................... Using Database Links in Oracle XA Applications.................................................................... Managing Transaction Branches in Oracle XA Applications ................................................. Using Oracle XA with Oracle Real Application Clusters (Oracle RAC)............................... 15-1 15-2 15-4 15-5 15-5 15-6 15-6 15-7 15-8 15-8 15-8 15-9 15-9 15-11 15-11 15-11 15-12 15-13 15-14 15-14 15-15 15-16 15-16 15-16 15-19 15-19 15-20 15-20 15-20 15-20 15-21 15-21 15-22 15-22 xv GLOBAL_TXN_PROCESSES Initialization Parameter .................................................... Managing Transaction Branches on Oracle RAC.............................................................. Managing Instance Recovery in Oracle RAC with DTP Services ................................... Global Uniqueness of XIDs in Oracle RAC........................................................................ Tight and Loose Coupling .................................................................................................... SQL-Based Oracle XA Restrictions ............................................................................................. Rollbacks and Commits ........................................................................................................ DDL Statements ..................................................................................................................... Session State............................................................................................................................ EXEC SQL ............................................................................................................................... Miscellaneous Restrictions........................................................................................................... 15-23 15-23 15-24 15-25 15-25 15-25 15-26 15-26 15-26 15-26 15-26 16 Developing Applications with the Publish-Subscribe Model Introduction to the Publish-Subscribe Model................................................................................. Publish-Subscribe Architecture ......................................................................................................... Database Events............................................................................................................................... Oracle Advanced Queuing ............................................................................................................ Client Notification........................................................................................................................... Publish-Subscribe Concepts ............................................................................................................... Examples of a Publish-Subscribe Mechanism ................................................................................ 16-1 16-2 16-2 16-2 16-2 16-3 16-4 17 Using the Identity Code Package Identity Concepts .................................................................................................................................. 17-1 What is the Identity Code Package? .................................................................................................. 17-5 Using the Identity Code Package ....................................................................................................... 17-6 Storing RFID Tags in Oracle Database Using MGD_ID ADT .................................................. 17-6 Creating a Table with MGD_ID Column Type and Storing EPC Tag Encodings in the Column 17-6 Constructing MGD_ID Objects to Represent RFID Tags ................................................... 17-7 Inserting an MGD_ID Object into a Database Table........................................................... 17-9 Querying MGD_ID Column Type....................................................................................... 17-10 Building a Function-Based Index Using the Member Functions of the MGD_ID Column Type .. 17-10 Using MGD_ID ADT Functions.................................................................................................. 17-10 Using the get_component Function with the MGD_ID Object ....................................... 17-11 Parsing Tag Data from Standard Representations............................................................ 17-11 Reconstructing Tag Representations from Fields ............................................................. 17-12 Translating Between Tag Representations ......................................................................... 17-13 Defining a Category of Identity Codes and Adding Encoding Schemes to an Existing Category 17-13 Creating a Category of Identity Codes ............................................................................... 17-13 Adding Two Metadata Schemes to a Newly Created Category ..................................... 17-14 Identity Code Package Types............................................................................................................ 17-18 DBMS_MGD_ID_UTL Package....................................................................................................... 17-18 Identity Code Metadata Tables and Views.................................................................................... 17-19 Electronic Product Code (EPC) Concepts........................................................................................ 17-21 RFID Technology and EPC v1.1 Coding Schemes ................................................................... 17-21 xvi Product Code Concepts and Their Current Use....................................................................... 17-22 Electronic Product Code (EPC) ............................................................................................ 17-22 Global Trade Identification Number (GTIN) and Serializable Global Trade Identification Number (SGTIN) 17-24 Serial Shipping Container Code (SSCC)............................................................................. 17-24 Global Location Number (GLN) and Serializable Global Location Number (SGLN) . 17-24 Global Returnable Asset Identifier (GRAI) ........................................................................ 17-24 Global Individual Asset Identifier (GIAI) .......................................................................... 17-24 RFID EPC Network................................................................................................................ 17-24 Oracle Database Tag Data Translation Schema ............................................................................ 17-24 18 Schema Object Dependency Overview of Schema Object Dependencies..................................................................................... Querying Object Dependencies ......................................................................................................... Object Status .......................................................................................................................................... Invalidation of Dependent Objects ................................................................................................... Session State and Referenced Packages ....................................................................................... Security Authorization ................................................................................................................... Guidelines for Reducing Invalidation .............................................................................................. Add Items to End of Package ........................................................................................................ Reference Each Table Through a View ........................................................................................ Object Revalidation .............................................................................................................................. Name Resolution in Schema Scope ................................................................................................. Local Dependency Management ...................................................................................................... Remote Dependency Management.................................................................................................. Dependencies Among Local and Remote Database Procedures ........................................... Dependencies Among Other Remote Objects........................................................................... Dependencies of Applications..................................................................................................... Remote Procedure Call (RPC) Dependency Management.......................................................... Time-Stamp Dependency Mode ................................................................................................. RPC-Signature Dependency Mode............................................................................................. Changing Names and Default Values of Parameters ....................................................... Changing Specification of Parameter Mode IN................................................................. Changing Subprogram Body................................................................................................ Changing Data Type Classes of Parameters ...................................................................... Changing Package Types...................................................................................................... Controlling Dependency Mode................................................................................................... Dependency Resolution ........................................................................................................ Suggestions for Managing Dependencies .......................................................................... Shared SQL Dependency Management.......................................................................................... 18-1 18-4 18-4 18-4 18-8 18-8 18-8 18-8 18-9 18-9 18-10 18-11 18-11 18-11 18-12 18-12 18-12 18-12 18-13 18-15 18-15 18-15 18-16 18-17 18-18 18-18 18-19 18-19 19 Edition-Based Redefinition Editions.................................................................................................................................................... Editioned and Noneditioned Objects........................................................................................... Editionable and Noneditionable Schema Object Types ..................................................... Rules for Editioned Objects .................................................................................................... 19-2 19-2 19-3 19-3 xvii Enabling Editions for a User .................................................................................................. Creating an Edition ......................................................................................................................... Inherited and Actual Objects......................................................................................................... Dropping Inherited Objects.................................................................................................... Actualizing Referenced Objects ............................................................................................. Making an Edition Available to Some Users .............................................................................. Making an Edition Available to All Users................................................................................... Current Edition and Session Edition.......................................................................................... Your Initial Session Edition .................................................................................................. Changing Your Session Edition ........................................................................................... Displaying the Names of the Current and Session Editions ........................................... When the Current Edition Might Differ from the Session Edition................................. Retiring an Edition ........................................................................................................................ Dropping an Edition ..................................................................................................................... Editioning Views................................................................................................................................. Creating an Editioning View ....................................................................................................... Partition-Extended Editioning View Names............................................................................. Changing the 'Write-ability' of an Editioning View................................................................. Replacing an Editioning View..................................................................................................... Dropping or Renaming the Base Table ...................................................................................... Adding Indexes and Constraints to the Base Table ................................................................. SQL Optimizer Index Hints......................................................................................................... Crossedition Triggers ......................................................................................................................... Forward Crossedition Triggers ................................................................................................... Reverse Crossedition Triggers .................................................................................................... Crossedition Trigger Interaction with Editions ........................................................................ Which Triggers Are Visible .................................................................................................. What Kind of Triggers Can Fire........................................................................................... Firing Order ............................................................................................................................ Crossedition Trigger Execution ........................................................................................... Creating a Crossedition Trigger.................................................................................................. Coding the Forward Crossedition Trigger Body .............................................................. Transforming Data from Pre- to Post-Upgrade Representation ............................................ Preventing Lost Updates....................................................................................................... Dropping the Crossedition Triggers .......................................................................................... Displaying Information About Editions, Editioning Views, and Crossedition Triggers..... Using Edition-Based Redefinition to Upgrade an Application ................................................. Preparing Your Application to Use Editioning Views ............................................................ Procedure for Edition-Based Redefinition Using Only Editions ........................................... Procedure for Edition-Based Redefinition Using Editioning Views ..................................... Procedure for Edition-Based Redefinition Using Crossedition Triggers.............................. Rolling Back the Application Upgrade ...................................................................................... Reclaiming Space Occupied by Unused Table Columns ........................................................ Example: Using Edition-Based Redefinition to Upgrade an Application ............................ Existing Application .............................................................................................................. Preparing the Application to Use Editioning Views ........................................................ Using Edition-Based Redefinition to Upgrade the Application ..................................... xviii 19-4 19-5 19-5 19-7 19-9 19-9 19-9 19-10 19-10 19-11 19-12 19-12 19-13 19-14 19-15 19-16 19-16 19-16 19-17 19-17 19-17 19-17 19-17 19-18 19-18 19-18 19-19 19-19 19-20 19-21 19-21 19-22 19-24 19-25 19-26 19-26 19-28 19-29 19-30 19-32 19-33 19-34 19-34 19-35 19-35 19-36 19-37 A Multithreaded extproc Agent Why Use the Multithreaded extproc Agent?...................................................................................... The Challenge of Dedicated Agent Architecture ......................................................................... The Advantage of Multithreading.................................................................................................. Multithreaded extproc Agent Architecture ........................................................................................ Monitor Thread ................................................................................................................................. Dispatcher Threads ........................................................................................................................... Task Threads...................................................................................................................................... Administering the Multithreaded extproc Agent ............................................................................. Agent Control Utility (agtctl) Commands..................................................................................... Using agtctl in Single-Line Command Mode................................................................................ Setting Configuration Parameters for a Multithreaded extproc Agent ............................. Starting a Multithreaded extproc Agent................................................................................. Shutting Down a Multithreaded extproc Agent ................................................................... Examining the Value of Configuration Parameters.............................................................. Resetting a Configuration Parameter to Its Default Value .................................................. Deleting an Entry for a Specific SID from the Control File.................................................. Requesting Help......................................................................................................................... Using Shell Mode Commands......................................................................................................... Example: Setting a Configuration Parameter ........................................................................ Example: Starting a Multithreaded extproc Agent ............................................................... Configuration Parameters for Multithreaded extproc Agent Control ...................................... A-1 A-1 A-1 A-2 A-3 A-4 A-4 A-4 A-5 A-5 A-6 A-6 A-6 A-7 A-7 A-7 A-7 A-8 A-8 A-8 A-8 Index xix List of Examples 1–1 1–2 1–3 1–4 1–5 2–1 2–2 2–3 2–4 3–1 3–2 3–3 4–1 4–2 4–3 4–4 5–1 5–2 5–3 5–4 5–5 5–6 5–7 5–8 5–9 5–10 5–11 5–12 5–13 5–14 6–1 6–2 6–3 6–4 6–5 6–6 6–7 6–8 6–9 6–10 6–11 6–12 6–13 6–14 6–15 6–16 6–17 6–18 6–19 6–20 6–21 6–22 6–23 7–1 xx Displaying Current Date and Time in Nondefault Format ............................................... 1-12 Inserting and Displaying Date in Nondefault Formats...................................................... 1-12 Inserting and Displaying Dates and Times in Nondefault Formats ................................ 1-14 Accessing Information in a SYS.ANYDATA Column........................................................ 1-19 Querying the ROWID Pseudocolumn .................................................................................. 1-23 LOCK TABLE with SHARE MODE ...................................................................................... 2-13 How the Pro*COBOL Precompiler Uses Locks ................................................................... 2-22 Marking a Package Subprogram as Autonomous .............................................................. 2-36 AFTER SUSPEND Trigger Handles Suspended Storage Allocation................................ 2-38 Enforcing a Phone Number Format with Regular Expressions........................................... 3-9 Inserting Phone Numbers in Correct and Incorrect Formats ............................................ 3-10 Using Back References to Reposition Characters ................................................................ 3-10 Function-Based Index for Precomputing Arithmetic Expression........................................ 4-5 Function-Based Indexes on Object Column ............................................................................ 4-6 Function-Based Index for Faster Case-Insensitive Searches................................................. 4-7 Function-Based Index for Language-Dependent Sorting ..................................................... 4-7 Enforcing Business Rules with Constraints ............................................................................ 5-2 Enforcing Business Rules with Both Constraints and Application Code ........................... 5-3 Inserting NULL Values into Columns with NOT NULL Constraints ................................ 5-5 Deferring Constraint Checks.................................................................................................. 5-12 Defining Constraints with the CREATE TABLE Statement .............................................. 5-16 Defining Constraints with the ALTER TABLE Statement ................................................. 5-16 Creating Enabled Constraints ................................................................................................ 5-18 Creating Disabled Constraints ............................................................................................... 5-19 Enabling Existing Constraints................................................................................................ 5-19 Disabling Existing Constraints............................................................................................... 5-20 Modifying Constraints ............................................................................................................ 5-21 Renaming a Constraint............................................................................................................ 5-22 Dropping Constraints.............................................................................................................. 5-23 Viewing Information About Constraints.............................................................................. 5-25 Anonymous Block....................................................................................................................... 6-2 Anonymous Block with Exception Handler for Predefined Error ...................................... 6-3 Anonymous Block with Exception Handler for User-Defined Exception.......................... 6-3 Stored Procedure with Parameters........................................................................................... 6-5 %TYPE and %ROWTYPE Attributes ....................................................................................... 6-6 Creating PL/SQL Package and Invoking Package Subprogram ...................................... 6-10 Raising ORA-04068 .................................................................................................................. 6-14 Trapping ORA-04068............................................................................................................... 6-14 DML Statements that Reference Collections........................................................................ 6-16 SELECT Statements that Reference Collections .................................................................. 6-17 FOR Loops that Reference Collections and Return DML .................................................. 6-17 Fetching Data with Cursor Variable ..................................................................................... 6-19 Cursor Variable with Discriminator...................................................................................... 6-21 Compile-Time Errors............................................................................................................... 6-22 Invoking a Subprogram Interactively with SQL*Plus........................................................ 6-30 Creating and Using a Session Variable with SQL*Plus...................................................... 6-30 Invoking a Subprogram from Within Another Subprogram ............................................ 6-31 PL/SQL Function in SQL Expression (Follows Rules)....................................................... 6-36 PL/SQL Function in SQL Expression (Exception to Rule) ................................................ 6-37 PRAGMA RESTRICT_REFERENCES................................................................................... 6-42 PRAGMA RESTRICT REFERENCES with TRUST on Invokee ........................................ 6-43 PRAGMA RESTRICT REFERENCES with TRUST on Invoker ........................................ 6-43 Overloaded Package Function with PRAGMA RESTRICT_REFERENCES ................... 6-44 Is STANDARD and DBMS_STANDARD PL/Scope Identifier Data Available? .............. 7-2 7–2 7–3 7–4 8–1 8–2 8–3 8–4 8–5 8–6 9–1 9–2 9–3 9–4 9–5 9–6 9–7 9–8 9–9 9–10 9–11 9–12 10–1 10–2 10–3 10–4 10–5 10–6 10–7 10–8 10–9 10–10 10–11 10–12 10–13 11–1 11–2 11–3 11–4 11–5 11–6 11–7 12–1 12–2 13–1 13–2 15–1 15–2 15–3 15–4 15–5 18–1 18–2 18–3 18–4 18–5 How Much Space is PL/Scope Data Using?........................................................................... 7-4 USAGE_CONTEXT_ID and USAGE_ID................................................................................. 7-5 Program Unit with Two Identifiers Named p ........................................................................ 7-7 Profiling a PL/SQL Procedure.................................................................................................. 8-3 Invoking DBMS_HPROF.analyze............................................................................................. 8-8 DBMSHP_RUNS Table for Sample PL/SQL Procedure .................................................... 8-10 DBMSHP_FUNCTION_INFO Table for Sample PL/SQL Procedure ............................. 8-10 DBMSHP_PARENT_CHILD_INFO Table for Sample PL/SQL Procedure.................... 8-11 Invoking DBMS_HPROF.analyze with Options ................................................................. 8-11 Creating and Configuring DADs........................................................................................... 9-11 Authorizing DADs to be Created or Changed Later .......................................................... 9-12 Determining the Authentication Mode for a DAD ............................................................. 9-13 Showing the Authentication Mode for All DADs............................................................... 9-14 Showing DAD Authorizations that Are Not in Effect........................................................ 9-14 epgstat.sql Script Output for Example 9–1........................................................................... 9-15 Using HTP Functions to Generate HTML Tags .................................................................. 9-20 Using HTP.PRINT to Generate HTML Tags........................................................................ 9-20 HTML Drop-Down List .......................................................................................................... 9-22 Passing Entry-Field Parameters from an HTML Form ...................................................... 9-23 Sending Email from PL/SQL ................................................................................................. 9-26 Retrieving HTTP URL Contents from PL/SQL................................................................... 9-28 simple.psp ................................................................................................................................. 10-1 Sample Returned HTML Page ............................................................................................... 10-6 simplewithuserinput.psp........................................................................................................ 10-8 Sample Comments in a PSP File .......................................................................................... 10-13 Loading PL/SQL Server Pages ............................................................................................ 10-13 Querying PL/SQL Server Page Source Code .................................................................... 10-14 show_prod_simple.psp ......................................................................................................... 10-17 show_catalog_raw.psp.......................................................................................................... 10-17 show_catalog_pretty.psp ...................................................................................................... 10-18 show_product_partial.psp.................................................................................................... 10-18 show_product_highlighed.psp ............................................................................................ 10-19 product_form.psp .................................................................................................................. 10-20 show_product_javascript.psp .............................................................................................. 10-20 Query to be Registered for Change Notification................................................................. 11-2 Query Too Complex for QRCN in Guaranteed Mode ....................................................... 11-3 Query Whose Simplified Version Invalidates Objects ....................................................... 11-4 Creating a CQ_NOTIFICATION$_REG_INFO Object..................................................... 11-22 Adding a Query to an Existing Registration...................................................................... 11-22 Creating Server-Side PL/SQL Notification Handler........................................................ 11-28 Registering a Query ............................................................................................................... 11-30 Retrieving a Lost Row with Oracle Flashback Query......................................................... 12-7 Restoring a Lost Row After Oracle Flashback Query......................................................... 12-7 Pro*C/C++ Application........................................................................................................ 13-15 Pro*COBOL Application....................................................................................................... 13-17 xa_open String.......................................................................................................................... 15-8 Sample Open String Configuration..................................................................................... 15-12 Transaction Started by an Application Server................................................................... 15-14 Transaction Started by an Application Client.................................................................... 15-14 Using the DBMS_XA Package.............................................................................................. 15-16 Displaying Dependent and Referenced Object Types........................................................ 18-1 Schema Object Change that Invalidates Some Dependents .............................................. 18-3 View that Depends on Multiple Objects............................................................................... 18-4 Changing Body of Procedure get_hire_date...................................................................... 18-15 Changing Data Type Class of get_hire_date Parameter .................................................. 18-17 xxi 18–6 19–1 19–2 19–3 19–4 19–5 19–6 19–7 19–8 19–9 19–10 19–11 19–12 19–13 19–14 A–1 xxii Changing Names of Fields in Package Record Type........................................................ 18-17 Inherited and Actual Objects.................................................................................................. 19-5 Dropping an Inherited Object ................................................................................................ 19-7 Creating an Object with the Name of a Dropped Inherited Object .................................. 19-8 Current Edition Differs from Session Edition.................................................................... 19-12 Crossedition Trigger that Handles Data Transformation Collisions ............................. 19-23 Edition-Based Redefinition of Very Simple Procedure .................................................... 19-31 Creating the Existing Application ....................................................................................... 19-35 Viewing Data in Existing Table ........................................................................................... 19-36 Creating an Editioning View for the Existing Table ......................................................... 19-36 Creating Edition in Which to Upgrade the Application .................................................. 19-37 Changing the Table and Replacing the Editioning View................................................. 19-38 Creating and Enabling the Crossedition Triggers............................................................. 19-38 Applying the Transforms...................................................................................................... 19-41 Viewing Data in Changed Table.......................................................................................... 19-41 Setting Configuration Parameters and Starting agtctl.......................................................... A-4 List of Figures 2–1 2–2 2–3 2–4 2–5 2–6 2–7 2–8 5–1 5–2 6–1 9–1 9–2 11–1 11–2 13–1 13–2 13–3 13–4 14–1 15–1 16–1 17–1 17–2 A–1 Interaction Between Serializable Transaction and Another Transaction......................... 2-26 Referential Integrity Check..................................................................................................... 2-27 Transaction Control Flow ....................................................................................................... 2-31 Possible Sequences of Autonomous Transactions .............................................................. 2-32 Example: A Buy Order ............................................................................................................ 2-33 Bank Withdrawal—Sufficient Funds .................................................................................... 2-34 Bank Withdrawal—Insufficient Funds with Overdraft Protection .................................. 2-35 Bank Withdrawal—Insufficient Funds Without Overdraft Protection............................ 2-36 Rows That Violate and Satisfy a UNIQUE Constraint .......................................................... 5-7 Rows That Violate and Satisfy a FOREIGN KEY Constraint ............................................... 5-9 Exceptions and User-Defined Errors.................................................................................... 6-24 PL/SQL Web Application ......................................................................................................... 9-2 Processing Client Requests with Embedded PL/SQL Gateway.......................................... 9-5 Middle-Tier Caching ............................................................................................................... 11-8 Basic Process of Continuous Query Notification (CQN) ................................................... 11-9 The OCI or OCCI Development Process ............................................................................ 13-20 Software Layers...................................................................................................................... 13-23 Objects and Their Relations ................................................................................................. 13-24 Supported Oracle Database Data Types............................................................................. 13-28 Oracle Database and External Procedures ......................................................................... 14-27 Possible DTP Model................................................................................................................. 15-2 Oracle Publish-Subscribe Functionality................................................................................ 16-2 RFID Code Categories and Their Schemes .......................................................................... 17-2 Oracle Database Tag Data Translation Markup Language Schema................................. 17-4 Multithreaded extproc Agent Architecture ........................................................................... A-3 xxiii List of Tables 1–1 1–2 1–3 1–4 1–5 1–6 1–7 1–8 1–9 1–10 1–11 2–1 2–2 2–3 2–4 2–5 2–6 2–7 2–8 3–1 3–2 3–3 3–4 3–5 3–6 3–7 6–1 7–1 7–2 8–1 8–2 8–3 8–4 8–5 8–6 9–1 9–2 9–3 9–4 10–1 11–1 11–2 11–3 11–4 11–5 11–6 11–7 12–1 12–2 12–3 13–1 14–1 14–2 xxiv SQL Character Data Types ....................................................................................................... 1-2 Binary Floating-Point Format Components........................................................................... 1-6 Summary of Binary Format Storage Parameters.................................................................. 1-6 Range and Precision of Floating-Point Data Types ............................................................. 1-6 Special Values for Native Floating-Point Formats ................................................................ 1-7 Values Resulting from Exceptions........................................................................................... 1-9 SQL Datetime Data Types ..................................................................................................... 1-11 SQL Conversion Functions for Datetime Data Types ....................................................... 1-15 Large Objects (LOBs) ............................................................................................................. 1-17 Display Types of SQL Functions .......................................................................................... 1-28 Data Type Families ................................................................................................................. 1-28 COMMIT Statement Options ................................................................................................... 2-6 Use of COMMIT, SAVEPOINT, and ROLLBACK............................................................... 2-8 Examples of Concurrency Under Explicit Locking............................................................ 2-16 Ways to Display Locking Information................................................................................ 2-23 ANSI/ISO SQL Isolation Levels and Possible Transaction Interactions ....................... 2-24 ANSI/ISO SQL Isolation Levels Provided by Oracle Database ..................................... 2-25 Comparison of READ COMMITTED and SERIALIZABLE Transactions..................... 2-30 Possible Transaction Outcomes ........................................................................................... 2-33 Oracle SQL Pattern-Matching Condition and Functions ..................................................... 3-2 Pattern-Matching Options for Oracle SQL Pattern-Matching Condition and Functions 3-3 POSIX Operators in Oracle SQL Regular Expressions ......................................................... 3-5 POSIX Operators and Multilingual Operator Relationships............................................... 3-7 PERL-Influenced Operators in Oracle SQL Regular Expressions ...................................... 3-8 Explanation of the Regular Expression Elements in Example 3–1 ..................................... 3-9 Explanation of the Regular Expression Elements in Example 3–3 .................................. 3-11 Attributes of Subprogram Parameters................................................................................... 6-5 Identifier Types that PL/Scope Collects................................................................................. 7-8 Usages that PL/Scope Reports ................................................................................................ 7-9 Raw Profiler Output File Indicators........................................................................................ 8-4 Function Names of Operations that the PL/SQL Hierarchical Profiler Tracks................ 8-6 PL/SQL Hierarchical Profiler Database Tables..................................................................... 8-6 DBMSHP_RUNS Table Columns ............................................................................................ 8-8 DBMSHP_FUNCTION_INFO Table Columns...................................................................... 8-9 DBMSHP_PARENT_CHILD_INFO Table Columns......................................................... 8-10 Commonly Used Packages in the PL/SQL Web Toolkit .................................................... 9-3 Mapping Between mod_plsql and Embedded PL/SQL Gateway DAD Attributes ........ 9-7 Mapping Between mod_plsql and Embedded PL/SQL Gateway Global Attributes ..... 9-8 Authentication Possibilities for a DAD................................................................................ 9-11 PSP Elements ........................................................................................................................... 10-4 Continuous Query Notification Registration Options .................................................... 11-11 Attributes of CQ_NOTIFICATION$_REG_INFO............................................................ 11-19 Quality-of-Service Flags....................................................................................................... 11-21 Attributes of CQ_NOTIFICATION$_DESCRIPTOR....................................................... 11-25 Attributes of CQ_NOTIFICATION$_TABLE ................................................................... 11-26 Attributes of CQ_NOTIFICATION$_QUERY.................................................................. 11-27 Attributes of CQ_NOTIFICATION$_ROW ...................................................................... 11-27 Oracle Flashback Version Query Row Data Pseudocolumns ......................................... 12-8 Flashback TRANSACTION_BACKOUT Options............................................................ 12-15 Static Data Dictionary Views for Flashback Data Archive Files .................................... 12-21 PL/SQL Packages and Their Java Equivalents................................................................ 13-13 Parameter Data Type Mappings........................................................................................ 14-16 External Data Type Mappings ........................................................................................... 14-17 14–3 15–1 15–2 15–3 15–4 15–5 15–6 15–7 15–8 15–9 17–1 17–2 17–3 17–4 17–5 17–6 17–7 17–8 18–1 18–2 18–3 19–1 19–2 A–1 A–2 Properties and Data Types ................................................................................................. 14-21 Required XA Features Published by Oracle Database ...................................................... 15-5 XA Library Subprograms...................................................................................................... 15-5 Oracle XA Interface Extensions ............................................................................................ 15-6 Required Fields of xa_open string........................................................................................ 15-9 Optional Fields in the xa_open String.................................................................................. 15-9 TX Interface Functions ........................................................................................................ 15-13 TPM Replacement Statements ........................................................................................... 15-15 Sample Trace File Contents ................................................................................................. 15-19 Tightly and Loosely Coupled Transaction Branches...................................................... 15-22 General Structure of EPC Encodings ................................................................................... 17-2 Identity Code Package ADTs .............................................................................................. 17-18 MGD_ID ADT Subprograms............................................................................................... 17-18 DBMS_MGD_ID_UTL Package Utility Subprograms..................................................... 17-19 Definition and Description of the MGD_ID_CATEGORY Metadata View ................. 17-20 Definition and Description of the USER_MGD_ID_CATEGORY Metadata View..... 17-20 Definition and Description of the MGD_ID_SCHEME Metadata View....................... 17-21 Definition and Description of the USER_MGD_ID_SCHEME Metadata View .......... 17-21 Database Object Status ........................................................................................................... 18-4 Operations that Cause Fine-Grained Invalidation............................................................. 18-5 Data Type Classes ................................................................................................................. 18-16 *_ Dictionary Views with Edition Information................................................................. 19-27 *_ Dictionary Views with Editioning View Information................................................. 19-27 Agent Control Utility (agtctl) Commands............................................................................. A-5 Configuration Parameters for agtctl....................................................................................... A-8 xxv xxvi Preface Oracle Database Advanced Application Developer's Guide explains topics that experienced application developers reference repeatedly. Information in this guide applies to features that work the same on all supported platforms, and does not include system-specific information. Preface Topics: ■ Audience ■ Documentation Accessibility ■ Related Documents ■ Conventions Audience Oracle Database Advanced Application Developer's Guide is intended for application developers who are either developing applications or converting applications to run in the Oracle Database environment. This guide is also valuable to anyone who is interested in the development of database applications, such as systems analysts and project managers. To use this document effectively, you need a working knowledge of: ■ Application programming ■ Structured Query Language (SQL) ■ Object-oriented programming Documentation Accessibility For information about Oracle's commitment to accessibility, visit the Oracle Accessibility Program website at http://www.oracle.com/pls/topic/lookup?ctx=acc&id=docacc. Access to Oracle Support Oracle customers that have purchased support have access to electronic support through My Oracle Support. For information, visit http://www.oracle.com/pls/topic/lookup?ctx=acc&id=info or visit http://www.oracle.com/pls/topic/lookup?ctx=acc&id=trs if you are hearing impaired. xxvii Related Documents For more information, see these documents in the Oracle Database 11g Release 2 documentation set: ■ Oracle Database PL/SQL Language Reference ■ Oracle Call Interface Programmer's Guide ■ Oracle Database Security Guide ■ Pro*C/C++ Programmer's Guide ■ Oracle Database SQL Language Reference ■ Oracle Database Administrator's Guide ■ Oracle Database Concepts ■ Oracle XML Developer's Kit Programmer's Guide ■ Oracle XML DB Developer's Guide ■ Oracle Database Globalization Support Guide ■ Oracle Database Sample Schemas See also: ■ ■ ■ ■ Oracle PL/SQL Tips and Techniques by Joseph C. Trezzo. Oracle Press, 1999. Oracle PL/SQL Programming by Steven Feuerstein. 3rd Edition. O'Reilly & Associates, 2002. Oracle PL/SQL Developer's Workbook by Steven Feuerstein. O'Reilly & Associates, 2000. Oracle PL/SQL Best Practices by Steven Feuerstein. O'Reilly & Associates, 2001. Conventions This document uses these text conventions: Convention Meaning boldface Boldface type indicates graphical user interface elements associated with an action, or terms defined in text or the glossary. italic Italic type indicates book titles, emphasis, or placeholder variables for which you supply particular values. monospace Monospace type indicates commands within a paragraph, URLs, code in examples, text that appears on the screen, or text that you enter. Also: ■ ■ xxviii *_view means all static data dictionary views whose names end with view. For example, *_ERRORS means ALL_ERRORS, DBA_ERRORS, and USER_ERRORS. For more information about any static data dictionary view, or about static dictionary views in general, see Oracle Database Reference. Table names not qualified with schema names are in the sample schema HR. For information about the sample schemas, see Oracle Database Sample Schemas. What's New in Application Development? This topic briefly describes the new Oracle Database features that this book documents and provides links to more information. Topics: ■ Oracle Database 11g Release 2 (11.2.0.4) Feature ■ Oracle Database 11g Release 2 (11.2.0.2) Feature ■ Oracle Database 11g Release 2 Features ■ Oracle Database 11g Release 1 Features Oracle Database 11g Release 2 (11.2.0.4) Feature Optimization for Flashback Data Archive History Tables Before Release 11.2.0.4, when creating or altering a Flashback Data Archive, you could not disable optimization for the corresponding history tables. As of Release 11.2.0.4, when creating or altering a Flashback Data Archive, you can either enable or disable optimization for the corresponding history tables by using the OPTIMIZE DATA clause of the CREATE FLASHBACK ARCHIVE or ALTER FLASHBACK ARCHIVE statement. For more information, see "Creating a Flashback Data Archive" on page 12-17 and "General Guidelines for Oracle Flashback Technology" on page 12-23. Oracle Database 11g Release 2 (11.2.0.2) Feature Edition Attribute of Database Service Before Release 11.2.0.2, you could not specify your initial session edition when using a database service to connect to Oracle Database. If you wanted to use Edition-Based Redefinition for hot rollover, where some database clients use the pre-upgrade edition while others use the post-upgrade edition, then you had to change the client code. As of Release 11.2.0.2, you can specify the initial session edition as an attribute of a database service, which makes it easier to ensure that each session uses the desired edition during hot rollover. For more information, see "Your Initial Session Edition" on page 19-10. As of Release 11.2.0.2, each *_SERVICES static data dictionary view has an EDITION column that shows the default initial session edition. For more information, see "Displaying Information About Editions, Editioning Views, and Crossedition Triggers" on page 19-26. xxix Oracle Database 11g Release 2 Features The Oracle Database features for Oracle Database 11g Release 2 are: ■ Flashback Transaction Foreign Key Dependency Tracking ■ Fine-Grained Invalidation for Triggers ■ Edition-Based Redefinition ■ APPLYING_CROSSEDITION_TRIGGER Function ■ IGNORE_ROW_ON_DUPKEY_INDEX Hint ■ CHANGE_DUPKEY_ERROR_INDEX Hint ■ DBMS_PARALLEL_EXECUTE Package ■ Internet Protocol version 6 (IPv6) Support Flashback Transaction Foreign Key Dependency Tracking Flashback Transaction (the DBMS_FLASHBACK.TRANSACTION_BACKOUT procedure) with the CASCADE option rolls back a transaction and its dependent transactions while the database remains online. Before Oracle Database 11g Release 2, Flashback Transaction did not track foreign key dependencies. Therefore, if you tried to use Flashback Transaction with the CASCADE option to roll back a transaction that had foreign key dependencies, you could get a foreign key violation error. The workaround was to include the foreign-key-dependent transactions in the list of transactions to roll back. As of Oracle Database 11g Release 2, when using Flashback Transaction with the CASCADE option, you do not have to include any dependent transactions in the list of transactions to be rolled back. Foreign key dependency tracking for Flashback Transaction requires that you enable foreign key supplemental logging. For instructions, see "Configuring Your Database for Flashback Transaction" on page 12-4. For information about Flashback Transaction, see "Using Flashback Transaction" on page 12-13. Fine-Grained Invalidation for Triggers The Oracle Database 11g Release 1 feature "Fine-Grained Invalidation" on page xxxvii has been extended to triggers. Edition-Based Redefinition Edition-based redefinition enables you to upgrade the database component of an application while it is in use, thereby minimizing or eliminating down time. To upgrade an application while it is in use, you copy the database objects that comprise the application and redefine the copied objects in isolation. Your changes do not affect users of the application—they continue to run the unchanged application. When you are sure that your changes are correct, you make the upgraded application available to all users. Using edition-based redefinition means using one or more of its component features. The features you use, and the down time, depend on these factors: xxx ■ What kind of database objects you redefine ■ How available the database objects must be to users while you are redefining them ■ Whether you make the upgraded application available to some users while others continue to use the older version of the application You always use the edition feature to copy the database objects and redefine the copied objects in isolation. If you change the structure of one or more tables, you also use the feature editioning views. If other users must be able to change data in the tables while you are changing their structure, you also use forward crossedition triggers. If the pre- and post-upgrade applications will be in ordinary use at the same time (hot rollover), you also use reverse crossedition triggers. Crossedition triggers are not a permanent part of the application—you drop them when all users are using the post-upgrade application. For more information, see Chapter 19, "Edition-Based Redefinition." APPLYING_CROSSEDITION_TRIGGER Function The body of a forward crossedition trigger must handle data transformation collisions. If your collision-handling strategy depends on why the trigger is running, you can determine the reason with the function APPLYING_CROSSEDITION_TRIGGER, which is defined in the package DBMS_STANDARD. For more information, see "Handling Data Transformation Collisions" on page 19-22. IGNORE_ROW_ON_DUPKEY_INDEX Hint When a statement of the form INSERT INTO target subquery runs, a unique key for some rows to be inserted might collide with existing rows. Suppose that your application must ignore such collisions and insert the rows that do not collide with existing rows. Before Oracle Database 11g Release 2, you had to write a PL/SQL program which, in a block with a NULL handler for the DUP_VAL_ON_INDEX exception, selected the source rows and then inserted them, one at a time, into the target. As of Oracle Database 11g Release 2, you do not have to write a PL/SQL program. You can use the IGNORE_ROW_ON_DUPKEY_INDEX hint in an INSERT statement, which is easier to write and runs much faster. This hint is especially helpful when implementing crossedition triggers. For more information, see "Handling Data Transformation Collisions" on page 19-22. CHANGE_DUPKEY_ERROR_INDEX Hint When an INSERT or UPDATE statement runs, a unique key might collide with existing rows. Before Oracle Database 11g Release 2, the collision caused error ORA-00001. You could tell that a collision had occurred, but you could not tell where. As of Oracle Database 11g Release 2, you can use the CHANGE_DUPKEY_ERROR_INDEX hint in an INSERT or UPDATE statement, specifying that when a unique key violation occurs for a specified index or set of columns, ORA-38911 is reported instead of ORA-00001. This hint is especially helpful when implementing crossedition triggers. For more information, see "Handling Data Transformation Collisions" on page 19-22. DBMS_PARALLEL_EXECUTE Package The DBMS_PARALLEL_EXECUTE package enables you to incrementally update the data in a large table in parallel, in two high-level steps: xxxi 1. Group sets of rows in the table into smaller chunks. 2. Apply the desired UPDATE statement to the chunks in parallel, committing each time you have finished processing a chunk. This technique improves performance, reduces rollback space consumption, and reduces the number of row locks held. The DBMS_PARALLEL_EXECUTE package is recommended whenever you are updating a lot of data; for example, when you are applying forward crossedition triggers. For more information, see "Transforming Data from Pre- to Post-Upgrade Representation" on page 19-24. Internet Protocol version 6 (IPv6) Support Internet Protocol version 6 (IPv6) supports a much larger address space than IPv4 does. An IPv6 address has 128 bits, while an IPv4 address has only 32 bits. Applications that use network addresses might need small changes, and recompilation, to accommodate IPv6 addresses. For more information, see "Performing Network Operations in PL/SQL Subprograms" on page 9-26. The agent control utility, agtctl, which starts a multithreaded extproc agent, now accepts IPv6 addresses. For more information, see "Configuration Parameters for Multithreaded extproc Agent Control" on page A-8. See Also: Oracle Database Net Services Administrator's Guide for detailed information about IPv6 support in Oracle Database Oracle Database 11g Release 1 Features The application development features for Oracle Database 11g Release 1 are: ■ WAIT Option for Data Definition Language (DDL) Statements ■ Binary XML Support for Oracle XML Database ■ Metadata for SQL Operators and Functions ■ Enhancements to Regular Expression SQL Functions ■ Invisible Indexes ■ PL/SQL Function Result Cache ■ Sequences in PL/SQL Expressions ■ PL/Scope ■ PL/SQL Hierarchical Profiler ■ Query Result Change Notification ■ Flashback Transaction ■ Flashback Data Archive (Oracle Total Recall) ■ XA API Available Within PL/SQL ■ xxxii Support for XA/JTA in Oracle Real Application Clusters (Oracle RAC) Environment ■ Identity Code Package ■ Enhanced Online Index Creation and Rebuilding ■ Embedded PL/SQL Gateway ■ Oracle Database Spawns Multithreaded extproc Agent Directly by Default ■ Fine-Grained Invalidation WAIT Option for Data Definition Language (DDL) Statements DDL statements require exclusive locks on internal structures. If these locks are unavailable when a DDL statement is issued, the DDL statement fails, though it might have succeeded if it had been issued subseconds later. The WAIT option of the SQL statement LOCK TABLE enables a DDL statement to wait for its locks for a specified period before failing. For more information, see "Choosing a Locking Strategy" on page 2-12. Binary XML Support for Oracle XML Database Binary XML is a third way to represent an XML document. Binary XML complements, rather than replaces, the existing object-relational storage and CLOB storage representations. Binary XML has two significant benefits: ■ ■ XML operations can be significantly optimized, with or without an XML schema is available. The internal representation of XML is the same on disk, in memory, and on wire. As with other storage mechanisms, the details of binary XML storage are transparent to you. You continue to use XMLType and its associated methods and operators. For more information, see "Representing XML Data" on page 1-18. See Also: Oracle XML DB Developer's Guide Metadata for SQL Operators and Functions Metadata for SQL operators and functions is accessible through dynamic performance (V$) views. Third-party tools can leverage SQL functions without maintaining their metadata in the application layer. For more information, see "Metadata for SQL Operators and Functions" on page 1-27. Enhancements to Regular Expression SQL Functions The regular expression SQL functions REGEXP_INSTR and REGEXP_SUBSTR have increased functionality. A new regular expression SQL function, REGEXP_COUNT, returns the number of times a pattern appears in a string. These functions act the same in SQL and PL/SQL. For more information, see "Oracle SQL Support for Regular Expressions" on page 3-2. See Also: Oracle Database SQL Language Reference Invisible Indexes An invisible index is maintained by Oracle Database for every data manipulation language (DML) statement, but is ignored by the optimizer unless you explicitly set the parameter OPTIMIZER_USE_INVISIBLE_INDEXES to TRUE on a session or system level. Making an index invisible is an alternative to making it unusable or dropping it. Using invisible indexes, you can: ■ Test the removal of an index before dropping it xxxiii ■ Create invisible indexes temporarily for specialized, nonstandard operations, such as online application upgrades, without affecting the behavior of existing applications For more information, see Oracle Database Administrator's Guide. PL/SQL Function Result Cache Before Oracle Database 11g Release 1, if you wanted your PL/SQL application to cache the results of a function, you had to design and code the cache and cache-management subprograms. If multiple sessions ran your application, each session had to have its own copy of the cache and cache-management subprograms. Sometimes each session had to perform the same expensive computations. As of Oracle Database 11g Release 1, PL/SQL provides a function result cache. Because the function result cache is stored in a shared global area (SGA), it is available to any session that runs your application. For more information, see "PL/SQL Function Result Cache" on page 6-9. See Also: Oracle Database PL/SQL Language Reference Sequences in PL/SQL Expressions The pseudocolumns CURRVAL and NEXTVAL make writing PL/SQL source code easier for you and improve runtime performance and scalability. You can use sequence_ name.CURRVAL and sequence_name.NEXTVAL wherever you can use a NUMBER expression. See Example 6–6 on page 6-10. See Also: Oracle Database PL/SQL Language Reference PL/Scope PL/Scope is a compiler-driven tool that collects and organizes data about user-defined identifiers from PL/SQL source code. Because PL/Scope is a compiler-driven tool, you use it through interactive development environments (such as SQL Developer and JDeveloper), rather than directly. PL/Scope enables the development of powerful and effective PL/Scope source code browsers that increase PL/SQL developer productivity by minimizing time spent browsing and understanding source code. For a detailed description of PL/Scope, see Chapter 7, "Using PL/Scope." PL/SQL Hierarchical Profiler Nonhierarchical (flat) profilers record the time that a program spends within each subprogram—the function time or self time of each subprogram. Function time is helpful, but often inadequate. For example, it is helpful to know that a program spends 40% of its time in the subprogram INSERT_ORDER, but it is more helpful to know which subprograms call INSERT_ORDER often and the total time the program spends under INSERT_ORDER (including its descendent subprograms). Hierarchical profilers provide such information. The PL/SQL hierarchical profiler does this: ■ xxxiv Reports the dynamic execution profile of your PL/SQL program, organized by subprogram calls ■ Accounts for SQL and PL/SQL execution times separately ■ Requires no special source or compile-time preparation ■ Stores results in database tables (hierarchical profiler tables) for custom report generation by integrated development environment (IDE) tools (such as SQL Developer and third-party tools) To generate simple HTML reports from raw profiler output, you can use the plshprof command-line utility. Each subprogram-level summary in the dynamic execution profile includes information such as: ■ Number of calls to the subprogram ■ Time spent in the subprogram itself (function time or self time) ■ ■ Time spent in the subprogram itself and in its descendent subprograms (subtree time) Detailed parent-children information, for example: – All callers of a given subprogram (parents) – All subprograms that a given subprogram called (children) – How much time was spent in subprogram x when called from y – How many calls to subprogram x were from y You can browse the generated HTML reports in any browser. The browser's navigational capabilities, combined with well chosen links, provide a powerful way to analyze performance of large applications, improve application performance, and lower development costs. For a detailed description of PL/SQL hierarchical profiler, see Chapter 8, "Using the PL/SQL Hierarchical Profiler." Query Result Change Notification Before Oracle Database 11g Release 1, Continuous Query Notification (CQN) published only object change notifications, which result from DML or DDL changes to the objects associated with registered the queries. As of Oracle Database 11g Release 1, CQN can also publish query result change notifications, which result from DML or DDL changes to the result set associated with the registered queries. New static data dictionary views enable you to see which queries are registered for result-set-change notifications (see "Querying CQN Registrations" on page 11-24). For more information, see Chapter 11, "Using Continuous Query Notification (CQN)." Flashback Transaction The DBMS_FLASHBACK.TRANSACTION_BACKOUT procedure rolls back a transaction and its dependent transactions while the database remains online. This recovery operation uses undo data to create and run the compensating transactions that return the affected data to its original state. For more information, see "Using Flashback Transaction" on page 12-13. Flashback Data Archive (Oracle Total Recall) A Flashback Data Archive provides the ability to store and track transactional changes to a record over its lifetime. It is no longer necessary to build this intelligence into the application. A Flashback Data Archive is useful for compliance with record stage policies and audit reports. xxxv For more information, see "Using Flashback Data Archive (Oracle Total Recall)" on page 12-16. XA API Available Within PL/SQL The XA interface functionality that supports transactions involving multiple resource managers, such as databases and queues, is now available within PL/SQL. You can use PL/SQL to switch and share transactions across SQL*Plus sessions and across processes. For more information, see "Using the DBMS_XA Package" on page 15-16. Support for XA/JTA in Oracle Real Application Clusters (Oracle RAC) Environment An XA transaction now spans Oracle RAC instances by default, enabling any application that uses XA to take full advantage of the Oracle RAC environment, enhancing the availability and scalability of the application. For more information, see "Using Oracle XA with Oracle Real Application Clusters (Oracle RAC)" on page 15-22. Identity Code Package The Identity Code Package provides tools to store, retrieve, encode, decode, and translate between various product or identity codes, including Electronic Product Code (EPC), in Oracle Database. The Identity Code Package provides new data types, metadata tables and views, and PL/SQL packages for storing EPC standard RFID tags or new types of RFID tags in a user table. The Identity Code Package enables Oracle Database to recognize EPC coding schemes, to support efficient storage and component-level retrieval of EPC data, and to meet the EPCglobal Tag Data Translation 1.0 (TDT) standard that defines how to decode, encode, and translate between various EPC RFID tag representations. The Identity Code Package also provides an extensible framework that enables you to use pre-existing coding schemes with applications that are not included in the EPC standard and adapt Oracle Database both to these older systems and to evolving identity codes that might become part of a future EPC standard. The Identity Code Package also lets you create your own identity codes by first registering the new encoding category, registering the new encoding type, and then registering the new components associated with each new encoding type. For more information, see Chapter 17, "Using the Identity Code Package." Enhanced Online Index Creation and Rebuilding Online index creation and rebuilding no longer requires a DML-blocking lock. Before Oracle Database 11g Release 1, online index creation and rebuilding required a very short-term DML-blocking lock at the end of the rebuilding. The DML-blocking lock could cause a spike in the number of waiting DML operations, and therefore a short drop and spike of system usage. This system usage anomaly could trigger operating system alarm levels. Embedded PL/SQL Gateway The PL/SQL gateway enables a user-written PL/SQL subprogram to be invoked in response to a URL with parameters derived from an HTTP request. mod_plsql is a form of the gateway that exists as a plug-in to the Oracle HTTP Server. Now the PL/SQL gateway is also embedded in the database itself. The embedded PL/SQL xxxvi gateway uses the internal Oracle XML Database Listener and does not depend on the Oracle HTTP Server. You configure the embedded version of the gateway with the DBMS_EPG package. For more information, see "Using Embedded PL/SQL Gateway" on page 9-4. Oracle Database Spawns Multithreaded extproc Agent Directly by Default When an application calls an external C procedure, either Oracle Database or Oracle Listener starts the external procedure agent, extproc. Before Oracle Database 11g Release 1, Oracle Listener spawned the multithreaded extproc agent, and you defined environment variables for extproc in the file listener.ora. As of Oracle Database 11g Release 1, by default, Oracle Database spawns extproc directly, eliminating the risk that Oracle Listener might spawn extproc unexpectedly. This default configuration is recommended for maximum security. If you use it, you define environment variables for extproc in the file extproc.ora. For more information, including situations in which you cannot use the default configuration, see "Loading External Procedures" on page 14-3. Fine-Grained Invalidation Before Oracle Database 11g Release 1, a DDL statement that changed a referenced object invalidated all of its dependents. As of Oracle Database 11g Release 1, a DDL statement that changes a referenced object invalidates only the dependents for which either of these statements is true: ■ ■ The dependent relies on the attribute of the referenced object that the DDL statement changed. The compiled metadata of the dependent is no longer correct for the changed referenced object. For example, if view v selects columns c1 and c2 from table t, a DDL statement that changes only column c3 of t does not invalidate v. For more information, see "Invalidation of Dependent Objects" on page 18-4. xxxvii xxxviii Part I Part I SQL for Application Developers This part presents information that application developers need about Structured Query Language (SQL), which is used to manage information in an Oracle Database. Chapters: ■ Chapter 2, "SQL Processing for Application Developers" ■ Chapter 1, "Using SQL Data Types in Database Applications" ■ Chapter 3, "Using Regular Expressions in Database Applications" ■ Chapter 4, "Using Indexes in Database Applications" ■ Chapter 5, "Maintaining Data Integrity in Database Applications" See Also: Oracle Database SQL Language Reference for a complete description of SQL 1 Using SQL Data Types in Database Applications 1 This chapter explains how to use SQL data types in database applications. Topics: ■ Overview of SQL Data Types ■ Representing Character Data ■ Representing Numeric Data ■ Representing Date and Time Data ■ Representing Specialized Data ■ Representing Conditional Expressions as Data ■ Identifying Rows by Address ■ How Oracle Database Converts Data Types ■ Metadata for SQL Operators and Functions See Also: ■ ■ ■ Oracle Database PL/SQL Language Reference for information about PL/SQL data types Oracle Database PL/SQL Language Reference for introductory information about Abstract Data Types (ADTs) Oracle Database Object-Relational Developer's Guide for advanced information about ADTs An ADT consists of a data structure and subprograms that manipulate the data. In the static data dictionary view *_OBJECTS, the OBJECT_TYPE of an ADE is TYPE. In the static data dictionary view *_TYPES, the TYPECODE of an ADE is OBJECT. Overview of SQL Data Types A data type associates fixed properties with the values that can be inserted in table columns or passed as parameters to subprograms. These properties cause Oracle Database to treat values of different data types differently. For example, Oracle Database can add values of NUMBER data type, but cannot add values of RAW data type. Oracle Database provides many data types and several categories for user-defined types that can be used as data types. Using SQL Data Types in Database Applications 1-1 Representing Character Data The Oracle precompilers recognize other data types in embedded SQL programs. These data types are called external data types and are associated with host variables. Do not confuse external data types with Oracle built-in, Oracle-supplied, and user-defined data types. See Also: ■ ■ Oracle Database SQL Language Reference for complete information about SQL data types Oracle Database Concepts for additional introductory information about SQL data types (which it calls Oracle data types) Representing Character Data Table 1–1 summarizes the SQL data types that store alphanumeric data. Table 1–1 SQL Character Data Types Data Types Values Stored CHAR Fixed-length character literals NCHAR Fixed-length Unicode character literals VARCHAR2 Variable-length character literals NVARCHAR2 Variable-length Unicode character literals CLOB Single-byte and multibyte character strings of up to (4 gigabytes - 1) * (the value obtained from DBMS_LOB.GETCHUNKSIZE) NCLOB Single-byte and multibyte Unicode character strings of up to (4 gigabytes - 1) * (the value obtained from DBMS_LOB.GETCHUNKSIZE) LONG Variable-length character data of up to 2 gigabytes - 1. Provided only for backward compatibility. For a client/server application, if the character set on the client side differs from the character set on the server side, then Oracle Database automatically converts CHAR, VARCHAR2, and LONG data from the database character set (determined by the NLS_ LANGUAGE parameter) to the character set defined for the user session. Topics: ■ Specifying Column Lengths as Bytes or Characters ■ Choosing Between CHAR and VARCHAR2 Data Types See Also: ■ ■ ■ Oracle Database SQL Language Reference for more information about CHAR, VARCHAR2, NCHAR, and NVARCHAR2 data types "Large Objects (LOBs)" on page 1-17 for more information about CLOB and NCLOB data types "LONG and LONG RAW Data Types" on page 1-17 for more information about LONG data type Specifying Column Lengths as Bytes or Characters You can specify the lengths of CHAR and VARCHAR2 columns as either bytes or characters. The lengths of NCHAR and NVARCHAR2 columns are always specified in 1-2 Oracle Database Advanced Application Developer's Guide Representing Character Data characters, making them ideal for storing Unicode character literals, where a character might consist of multiple bytes. This table shows some column length specifications and their meanings: Column Length Specification Meaning id VARCHAR2(32 BYTE) The id column contains up to 32 single-byte characters. name VARCHAR2(32 CHAR) The name column contains up to 32 characters of the database character set. If the database character set includes multibyte characters, then the 32 characters can occupy more than 32 bytes. biography NVARCHAR2(2000) The biography column contains up to 2000 characters of any Unicode-representable language. The encoding depends on the national character set. The column can contain multibyte values even if the database character set is single-byte. comment VARCHAR2(2000) The comment column contains up to 2000 bytes or characters, depending on the value of the initialization parameter NLS_LENGTH_ SEMANTICS. When using a multibyte database character encoding scheme, consider carefully the space required for tables with character columns. If the database character encoding scheme is single-byte, then the number of bytes and the number of characters in a column is the same. If it is multibyte, however, then generally there is no such correspondence. A character might consist of one or more bytes, depending on the specific multibyte encoding scheme and whether shift-in/shift-out control codes are present. To avoid overflowing buffers, specify data as NCHAR or NVARCHAR2 if it might use a Unicode encoding that is different from the database character set. See Also: ■ ■ Oracle Database Globalization Support Guide for more information about SQL data types NCHAR and NVARCHAR2 Oracle Database SQL Language Reference for more information about SQL data types NCHAR and NVARCHAR2 Choosing Between CHAR and VARCHAR2 Data Types When choosing a data type for a column that stores alphanumeric data in a table, consider: ■ Space usage Oracle Database blank-pads values stored in CHAR columns but not values stored in VARCHAR2 columns. Therefore, VARCHAR2 columns use space more efficiently than CHAR columns. ■ Performance Because of the blank-padding difference, a full table scan on a large table containing VARCHAR2 columns might read fewer data blocks than a full table scan on a table containing the same data stored in CHAR columns. If your application often performs full table scans on large tables containing character data, then you Using SQL Data Types in Database Applications 1-3 Representing Numeric Data might be able to improve performance by storing data in VARCHAR2 columns rather than in CHAR columns. ■ Comparison semantics When you need ANSI compatibility in comparison semantics, use the CHAR data type. When trailing blanks are important in string comparisons, use the VARCHAR2 data type. See Also: Oracle Database SQL Language Reference for more information about comparison semantics for these data types ■ Future compatibility The CHAR and VARCHAR2 data types are fully supported. Today, the VARCHAR data type automatically corresponds to the VARCHAR2 data type and is reserved for future use. Representing Numeric Data The SQL data types that store numeric data are NUMBER, BINARY_FLOAT, and BINARY_ DOUBLE. The NUMBER data type stores real numbers in either a fixed-point or floating-point format. NUMBER offers up to 38 decimal digits of precision. In a NUMBER column, you can store positive and negative numbers of magnitude 1 x 10-130 through 9.99 x10125, and 0. All Oracle Database platforms support NUMBER values. The BINARY_FLOAT and BINARY_DOUBLE data types store floating-point numbers in the single-precision (32-bit) IEEE 754 format and the double-precision (64-bit) IEEE 754 format, respectively. High-precision values use less space when stored as BINARY_ FLOAT and BINARY_DOUBLE than when stored as NUMBER. Arithmetic operations on floating-point numbers are usually faster for BINARY_FLOAT and BINARY_DOUBLE values than for NUMBER values. In client interfaces that Oracle Database supports, arithmetic operations on BINARY_ FLOAT and BINARY_DOUBLE values are performed by the native instruction set that the hardware vendor supplies. The term native floating-point data type includes BINARY_ FLOAT and BINARY_DOUBLE data types and all implementations of these types in supported client interfaces. Native floating-point data types conform substantially with the Institute of Electrical and Electronics Engineers (IEEE) Standard for Binary Floating-Point Arithmetic, IEEE Standard 754-1985 (IEEE754). For details, see Oracle Database SQL Language Reference. Topics: ■ Floating-Point Number Components ■ Floating-Point Number Formats ■ Comparison Operators for Native Floating-Point Data Types ■ Arithmetic Operations with Native Floating-Point Data Types ■ Conversion Functions for Floating-Point Data Types ■ Client Interfaces for Native Floating-Point Data Types 1-4 Oracle Database Advanced Application Developer's Guide Representing Numeric Data See Also: ■ ■ Oracle Database SQL Language Reference for more information about the NUMBER data type Oracle Database SQL Language Reference for more information about the BINARY_FLOAT and BINARY_DOUBLE data types Floating-Point Number Components A floating-point number has these components: ■ Binary-valued sign ■ Signed exponent ■ Significand ■ Base The formula for a floating-point value is: (-1)sign.significand.baseexponent For example, the floating-point value 4.31 is represented: (-1)0.431.10-2 The components of the preceding representation are: Component Name Component Value Sign 0 Significand 431 Base 10 Exponent -2 Floating-Point Number Formats A floating-point number format specifies how the components of a floating-point number are represented, thereby determining the range and precision of the values that the format can represent. The range is the interval bounded by the smallest and largest values and the precision is the number of significant digits. Both range and precision are finite. If a floating-point number is too precise for a given format, then the number is rounded. How the number is rounded depends on the base of its format, which can be either decimal or binary. A number stored in decimal format is rounded to the nearest decimal place (for example, 1000, 10, or 0.01). A number stored in binary format is rounded to the nearest binary place (for example, 1024, 512, or 1/64). NUMBER values are stored in decimal format. For calculations that need decimal rounding, use the NUMBER data type. Native floating-point values are stored in binary format. Topics: ■ Binary Floating-Point Formats ■ Special Values for Native Floating-Point Formats Using SQL Data Types in Database Applications 1-5 Representing Numeric Data Binary Floating-Point Formats This formula determines the value of a floating-point number that uses a binary format: (-1)sign 2E (bit0 bit1 bit2 ... bitp-1) Table 1–2 describes the components of the preceding formula. Table 1–2 Binary Floating-Point Format Components Component Component Value sign 0 or 1 E (exponent) For single-precision (32-bit) data type, an integer from -126 through 127. For double-precision (64-bit) data type, an integer from -1022 through 1023. 0 or 1. (The bit sequence represents a number in base 2.) biti p (precision) For single-precision data type, 24. For double-precision data type, 53. The leading bit of the significand, b0, must be set (1), except for subnormal numbers (explained later). Therefore, the leading bit is not actually stored, and a binary format provides n bits of precision while storing only n-1 bits. The IEEE 754 standard defines the in-memory formats for single-precision and double-precision data types, which Table 1–3 shows. Table 1–3 Summary of Binary Format Storage Parameters Data Type Sign Bit Exponent Bits Significand Bits Total Bits Single-precision 1 8 24 (23 stored) 32 Double-precision 1 11 53 (52 stored) 64 Oracle Database does not support the extended single- and double-precision formats that the IEEE 754 standard defines. Note: A significand whose leading bit is set is called normalized. The IEEE 754 standard defines subnormal numbers (also called denormal numbers) that are too small to represent with normalized significands. If the significand of a subnormal number were normalized, then its exponent would be too large. Subnormal numbers preserve this property: If x-y==0.0 (using floating-point subtraction), then x==y. IEEE 754 formats support subnormal values. Table 1–4 shows the range and precision of the IEEE 754 single- and double-precision formats and Oracle Database NUMBER. Range limits are expressed as positive numbers, but they also apply to absolute values of negative numbers. (The notation "number e exponent" means number * 10exponent.) Table 1–4 Range and Precision of Floating-Point Data Types Range and Precision Single-precision 32-bit1 Double-precision 64-bit1 Oracle Database NUMBER Data Type Maximum positive normal number 3.40282347e+38 1.7976931348623157e+308 < 1.0e126 1-6 Oracle Database Advanced Application Developer's Guide Representing Numeric Data Table 1–4 (Cont.) Range and Precision of Floating-Point Data Types Range and Precision Single-precision 32-bit1 Double-precision 64-bit1 Oracle Database NUMBER Data Type Minimum positive normal number 1.17549435e-38 2.2250738585072014e-308 1.0e-130 Maximum positive subnormal number 1.17549421e-38 2.2250738585072009e-308 not applicable Minimum positive subnormal number 1.40129846e-45 4.9406564584124654e-324 not applicable Precision (decimal digits) 6-9 15 - 17 38 - 40 1 These numbers are from the IEEE Numerical Computation Guide. See Also: ■ ■ ■ Oracle Database SQL Language Reference for information about literal representation of numeric values Oracle Database SQL Language Reference for more information about floating-point formats Oracle Database SQL Language Reference for information about floating-point conditions Special Values for Native Floating-Point Formats The IEEE 754 standard supports the special values shown in Table 1–5. Table 1–5 Special Values for Native Floating-Point Formats Value Meaning +INF Positive infinity -INF Negative infinity NaN Not a number +0 Positive zero -0 Negative zero Each value in Table 1–5 is represented by a specific bit pattern, except NaN. NaN, the result of any undefined operation, is represented by many bit patterns. Some of these bits patterns have the sign bit set and some do not, but the sign bit has no meaning. The IEEE 754 standard distinguishes between quiet NaNs (which do not raise additional exceptions as they propagate through most operations) and signaling NaNs (which do). The IEEE 754 standard specifies action for when exceptions are enabled and action for when they are disabled. In Oracle Database, exceptions cannot be enabled. Oracle Database acts as the IEEE 754 standard specifies for when exceptions are disabled. In particular, Oracle Database does not distinguish between quiet and signaling NaNs. You can use Oracle Call Interface (OCI) to retrieve NaN values from Oracle Database, but whether a retrieved NaN value is signaling or quiet depends on the client platform and is beyond the control of Oracle Database. The IEEE 754 standard defines these classes of special values: Using SQL Data Types in Database Applications 1-7 Representing Numeric Data ■ Zero ■ Subnormal ■ Normal ■ Infinity ■ NaN The values in each class in the preceding list are larger than the values in the classes that precede it in the list (ignoring signs), except NaN. NaN is unordered with other classes of special values and with itself. In Oracle Database: ■ All NaNs are quiet. ■ Any non-NaN value < NaN ■ Any NaN == any other NaN ■ All NaNs are converted to the same bit pattern. ■ -0 is converted to +0. ■ IEEE 754 exceptions are not raised. See Also: Oracle Database SQL Language Reference for information about floating-point conditions, which let you determine whether an expression is infinite or is the undefined result of an operation (is not a number or NaN). Comparison Operators for Native Floating-Point Data Types Oracle Database defines these comparison operators for native floating-point data types: ■ Equal to ■ Not equal to ■ Greater than ■ Greater than or equal to ■ Less than ■ Less than or equal to ■ Unordered Comparisons ignore the sign of zero (-0 equals +0). See Also: "Special Values for Native Floating-Point Formats" on page 1-7 for more information about comparison results, ordering, and other actions of special values Arithmetic Operations with Native Floating-Point Data Types Oracle Database defines these arithmetic operators for native floating-point data types: ■ Multiplication ■ Division ■ Addition 1-8 Oracle Database Advanced Application Developer's Guide Representing Numeric Data ■ Subtraction ■ Remainder ■ Square root You can define the mode used to round the result of the operation. Exceptions can be raised when operations are performed. Exceptions can also be disabled. Formerly, Java required floating-point arithmetic to be exactly reproducible. IEEE 754 does not have this requirement. Therefore, results of operations (including arithmetic operations) can be delivered to a destination that uses a range greater than the range that the operands of the operation use. You can compute the result of a double-precision multiplication at an extended double-precision destination, but the result must be rounded as if the destination were single-precision or double-precision. The range of the result (that is, the number of bits used for the exponent) can use the range supported by the wider (extended double-precision) destination; however, this might cause a double-rounding error in which the least significant bit of the result is incorrect. This situation can occur only for double-precision multiplication and division on hardware that implements the IA-32 and IA-64 instruction set architecture. Therefore, except for this case, arithmetic for these data types is reproducible across platforms. When the result of a computation is NaN, all platforms produce a value for which IS NAN is true. However, all platforms do not have to use the same bit pattern. Conversion Functions for Floating-Point Data Types Oracle Database defines functions that convert between floating-point and other data types, including string formats that use decimal precision (but precision might be lost during the conversion). For example: ■ TO_BINARY_DOUBLE, described in Oracle Database SQL Language Reference ■ TO_BINARY_FLOAT, described in Oracle Database SQL Language Reference ■ TO_CHAR, described in Oracle Database SQL Language Reference ■ TO_NUMBER, described in Oracle Database SQL Language Reference Oracle Database can raise exceptions during conversion. The IEEE 754 standard defines these exceptions: ■ Invalid ■ Inexact ■ Divide by zero ■ Underflow ■ Overflow Oracle Database does not raise these exceptions for native floating-point data types. Generally, operations that raise exceptions produce the values described in Table 1–6. Table 1–6 Values Resulting from Exceptions Exception Value Underflow 0 Overflow -INF, +INF Invalid Operation NaN Using SQL Data Types in Database Applications 1-9 Representing Date and Time Data Table 1–6 (Cont.) Values Resulting from Exceptions Exception Value Divide by Zero -INF, +INF, NaN Inexact Any value – rounding was performed Client Interfaces for Native Floating-Point Data Types Oracle Database supports native floating-point data types in these client interfaces: ■ SQL ■ PL/SQL ■ Oracle Call Interface (OCI) ■ Oracle C++ Call Interface (OCCI) ■ Pro*C/C++ ■ JDBC Topics: ■ OCI Native Floating-Point Data Types SQLT_BFLOAT and SQLT_BDOUBLE ■ Native Floating-Point Data Types Supported in ADTs ■ Pro*C/C++ Support for Native Floating-Point Data Types OCI Native Floating-Point Data Types SQLT_BFLOAT and SQLT_BDOUBLE The OCI API implements the IEEE 754 single- and double-precision native floating-point data types with the data types SQLT_BFLOAT and SQLT_BDOUBLE, respectively. Conversions between these types and the SQL types BINARY_FLOAT and BINARY_DOUBLE are exact on platforms that implement the IEEE 754 standard for the C data types FLOAT and DOUBLE. See Also: Oracle Call Interface Programmer's Guide Native Floating-Point Data Types Supported in ADTs Oracle Database supports the SQL data types BINARY_FLOAT and BINARY_DOUBLE as attributes of ADTs. Pro*C/C++ Support for Native Floating-Point Data Types Pro*C/C++ supports the native FLOAT and DOUBLE data types using the column data types BINARY_FLOAT and BINARY_DOUBLE. You can use these data types in the same way that Oracle Database NUMBER data type is used. You can bind FLOAT and DOUBLE to BINARY_FLOAT and BINARY_DOUBLE, respectively, by setting the Pro*C/C++ precompiler command line option NATIVE_TYPES to Y (yes) when you compile your application. Representing Date and Time Data Oracle Database stores date and time (datetime) data in its own internal format, in 7-byte fields that correspond to century, year, month, day, hour, minute, and second. Table 1–7 summarizes the SQL datetime data types. For more information about these data types, see Oracle Database SQL Language Reference. 1-10 Oracle Database Advanced Application Developer's Guide Representing Date and Time Data Table 1–7 SQL Datetime Data Types Date Type Usage DATE Use to store point-in-time (datetime) values in a table—for example, dates of jobs. TIMESTAMP Use to store datetime values that are precise to fractional seconds—for example, times of events that must be compared to determine the order in which they occurred. TIMESTAMP WITH TIME ZONE Use to store datetime values that must be gathered or coordinated across geographic regions. TIMESTAMP WITH LOCAL TIME ZONE Use to store datetime values when the time zone is insignificant—for example, in an application that schedules teleconferences, where participants each see the start and end times for their own time zone. Appropriate for two-tier applications in which you want to display dates and times that use the time zone of the client system. Usually inappropriate for three-tier applications, because data displayed in a web browser is formatted according to the time zone of the web server, not the time zone of the browser. The web server is the database client, so its local time is used. INTERVAL YEAR TO MONTH Use to store the difference between two datetime values, where only the year and month are significant—for example, to set a reminder for a date 18 months in the future, or check whether 6 months have elapsed since a particular date. INTERVAL DAY TO SECOND Use to store the precise difference between two datetime values—for example, to set a reminder for a time 36 hours in the future or to record the time between the start and end of a race. To represent long spans of time with high precision, use a large number of days. Topics: ■ Displaying Current Date and Time ■ Displaying and Inserting Dates in Nondefault Formats ■ Displaying and Inserting Times in Nondefault Formats ■ Arithmetic Operations with Datetime Data Types ■ Conversion Functions for Datetime Data Types ■ Importing, Exporting, and Comparing Datetime Types See Also: Oracle Call Interface Programmer's Guide for more information about Oracle Database internal date types Displaying Current Date and Time The simplest way to display the current date and time is: SELECT SYSDATE FROM DUAL The preceding command displays the current date and time in the default date format, which depends on the initialization parameter NLS_DATE_FORMAT. The standard Oracle Database default date format is DD-MON-RR. The RR datetime format element lets you store 20th century dates in the 21st century by specifying only the last two digits of the year. For example, in the datetime format DD-MON-YY, Using SQL Data Types in Database Applications 1-11 Representing Date and Time Data 13-NOV-54 refers to the year 1954 in a query issued between 1950 and 2049, but to the year 2054 in a query issued between 2050 and 2099. To display SYSDATE in a nondefault format, use the TO_CHAR function with a datetime format model. Example 1–1 uses TO_CHAR with a format model to display SYSDATE in a nondefault format, which includes the qualifier BC or AD. (By default, SYSDATE is displayed without this qualifier.) Example 1–1 Displaying Current Date and Time in Nondefault Format SELECT TO_CHAR(SYSDATE, 'DD-MON-YYYY BC') NOW FROM DUAL; Result: NOW ----------------------18-MAR-2009 AD 1 row selected. When testing code that uses SYSDATE, it can be helpful to set SYSDATE to a constant. Do this with the initialization parameter FIXED_ DATE, described in Oracle Database Reference. Tip: See Also: ■ ■ ■ ■ ■ Oracle Database SQL Language Reference for more information about SYSDATE Oracle Database Globalization Support Guide for information about NLS_DATE_FORMAT Oracle Database SQL Language Reference for more information about TO_CHAR Oracle Database SQL Language Reference for information about datetime format models Oracle Database SQL Language Reference for more information about the RR datetime format element Displaying and Inserting Dates in Nondefault Formats Although Oracle Database always stores dates in the default date format (set by the initialization parameter NLS_DATE_FORMAT), you can display and insert dates in nondefault formats by using the TO_CHAR and TO_DATE functions, respectively, with datetime format models. Example 1–2 creates a table with a DATE column and inserts into it a date specified in a nondefault format. The date is stored in the default format, as the first SELECT statement shows. The second SELECT statement displays the date in a nondefault format. Example 1–2 Inserting and Displaying Date in Nondefault Formats DROP TABLE dates; CREATE TABLE dates (d DATE); INSERT INTO dates VALUES (TO_DATE('OCT 27, 1998', 'MON DD, YYYY')); 1-12 Oracle Database Advanced Application Developer's Guide Representing Date and Time Data SELECT d FROM dates; Result: D --------27-OCT-98 1 row selected. SELECT TO_CHAR(d, 'YYYY-MON-DD') D FROM dates; Result: D -------------------1998-OCT-27 1 row selected. Be careful when using the YY datetime format element, which indicates the year in the current century. For example, in the 21st century, the format DD-MON-YY, 31-DEC-92 is December 31, 2092 (not December 31, 1992, as you might expect). To store 20th century dates in the 21st century by specifying only the last two digits of the year, use the RR datetime format element (the default). Caution: See Also: ■ ■ ■ ■ ■ Oracle Database Globalization Support Guide for information about NLS_DATE_FORMAT Oracle Database SQL Language Reference for more information about TO_CHAR Oracle Database SQL Language Reference for more information about TO_DATE Oracle Database SQL Language Reference for information about datetime format models Oracle Database SQL Language Reference for more information about the RR datetime format element Displaying and Inserting Times in Nondefault Formats Although Oracle Database always stores times in the 24-hour format HH24:MI:SS, you can display and insert times in nondefault formats by using the TO_CHAR and TO_DATE functions, respectively, with datetime format models. In a DATE column: ■ The default time is 12:00:00 A.M. (midnight). The default time applies to any value in the column that has no time portion, either because none was specified or because the value was truncated. ■ The default date is the first day of the current month. The default date applies to any value in the column that has no date portion, because none was specified. Using SQL Data Types in Database Applications 1-13 Representing Date and Time Data Example 1–3 creates a table with a DATE column and inserts into it three dates specified in nondefault formats—one with both date and time portions, one with no time portion, and one with no date portion. The first SELECT statement shows the current date. The second SELECT statement displays the three dates in a nondefault format that includes both date and time portions. Example 1–3 Inserting and Displaying Dates and Times in Nondefault Formats DROP TABLE birthdays; CREATE TABLE birthdays (name VARCHAR2(20), day DATE); INSERT INTO birthdays (name, day) VALUES ('Annie', TO_DATE('13-NOV-92 10:56 A.M.','DD-MON-RR HH:MI A.M.') ); INSERT INTO birthdays (name, day) VALUES ('Bobby', TO_DATE('5-APR-02','DD-MON-RR') ); INSERT INTO birthdays (name, day) VALUES ('Cindy', TO_DATE('8:25 P.M.','HH:MI A.M.') ); Display current date: SELECT SYSDATE FROM DUAL; Result: SYSDATE --------05-NOV-10 1 row selected. Display both date and time portions of stored datetime values: SELECT name, TO_CHAR(day, 'Mon DD, RRRR') DAY, TO_CHAR(day, 'HH:MI A.M.') TIME FROM birthdays; Result: NAME -------------------Annie Bobby Cindy DAY --------------------Nov 13, 1992 Apr 05, 2002 Nov 01, 2010 TIME ---------10:56 A.M. 12:00 A.M. 08:25 P.M. 3 rows selected. Arithmetic Operations with Datetime Data Types You can perform arithmetic operations on datetime values. The results of such operations are determined by the rules in Oracle Database SQL Language Reference. 1-14 Oracle Database Advanced Application Developer's Guide Representing Date and Time Data SQL has many datetime functions that you can use in datetime expressions. For example, the function ADD_MONTHS returns the date that is a specified number of months from a specified date. For the complete list of datetime functions, see Oracle Database SQL Language Reference. Conversion Functions for Datetime Data Types Table 1–8 summarizes the SQL functions that convert to or from datetime data types. Table 1–8 SQL Conversion Functions for Datetime Data Types Function Converts ... To ... NUMTODSINTERVAL NUMBER INTERVAL DAY TO SECOND NUMTOYMINTERVAL NUMBER INTERVAL DAY TO MONTH TO_CHAR DATE VARCHAR2 TIMESTAMP TIMESTAMP WITH TIME ZONE TIMESTAMP WITH LOCAL TIME ZONE INTERVAL DAY TO SECOND INTERVAL YEAR TO MONTH TO_DATE CHAR DATE VARCHAR2 NCHAR NVARCHAR2 TO_DSINTERVAL INTERVAL DAY TO SECOND CHAR VARCHAR2 NCHAR NVARCHAR2 TO_TIMESTAMP CHAR TIMESTAMP VARCHAR2 NCHAR NVARCHAR2 TO_TIMESTAMP_TZ TIMESTAMP WITH TIME ZONE CHAR VARCHAR2 NCHAR NVARCHAR2 TO_YMINTERVAL CHAR INTERVAL DAY TO MONTH VARCHAR2 NCHAR NVARCHAR2 Importing, Exporting, and Comparing Datetime Types You can import, export, and compare TIMESTAMP WITH TIME ZONE and TIMESTAMP WITH LOCAL TIME ZONE values without worrying about time zone offsets, because the database stores these values in normalized format. Using SQL Data Types in Database Applications 1-15 Representing Specialized Data When importing, exporting, and comparing DATE and TIMESTAMP values, you must adjust them to account for any time zone differences between source and target databases, because the database does not store their time zones. Representing Specialized Data Topics: ■ Representing Geographic Data ■ Representing Multimedia Data ■ Representing Large Amounts of Data ■ Representing Searchable Text ■ Representing XML Data ■ Representing Dynamically Typed Data ■ Representing ANSI, DB2, and SQL/DS Data Representing Geographic Data To represent Geographic Information System (GIS) or spatial data in the database, you can use Oracle Spatial features, including the type MDSYS.SDO_GEOMETRY. You can store the data in the database by using either an object-relational or a relational model. You can use a set of PL/SQL packages to query and manipulate the data. See Also: Oracle Spatial Developer's Guide for information about Oracle Spatial features Representing Multimedia Data Oracle Multimedia enables Oracle Database to store, manage, and retrieve images, audio, video, or other heterogeneous media data in an integrated fashion with other enterprise information. Oracle Multimedia extends Oracle Database reliability, availability, and data management to multimedia content in traditional, Internet, electronic commerce, and media-rich applications. Whether you store such multimedia data inside the database as BLOB or BFILE values, or store it externally on a web server or other kind of server, you can use Oracle Multimedia to access the data using either an object-relational or a relational model, and manipulate and query the data using a set of ADTs. Oracle Multimedia provides the ORDAudio, ORDDoc, ORDImage, ORDImageSignature, ORDVideo, and SI_StillImage ADTs (including methods) for these purposes: ■ ■ ■ Extracting metadata and attributes from multimedia data Retrieving and managing multimedia data from Oracle Multimedia, web servers, file systems, and other servers Performing manipulation operations on image data See Also: Oracle Multimedia Reference for information about Oracle Multimedia Representing Large Amounts of Data For representing large amounts of data, Oracle Database provides: 1-16 Oracle Database Advanced Application Developer's Guide Representing Specialized Data ■ Large Objects (LOBs) ■ LONG and LONG RAW Data Types (for backward compatibility) Large Objects (LOBs) Large Objects (LOBs) are data types that are designed to store large amounts of data (the maximum size of a LOB depends on how your database is configured). Storing data in LOBs enables you to access and manipulate the data efficiently in your application. Table 1–9 summarizes the LOBs. Table 1–9 Large Objects (LOBs) Data Type Description Binary large object BLOB Stores any kind of data in binary format. Typically used for multimedia data such as images, audio, and video. Character large object CLOB Stores string data in the database character set format. Used for large strings or documents that use the database character set exclusively. National character large object NCLOB Stores string data in National Character Set format. Used for large strings or documents in the National Character Set. External large object BFILE Stores a binary file outside the database in the host operating system file system. Applications have read-only access to BFILEs. Used for static data that applications do not manipulate, such as image data. Any kind of data (that is, any operating system file) can be stored in a BFILE. For example, you can store character data in a BFILE and then load the BFILE data into a CLOB, specifying the character set when loading. An instance of type BLOB, CLOB, or NCLOB can be either temporary (declared in the scope of your application) or persistent (created and stored in the database). See Also: ■ ■ Oracle Database SQL Language Reference for additional general information about LOBs Oracle Database SecureFiles and Large Objects Developer's Guide for information about using LOBs in application development LONG and LONG RAW Data Types Note: Oracle supports the LONG and LONG RAW data types for backward compatibility, but strongly recommends that you convert LONG columns to LOB columns and LONG RAW columns to BLOB columns. LONG columns store variable-length character strings containing up to 2 gigabytes - 1 bytes. LONG columns have many of the characteristics of VARCHAR2 columns. You can Using SQL Data Types in Database Applications 1-17 Representing Specialized Data use LONG columns to store long text strings. The length of LONG values may be limited by the memory available on your computer. For more information about the LONG data type, including its many restrictions, see Oracle Database SQL Language Reference. The LONG RAW (and RAW) data types store data that is not to be explicitly converted by Oracle Database when moving data between different systems. These data types are intended for binary data or byte strings. For example, you can use LONG RAW to store graphics, sound, documents, or arrays of binary data, for which the interpretation is dependent on the use. You can index RAW data, but not LONG RAW data. For more information about the RAW and LONG RAW data types, see Oracle Database SQL Language Reference. Representing Searchable Text Rather than writing low-level code to do full-text searches, you can use Oracle Text. Oracle Text stores the search data in a special kind of index and lets you query the data with operators and PL/SQL packages. This technology enables you to create your own search engine using data from tables, files, or URLs, and combine the search logic with relational queries. You can also search XML data this way with the XPath notation. See Also: Oracle Text Application Developer's Guide for more information about Oracle Text Representing XML Data If you have information stored as files in XML format, or want to store an ADT in XML format, then you can use the Oracle-supplied type XMLType. When you create an XMLType column in a table, you can store the XML data in any of these ways: ■ In a CLOB column ■ As binary XML (stored internally as a CLOB) ■ Object relationally XMLType has member functions that access, extract, and query the XML data using W3C XPath expressions (see Oracle XML DB Developer's Guide). Also, Oracle provides SQL XML functions that manipulate or return whole or partial XML documents (see Oracle Database SQL Language Reference) and these PL/SQL packages (described in Oracle Database PL/SQL Packages and Types Reference): ■ DBMS_XMLDOM, for accessing XMLType objects ■ DBMS_XMLGEN, for converting the results of a SQL query to a canonical XML format ■ DBMS_XMLINDEX, for implementing asynchronous indexing ■ DBMS_XMLPARSER, for accessing the contents and structure of XML documents ■ DBMS_XMLQUERY, for database-to-XMLType functionality ■ DBMS_XMLSAVE, for XML-to-database-type functionality ■ DBMS_XMLSCHEMA, for managing XML schemas ■ DBMS_XMLSTORE, for storing XML data in relational tables ■ DBMS_XMLTRANSLATIONS, for translating strings so that they can be searched or displayed in various languages 1-18 Oracle Database Advanced Application Developer's Guide Representing Specialized Data See Also: ■ ■ Oracle XML DB Developer's Guide for information about Oracle XML DB and how you can use it to store, generate, manipulate, manage, and query XML data in the database Oracle XML Developer's Kit Programmer's Guide for information about client-side programming with XML Representing Dynamically Typed Data Some languages allow data types to change at run time, and some let a program check the type of a variable. For example, C has the union keyword and the void * pointer, and Java has the typeof operator and wrapper types such as Number. In Oracle Database, you can create variables and columns that can hold data of any type and test their values to determine their underlying representation. For example, a single table column can have a numeric value in one row, a string value in another row, and an object in another row. You can use the Oracle-supplied ADT SYS.ANYDATA to represent values of any scalar type or ADT. SYS.ANYDATA has methods that accept scalar values of any type, and turn them back into scalars or objects. Similarly, you can use the Oracle-supplied ADT SYS.ANYDATASET to represent values of any collection type. For more information about these ADTs, see Oracle Database Object-Relational Developer's Guide. To check and manipulate type information, use the DBMS_TYPES package, as in Example 1–4. For more information about this package, see Oracle Database PL/SQL Packages and Types Reference. With OCI, use the OCIAnyData and OCIAnyDataSet interfaces, described in Oracle Call Interface Programmer's Guide. Example 1–4 Accessing Information in a SYS.ANYDATA Column CREATE OR REPLACE TYPE employee_type AS OBJECT (empno NUMBER, ename VARCHAR2(10)); / DROP TABLE mytab; CREATE TABLE mytab (id NUMBER, data SYS.ANYDATA); INSERT INTO mytab (id, data) VALUES (1, SYS.ANYDATA.ConvertNumber(5)); INSERT INTO mytab (id, data) VALUES (2, SYS.ANYDATA.ConvertObject(Employee_type(5555, 'john'))); CREATE OR REPLACE PROCEDURE p IS CURSOR cur IS SELECT id, data FROM mytab; v_id mytab.id%TYPE; v_data mytab.data%TYPE; v_type SYS.ANYTYPE; v_typecode PLS_INTEGER; v_typename VARCHAR2(60); v_dummy PLS_INTEGER; v_n NUMBER; v_employee employee_type; non_null_anytype_for_NUMBER exception; unknown_typename exception; BEGIN Using SQL Data Types in Database Applications 1-19 Representing Specialized Data OPEN cur; LOOP FETCH cur INTO v_id, v_data; EXIT WHEN cur%NOTFOUND; /* typecode signifies type represented by v_data. GetType also produces a value of type SYS.ANYTYPE with methods you can call to find precision and scale of a number, length of a string, and so on. */ v_typecode := v_data.GetType (v_type /* OUT */); /* Compare typecode to DBMS_TYPES constants to determine type of data and decide how to display it. */ CASE v_typecode WHEN DBMS_TYPES.TYPECODE_NUMBER THEN IF v_type IS NOT NULL THEN -- This condition should never happen. RAISE non_null_anytype_for_NUMBER; END IF; -- For each type, there is a Get method. v_dummy := v_data.GetNUMBER (v_n /* OUT */); DBMS_OUTPUT.PUT_LINE (TO_CHAR(v_id) || ': NUMBER = ' || TO_CHAR(v_n) ); WHEN DBMS_TYPES.TYPECODE_OBJECT THEN v_typename := v_data.GetTypeName(); IF v_typename NOT IN ('HR.EMPLOYEE_TYPE') THEN RAISE unknown_typename; END IF; v_dummy := v_data.GetObject (v_employee /* OUT */); DBMS_OUTPUT.PUT_LINE (TO_CHAR(v_id) || ': user-defined type = ' || v_typename || ' ( ' || v_employee.empno || ', ' || v_employee.ename || ' )' ); END CASE; END LOOP; CLOSE cur; EXCEPTION WHEN non_null_anytype_for_NUMBER THEN RAISE_Application_Error (-20000, 'Paradox: the return AnyType instance FROM GetType ' || 'should be NULL for all but user-defined types'); WHEN unknown_typename THEN RAISE_Application_Error( -20000, 'Unknown user-defined type ' || v_typename || ' - program written to handle only HR.EMPLOYEE_TYPE'); END; / SELECT t.data.gettypename() AS "Type Name" FROM mytab t; Result: Type Name -------------------------------------------------------------------------------SYS.NUMBER HR.EMPLOYEE_TYPE 2 rows selected. 1-20 Oracle Database Advanced Application Developer's Guide Representing Conditional Expressions as Data Representing ANSI, DB2, and SQL/DS Data SQL statements that create tables and clusters can use ANSI data types and data types from the IBM products SQL/DS and DB2 (except those noted after this paragraph). Oracle Database converts the ANSI or IBM data type to the equivalent Oracle data type, records the Oracle data type as the name of the column data type, and stores the column data in the Oracle data type. For conversion details, see Oracle Database SQL Language Reference. SQL statements cannot use the SQL/DS and DB2 data types TIME, GRAPHIC, VARGRAPHIC, and LONG VARGRAPHIC, because they have no equivalent Oracle data types. Note: Representing Conditional Expressions as Data Oracle Expression Filter (a feature of Rules Manager) enables you to store, index, and evaluate conditional expressions in one or more columns of a database table. Then Oracle Expression Filter compares the stored expressions to incoming data, identifying rows of interest. Scenario: You created the following table, in which each row holds data for a stock-trading account holder, and you want to define a column that stores information about the stocks in which each trader is interested as a conditional expression. DROP TABLE traders; CREATE TABLE traders ( name VARCHAR2(10), email VARCHAR2(20), interest VARCHAR2(30) ); Solution: 1. Create a type with attributes for the trading symbol, limit price, and amount of change in the stock price: CREATE OR REPLACE TYPE ticker AS OBJECT ( symbol VARCHAR2(20), price NUMBER, change NUMBER ); / 2. Create an attribute set based on the type ticker: BEGIN DBMS_EXPFIL.DROP_ATTRIBUTE_SET (attr_set END; / BEGIN DBMS_EXPFIL.CREATE_ATTRIBUTE_SET (attr_set => 'ticker', from_type => 'YES'); END; / 3. => 'ticker'); Associate the attribute set with the expression set stored in the column trader.interest: BEGIN Using SQL Data Types in Database Applications 1-21 Identifying Rows by Address DBMS_EXPFIL.ASSIGN_ATTRIBUTE_SET (attr_set => 'ticker', expr_tab => 'traders', expr_col => 'interest'); END; / The preceding code ensures that the interest column stores valid conditional expressions. 4. Populate the table with trader names, e-mail addresses, and conditional expressions that represent stocks in which the trader is interested, at specific prices. For example: INSERT INTO traders (name, email, interest) VALUES ('Vishu', 'vishu@example.com', 'symbol = ''ABC'' AND price > 25'); 5. Use the EVALUATE operator to identify the conditional expressions that evaluate to TRUE for a given data item. For example, this query returns traders who are interested in the stock quote (symbol='ABC', price=31, change=5.2): SELECT name, email FROM traders WHERE EVALUATE ( interest, 'symbol=>''ABC'', price=>31, change=>5.2' ) = 1; Result: NAME EMAIL ---------- -------------------Vishu vishu@example.com 1 row selected. Tip: To speed up the query, create an Oracle Expression Filter index on the interest column. See Also: Oracle Database Rules Manager and Expression Filter Developer's Guide for information about developing applications using Oracle Expression Filter Identifying Rows by Address The fastest way to access a row is by its address, or rowid, which uniquely identifies it. Different rows in the same data block can have the same rowid only if they are in different clustered tables. If a row is larger than one data block, then its rowid identifies its initial row piece. To see rowids, query the ROWID pseudocolumn, whose value is a string that represents the address of the row. The string has the data type ROWID or UROWID. 1-22 Oracle Database Advanced Application Developer's Guide Identifying Rows by Address When you update a row in a table compressed with Hybrid Columnar Compression (HCC), the ROWID of the row changes. HCC, a feature of certain Oracle storage systems, is described in Oracle Database Concepts. Note: Topics: ■ Querying the ROWID Pseudocolumn ■ ROWID Data Type ■ UROWID Data Type See Also: Oracle Database SQL Language Reference for more information about the ROWID pseudocolumn Querying the ROWID Pseudocolumn Each table in Oracle Database has a pseudocolumn named ROWID, which can appear in a query in either the SELECT list or WHERE clause. Example 1–5 creates a table of with a column of the data type ROWID, populates it with rowids by querying the ROWID pseudocolumn inside an INSERT statement, and then displays it. The rowids of the table rows show how they are stored. Example 1–5 Querying the ROWID Pseudocolumn DROP TABLE t_tab; -- in case it exists CREATE TABLE t_tab (col1 ROWID); INSERT INTO t_tab (col1) SELECT ROWID FROM employees WHERE employee_id > 199; Query: SELECT employee_id, rowid FROM employees WHERE employee_id > 199; ROWID varies, but result is similar to: EMPLOYEE_ID ----------200 201 202 203 204 205 206 ROWID -----------------AAAPeSAAFAAAABTAAC AAAPeSAAFAAAABTAAD AAAPeSAAFAAAABTAAE AAAPeSAAFAAAABTAAF AAAPeSAAFAAAABTAAG AAAPeSAAFAAAABTAAH AAAPeSAAFAAAABTAAI 7 rows selected. Query: SELECT * FROM t_tab; Using SQL Data Types in Database Applications 1-23 Identifying Rows by Address COL1 varies, but result is similar to: COL1 -----------------AAAPeSAAFAAAABTAAC AAAPeSAAFAAAABTAAD AAAPeSAAFAAAABTAAE AAAPeSAAFAAAABTAAF AAAPeSAAFAAAABTAAG AAAPeSAAFAAAABTAAH AAAPeSAAFAAAABTAAI 7 rows selected. ROWID Data Type In heap-organized tables generated by Oracle Database, the values in the ROWID pseudocolumn have the data type ROWID. Internally, this data type is a structure that stores information that the database server needs to access a row. The format of this structure is either restricted, extended, or external binary. Creating a column of the type ROWID (like col1 in Example 1–5) does not guarantee that its values will be valid rowids. Note: Topics: ■ Restricted Internal ROWID Format ■ Extended Internal ROWID Format ■ External Binary Internal ROWID Format Restricted Internal ROWID Format A ROWID structure with the restricted internal format has these components: ■ Data file identifier ■ Block identifier ■ Row identifier On most platforms, the size of this structure is 6 bytes. The database server returns a ROWID pseudocolumn value to the client application as an 18-character string with a hexadecimal encoding of each component. Extended Internal ROWID Format A ROWID structure with the extended internal format has the same components as the restricted format and a data object number, which identifies a database segment. On most platforms, the size of this structure is 10 bytes. The database server returns a ROWID pseudocolumn value to the client application as an 18-character string with a base-64 encoding of each component. For example, the string might be "AAAA8mAALAAAAQkAAA", which represents a base-64 encoding of the components of the extended ROWID in a four-piece format, OOOOOOFFFBBBBBBRRR. To access and interpret the contents of an extended rowid, use the DBMS_ROWID package, described in Oracle Database PL/SQL Packages and Types Reference. 1-24 Oracle Database Advanced Application Developer's Guide How Oracle Database Converts Data Types External Binary Internal ROWID Format Some client applications use a binary internal format for the ROWID structure. For example, OCI and some precompiler applications can map the ROWID data type to a 3GL structure on bind or define calls. In binary internal format, the ROWID structure is the same size for restricted and extended rowids. For a restricted rowid, the data object number is stored in an unused field. The format of the extended binary ROWID, expressed as a C struct, is: struct riddef { ub4 ridobjnum; /* data obj#--this field is unused in restricted ROWIDs */ ub2 ridfilenum; ub1 filler; ub4 ridblocknum; ub2 ridslotnum; } UROWID Data Type In tables that are foreign (that is, not generated by Oracle Database) or index-organized, the values in the ROWID pseudocolumn have the data type UROWID. This data type stores a universal rowid (urowid). Urowids for foreign tables (such as DB2 tables accessed through a gateway) are called foreign rowids. Urowids for index-organized tables (whose rows are stored in index leaves, which can move) are called logical rowids. Oracle Database creates logical rowids based on the primary key of the table. The logical rowids do not change if the primary key does not change. To store urowids in a table, define a column of data type UROWID for the table and then retrieve the value of the ROWID pseudocolumn into that column. How Oracle Database Converts Data Types Generally, you cannot assign a value of one data type to a variable or column of another data type, or create an expression with values of different data types. However, in some cases, Oracle Database accepts data of one type where it expects data of another type and then automatically converts the accepted data to the expected type. This is called implicit data conversion. Topics: ■ Data Type Conversion During Assignments ■ Data Type Conversion During Expression Evaluation See Also: Oracle Database SQL Language Reference for more information about data type conversion Data Type Conversion During Assignments For the assignment variable := expression Using SQL Data Types in Database Applications 1-25 How Oracle Database Converts Data Types if the data type of expression differs from that of variable, then Oracle Database tries to convert the data type of expression to that of variable. For information about when that is possible, see Oracle Database SQL Language Reference. A character-to-NUMBER conversion succeeds only if the character string represents a valid number. A character-to-DATE conversion succeeds only if the character string satisfies the session default date format. (For information about the default date format, see "Displaying Current Date and Time" on page 1-11.) Examples Assume that test_package, its public variable var1, and table1_tab are declared as follows: CREATE OR REPLACE PACKAGE test_package AS var1 CHAR(5); END; / DROP TABLE table1_tab; CREATE TABLE table1_tab (col1 NUMBER); In the assignment variable := expression the data type of expression must be either the same as, or implicitly convertible to, the data type of variable. For example, for this assignment, Oracle Database automatically converts zero to the data type of var1, which is CHAR(5): var1 := 0; In the statement INSERT INTO table1_tab (col1) VALUES (expression) the data type of expression must be either the same as, or implicitly convertible to, the data type of col1. For example, for this statement, Oracle Database automatically converts the string '19' to the data type of col1, which is NUMBER: INSERT INTO table1_tab (col1) VALUES ('19') In the statement UPDATE table1_tab SET column = expression the data type of expression must be either the same as, or implicitly convertible to, the data type of column. For example, for this statement, Oracle Database automatically converts the string '30' to the data type of col1, which is NUMBER: UPDATE table1_tab SET col1 = '30'; In the statement SELECT column INTO variable FROM table1_tab the data type of column must be either the same as, or convertible to, the data type of variable. For example, for this statement, Oracle Database automatically converts the value selected from col1, which is 30, to the data type of var1, which is CHAR(5): SELECT col1 INTO var1 FROM table1_tab WHERE col1 = 30; 1-26 Oracle Database Advanced Application Developer's Guide Metadata for SQL Operators and Functions Data Type Conversion During Expression Evaluation When evaluating an expression, Oracle Database can perform the same automatic conversions that it does for assignments. The target data type is determined by the context of the expression. For example, if an expression is the operand of an arithmetic operator, then Oracle Database tries to convert the value of the expression to NUMBER; if the expression is the operand of a string function, then Oracle Database tries to convert the value of the expression to VARCHAR2. For the assignment variable := expression Oracle Database first evaluates expression, using the conversion rules for expressions. If the evaluation succeeds, the result is a single value of a single data type, which Oracle Database tries to assign to variable, using the conversion rules for assignments. Metadata for SQL Operators and Functions The dynamic performance view V$SQLFN_METADATA contains metadata about SQL operators and functions. For every function in V$SQLFN_METADATA, the dynamic performance view V$SQLFN_ARG_METADATA has one row of metadata about each function argument. If a function argument can be repeated (as in the functions LEAST and GREATEST), then V$SQLFN_ARG_METADATA has only one row for each repeating argument. You can join these two views on the column FUNCID. These views enable third-party tools to leverage SQL functions without maintaining their metadata in the application layer. Topics: ARGn Data Type ■ ■ DISP_TYPE Data Type ■ Data Type Families See Also: ■ ■ Oracle Database Reference for more information about V$SQLFN_ METADATA Oracle Database Reference for more information about V$SQLFN_ ARG_METADATA ARGn Data Type In the view V$SQLFN_METADATA, the column DATATYPE is the data type of the function (that is, the data type that the function returns). This data type can be an Oracle data type, data type family (see "Data Type Families" on page 1-28), or ARGn. ARGn is the data type of the nth argument of the function. For example: ■ ■ The MAX function (described in Oracle Database SQL Language Reference) returns a value that has the data type of its first argument, so the MAX function has return data type ARG1. The DECODE function (described in Oracle Database SQL Language Reference) returns a value that has the data type of its third argument, so the DECODE function has data type ARG3. Using SQL Data Types in Database Applications 1-27 Metadata for SQL Operators and Functions DISP_TYPE Data Type In the view V$SQLFN_METADATA, DISP_TYPE is the data type of an argument that can be any expression. An expression is either a single value or a combination of values and SQL functions that has a single value. Table 1–10 Display Types of SQL Functions Display Type Description Example NORMAL FUNC(A,B,...) LEAST(A,B,C) ARITHMETIC A FUNC B) A+B PARENTHESIS FUNC() SYS_GUID() RELOP A FUNC B A IN B CASE_LIKE CASE statement or DECODE decode NOPAREN FUNC SYSDATE Data Type Families Often, a SQL function argument can have any data type in a data type family. Table 1–11 shows the data type families and their member data types. Table 1–11 Data Type Families Family Data Types STRING CHARACTER VARCHAR2 CLOB NCHAR NVARCHAR2 NCLOB LONG NUMERIC NUMBER BINARY_FLOAT BINARY_DOUBLE DATETYPE DATE TIMESTAMP TIMESTAMP WITH TIME ZONE TIMESTAMP WITH LOCAL TIME ZONE INTERVAL YEAR TO MONTH INTERVAL DAY TO SECOND BINARY BLOB RAW LONGRAW 1-28 Oracle Database Advanced Application Developer's Guide 2 SQL Processing for Application Developers 2 This chapter explains what application developers must know about how Oracle Database processes SQL statements. Before reading this chapter, read the basic information about SQL processing in Oracle Database Concepts. Topics: Description of SQL Statement Processing ■ ■ Grouping Operations into Transactions ■ Ensuring Repeatable Reads with Read-Only Transactions ■ Using Cursors ■ Locking Tables Explicitly ■ Using Oracle Lock Management Services (User Locks) ■ Using Serializable Transactions for Concurrency Control ■ Autonomous Transactions ■ Resuming Execution After Storage Allocation Errors Description of SQL Statement Processing This topic explains what happens during each stage of processing the execution of a SQL statement, using a DML statement as an example. Assume that you are using a Pro*C program to increase the salary for all employees in a department. The program has connected to Oracle Database and you are connected to the HR schema, which owns the employees table. You can embed this SQL statement in your program: EXECUTE SQL UPDATE employees SET salary = 1.10 * salary WHERE department_id = :department_id; The program provides a value for the bind variable placeholder :department_id, which the SQL statement uses when it runs. Stages of SQL Statement Processing DML statements use all stages. Transaction management, session management, and system management SQL statements use only stages 2 and 8. Note: SQL Processing for Application Developers 2-1 Description of SQL Statement Processing 1. Open or create a cursor. A program interface call opens or creates a cursor, in expectation of a SQL statement. Most applications create the cursor implicitly (automatically). Precompiler programs can create the cursor either implicitly or explicitly. 2. Parse the statement. The user process passes the SQL statement to Oracle Database, which loads a parsed representation of the statement into the shared SQL area. Oracle Database can catch many errors during parsing. For a DDL statement, parsing includes data dictionary lookup and execution. Note: See Also: ■ Oracle Database Concepts for information about parsing ■ "Shared SQL Areas" on page 2-3 3. Determine if the statement is a query. 4. If the statement is a query, describe its results. This stage is necessary only if the characteristics of the result are unknown; for example, when a user enters the query interactively. Note: Oracle Database determines the characteristics (data types, lengths, and names) of the result. 5. If the statement is a query, define its output. You specify the location, size, and data type of variables defined to receive each fetched value. These variables are called define variables. Oracle Database performs data type conversion if necessary. Oracle Database Concepts for information about the DEFINE stage See Also: 6. Bind any variables. Oracle Database has determined the meaning of the SQL statement but does not have enough information to run it. Oracle Database needs values for any bind variable placeholders in the statement. In the example, Oracle Database needs a value for :department_id. The process of obtaining these values is called binding variables. A program must specify the location (memory address) of the value. End users of applications may be unaware that they are specifying values for bind variable placeholders, because the Oracle Database utility can prompt them for the values. Because the program specifies the location of the value (that is, binds by reference), it need not rebind the variable before rerunning the statement, even if the value changes. Each time Oracle Database runs the statement, it gets the value of the variable from its address. 2-2 Oracle Database Advanced Application Developer's Guide Description of SQL Statement Processing You must also specify a data type and length for each value (unless they are implied or defaulted) if Oracle Database must perform data type conversion. See Also: For more information about specifying a data type and length for a value: 7. ■ Oracle Call Interface Programmer's Guide ■ Pro*C/C++ Programmer's Guide (Optional) Parallelize the statement. Oracle Database can parallelize queries and some data definition language (DDL) operations (for example, index creation, creating a table with a subquery, and operations on partitions). Parallelization causes multiple server processes to perform the work of the SQL statement so that it can complete faster. 8. Run the statement. Oracle Database runs the statement. If the statement is a query or an INSERT statement, the database locks no rows, because no data is changing. If the statement is an UPDATE or DELETE statement, the database locks all rows that the statement affects, until the next COMMIT, ROLLBACK, or SAVEPOINT for the transaction, thereby ensuring data integrity. For some statements, you can specify multiple executions to be performed. This is called array processing. Given n number of executions, the bind and define locations are assumed to be the beginning of an array of size n. 9. If the statement is a query, fetch its rows. Oracle Database selects rows and, if the query has an ORDER BY clause, orders the rows. Each successive fetch retrieves another row of the result set, until the last row has been fetched. 10. Close the cursor. Oracle Database closes the cursor. To rerun a transaction management, session management, or system management SQL statement, use another EXECUTE statement. Note: Shared SQL Areas Oracle Database automatically detects when applications send similar SQL statements to the database. The SQL area used to process the first occurrence of the statement is shared—that is, used for processing subsequent occurrences of that same statement. Therefore, only one shared SQL area exists for a unique statement. Because shared SQL areas are shared memory areas, any Oracle Database process can use a shared SQL area. The sharing of SQL areas reduces memory use on the database server, thereby increasing system throughput. In determining whether statements are similar or identical, Oracle Database compares both SQL statements issued directly by users and applications and recursive SQL statements issued internally by DDL statements. See Also: Oracle Database Performance Tuning Guide for more information about shared SQL SQL Processing for Application Developers 2-3 Grouping Operations into Transactions Grouping Operations into Transactions Topics: ■ Deciding How to Group Operations in Transactions ■ Improving Transaction Performance ■ Committing Transactions ■ Managing Commit Redo Action ■ Rolling Back Transactions ■ Defining Transaction Savepoints See Also: Oracle Database Concepts for basic information about transactions Deciding How to Group Operations in Transactions Typically, deciding how to group operations in transactions is the concern of application designers who use programming interfaces to Oracle Database. When deciding how to group transactions: ■ ■ ■ Define transactions such that work is accomplished in logical units and data remains consistent. Ensure that data in all referenced tables is in a consistent state before the transaction begins and after it ends. Ensure that each transaction consists only of the SQL statements or PL/SQL blocks that comprise one consistent change to the data. For example, suppose that you write a web application that enables users to transfer funds between accounts. The transaction must include the debit to one account, executed by one SQL statement, and the credit to another account, executed by another SQL statement. Both statements must fail or succeed as a unit of work; one statement must not be committed without the other. Do not include unrelated actions, such as a deposit to one account, in the transaction. Improving Transaction Performance As an application developer, you must try to improve performance. Consider using these performance enhancement techniques when designing and writing your application: ■ For each transaction: 1. If you can use a single SQL statement, then do so. 2. If you cannot use a single SQL statement but you can use PL/SQL, then use as little PL/SQL as possible. For information about PL/SQL, see Part II, "PL/SQL for Application Developers". 3. If you cannot use PL/SQL (because it cannot do what you must do; for example, send email), then use Java. 4. If you cannot use Java (for example, if it is too slow) or you have existing third-generation language (3GL) code, then use an external C subprogram. 2-4 Oracle Database Advanced Application Developer's Guide Grouping Operations into Transactions For information about using Java and C in your application, see Chapter 14, "Developing Applications with Multiple Programming Languages." ■ Establish standards for writing SQL statements so that you can take advantage of shared SQL areas. Oracle Database recognizes identical SQL statements and enables them to share memory areas, reducing memory usage on the database server and increasing system throughput. ■ Collect statistics that Oracle Database can use to implement a cost-based approach to SQL statement optimization, and use additional hints to the optimizer as needed. To collect most statistics, use the DBMS_STATS package, which lets you collect statistics in parallel, collect global statistics for partitioned objects, and fine-tune your statistics collection in other ways. For more information about this package, see Oracle Database PL/SQL Packages and Types Reference. To collect statistics unrelated to the cost-based optimizer (such as information about free list blocks), use the SQL statement ANALYZE. For more information about this statement, see Oracle Database SQL Language Reference. For more information about hints, see Oracle Database SQL Language Reference. ■ ■ Before beginning a transaction, invoke DBMS_APPLICATION_INFO procedures to record the name of the transaction in the database for later use when tracking its performance with Oracle Trace and the SQL trace facility. For information about the DBMS_APPLICATION_INFO package, see Oracle Database PL/SQL Packages and Types Reference. Increase user productivity and query efficiency by including user-written PL/SQL functions in SQL expressions. For details, see "Invoking Stored PL/SQL Functions from SQL Statements" on page 6-35. Oracle Database Concepts for more information about transaction management See Also: Committing Transactions To commit a transaction, use the COMMIT statement. These two statements are equivalent and commit the current transaction: COMMIT WORK; COMMIT; The COMMIT statement lets you include the COMMENT parameter with a comment that provides information about the transaction being committed. A comment is useful for including information about the origin of the transaction when you commit distributed transactions: COMMIT COMMENT 'Dallas/Accts_pay/Trans_type 10B'; See Also: Oracle Database SQL Language Reference for information about the COMMIT statement Managing Commit Redo Action When a transaction updates Oracle Database, it generates a corresponding redo entry. Oracle Database buffers the redo entry to the redo log until the transaction completes. When the transaction commits, the log writer process (LGWR) writes redo records to SQL Processing for Application Developers 2-5 Grouping Operations into Transactions disk for the buffered redo entries of all changes in the transaction. By default, Oracle Database writes the redo entries to disk before the call returns to the client. This action causes a latency in the commit, because the application must wait for the redo entries to be persistent on disk. Oracle Database lets you change the handling of commit redo to fit the needs of your application. If your application requires very high transaction throughput and you are willing to trade commit durability for lower commit latency, then you can change the default COMMIT options so that the application need not wait for the database to write data to the online redo logs. Table 2–1 describes the COMMIT options. Caution: With the NOWAIT option, a failure that occurs after the commit message is received, but before the redo log records are written, can falsely indicate to a transaction that its changes are persistent. Table 2–1 COMMIT Statement Options Option Effect WAIT (default) Ensures that the COMMIT statement returns only after the corresponding redo information is persistent in the online redo log. When the client receives a successful return from this COMMIT statement, the transaction has been committed to durable media. A failure that occurs after a successful write to the log might prevent the success message from returning to the client, in which case the client cannot tell whether the transaction committed. NOWAIT (alternative to WAIT) The COMMIT statement returns to the client regardless of whether the write to the redo log has completed. This behavior can increase transaction throughput. BATCH (alternative to IMMEDIATE) Buffers the redo information to the redo log with concurrently running transactions. After collecting sufficient redo information, initiates a disk write to the redo log. This behavior is called group commit, because it writes redo information for multiple transactions to the log in a single I/O operation. IMMEDIATE (default) LGWR writes the transaction redo information to the log. Because this operation option forces a disk I/O, it can reduce transaction throughput. To change the COMMIT options, use either the COMMIT statement (described in Oracle Database SQL Language Reference) or the appropriate initialization parameter. For information about initialization parameters, see Oracle Database Reference. You cannot change the default IMMEDIATE and WAIT action for distributed transactions. Note: If your application uses Oracle Call Interface (OCI), then you can modify redo action by setting these flags in the OCITransCommit function in your application: ■ OCI_TRANS_WRITEWAIT ■ OCI_TRANS_WRITENOWAIT ■ OCI_TRANS_WRITEBATCH ■ OCI_TRANS_WRITEIMMED 2-6 Oracle Database Advanced Application Developer's Guide Grouping Operations into Transactions OCI_TRANS_WRITENOWAIT can cause silent transaction loss with shutdown termination, startup force, and any instance or node failure. On an Oracle RAC system, asynchronously committed changes might not be immediately available to read on other instances. Caution: See Also: Oracle Call Interface Programmer's Guide for information about the OCITransCommit function The specification of the NOWAIT and BATCH options has a small window of vulnerability in which Oracle Database can roll back a transaction that your application views as committed. Your application must be able to tolerate these scenarios: ■ ■ The database host fails, which causes the database to lose redo entries that were buffered but not yet written to the online redo logs. A file I/O problem prevents LGWR from writing buffered redo entries to disk. If the redo logs are not multiplexed, then the commit is lost. Rolling Back Transactions To roll back an entire transaction, or to roll back part of a transaction to a savepoint, use the ROLLBACK statement. For example, either of these statements rolls back the entire current transaction: ROLLBACK WORK; ROLLBACK; The WORK option of the ROLLBACK statement has no function. To roll back to a savepoint defined in the current transaction, use the TO option of the ROLLBACK statement. For example, either of these statements rolls back the current transaction to the savepoint named POINT1: SAVEPOINT Point1; ... ROLLBACK TO SAVEPOINT Point1; ROLLBACK TO Point1; Defining Transaction Savepoints To define a savepoint in a transaction, use the SAVEPOINT statement. This statement creates the savepoint named ADD_EMP1 in the current transaction: SAVEPOINT Add_emp1; Creating a savepoint with the same identifier as an earlier savepoint deletes the earlier savepoint. After creating a savepoint, you can roll back to it. An active savepoint is one that was created after the last COMMIT or ROLLBACK statement. The number of active savepoints for each session is unlimited. Table 2–2 shows a series of SQL statements that illustrates the use of COMMIT, SAVEPOINT, and ROLLBACK statements within a transaction. SQL Processing for Application Developers 2-7 Ensuring Repeatable Reads with Read-Only Transactions Table 2–2 Use of COMMIT, SAVEPOINT, and ROLLBACK SQL Statement Results SAVEPOINT a; First savepoint of this transaction DELETE...; First DML statement of this transaction SAVEPOINT b; Second savepoint of this transaction INSERT INTO...; Second DML statement of this transaction SAVEPOINT c; Third savepoint of this transaction UPDATE...; Third DML statement of this transaction ROLLBACK TO c; UPDATE statement is rolled back, savepoint C remains defined. ROLLBACK TO b; INSERT statement is rolled back, savepoint C is lost, savepoint B remains defined. ROLLBACK TO c; ORA-01086 INSERT INTO...; New DML statement in this transaction COMMIT; Commits all actions performed by the first DML statement (the DELETE statement) and the last DML statement (the second INSERT statement). All other statements (the second and the third statements) of the transaction were rolled back before the COMMIT. The savepoint A is no longer active. Ensuring Repeatable Reads with Read-Only Transactions By default, Oracle Database guarantees statement-level read consistency, but not transaction-level read consistency. With statement-level read consistency, queries in a statement produce consistent data for the duration of the statement, not reflecting changes by other statements. With transaction-level read consistency (repeatable reads), queries in the transaction produce consistent data for the duration of the transaction, not reflecting changes by other transactions. To ensure transaction-level read consistency for a transaction that does not include DML statements, specify that the transaction is read-only. The queries in a read-only transaction see only changes committed before the transaction began, so query results are consistent for the duration of the transaction. A read-only transaction provides transaction-level read consistency without acquiring additional data locks. Therefore, while the read-only transaction is querying data, other transactions can query and update the same data. A read-only transaction begins with this statement: SET TRANSACTION READ ONLY [ NAME string ]; Only DDL statements can precede the SET TRANSACTION READ ONLY statement. After the SET TRANSACTION READ ONLY statement successfully runs, the transaction can include only SELECT (without FOR UPDATE), COMMIT, ROLLBACK, or non-DML statements (such as SET ROLE, ALTER SYSTEM, and LOCK TABLE). A COMMIT, ROLLBACK, or DDL statement ends the read-only transaction. See Also: Oracle Database SQL Language Reference for more information about the SET TRANSACTION statement 2-8 Oracle Database Advanced Application Developer's Guide Using Cursors Long-running queries sometimes fail because undo information required for consistent read (CR) operations is no longer available. This situation occurs when active transactions overwrite committed undo blocks. Automatic undo management lets your database administrator (DBA) explicitly control how long the database retains undo information, using the parameter UNDO_ RETENTION. For example, if UNDO_RETENTION is set to 30 minutes, then the database retains all committed undo information for at least 30 minutes, ensuring that all queries running for 30 minutes or less do not encounter the OER error "snapshot too old." See Also: Oracle Database Administrator's Guide for information about long-running queries and resumable space allocation Using Cursors PL/SQL implicitly declares a cursor for all SQL data manipulation statements, including queries that return only one row. For queries that return multiple rows, you can explicitly declare a cursor to process the rows individually. You can think of a cursor as a name for a specific private SQL area. A PL/SQL cursor variable lets you retrieve multiple rows from a stored subprogram. You can pass cursor variables as parameters in your 3GL application. For more information about cursor variables, see Oracle Database PL/SQL Language Reference. Most Oracle Database users rely on the automatic cursor handling of the database utilities, but programmatic interfaces offer application designers more control over cursors. In application development, a cursor is a named resource available to a program, which can be specifically used for parsing SQL statements embedded within the application. Topics: ■ How Many Cursors Can a Session Have? ■ Using a Cursor to Reexecute a Statement ■ Scrollable Cursors ■ Closing a Cursor ■ Canceling a Cursor How Many Cursors Can a Session Have? The number of cursors that a session can have open simultaneously is determined by: ■ ■ The amount of memory available to the session The value of the initialization parameter OPEN_CURSORS, described in Oracle Database Reference Explicitly creating cursors for precompiler programs has advantages in tuning those applications. For example, increasing the number of cursors can reduce the frequency of parsing and improve performance. If you know how many cursors might be required at a given time, you can open that many cursors simultaneously. Using a Cursor to Reexecute a Statement After each stage of execution, the cursor retains enough information about the SQL statement to reexecute the statement without starting over, if no other SQL statement SQL Processing for Application Developers 2-9 Using Cursors was associated with that cursor. The statement can be reexecuted without including the parse stage. By opening several cursors, the parsed representation of several SQL statements can be saved. Repeated execution of the same SQL statements can thus begin at the describe, define, bind, or run step, saving the repeated cost of opening cursors and parsing. To understand the performance characteristics of a cursor, the DBA can use the V$SQL dynamic performance view to display the text of the associated query (see Oracle Database Reference). Because the results of EXPLAIN PLAN for the original query might differ from the way the database actually processes the query, the DBA can get more precise information by examining these dynamic performance views: View Description V$SQL_PLAN Execution plan information for each child cursor loaded in the library cache. For more information, see Oracle Database Reference. V$SQL_PLAN_STATISTICS Execution statistics at the row source level for each child cursor. For more information, see Oracle Database Reference. V$SQL_PLAN_STATISTICS_ALL Memory usage statistics for row sources that use SQL memory (sort or hash-join). This view concatenates information in V$SQL_PLAN with execution statistics from V$SQL_PLAN_STATISTICS and V$SQL_WORKAREA. For more information, see Oracle Database Reference. Scrollable Cursors Execution of a cursor puts the results of the query into a set of rows called the result set. A scrollable cursor is one whose result rows need not be fetched in forward sequential order. For a scrollable cursor, interfaces exist to fetch previously fetched rows, to fetch the nth row in the result set, and to fetch the nth row from the current position in the result set. See Also: Oracle Call Interface Programmer's Guide for more information about using scrollable cursors in OCI Closing a Cursor Closing a cursor makes its information inaccessible and deallocates the memory that it uses. After a cursor opens, it does not close until the user program terminates its connection to the server. An OCI program or precompiler application that follows good programming practice explicitly closes open cursors during program execution. If the program terminates without closing an open cursor, then that cursor closes implicitly. Canceling a Cursor Canceling a cursor frees resources from the current fetch.The information in the associated private area is lost but the cursor remains open, parsed, and associated with its bind variables. Note: You cannot cancel cursors using Pro*C/C++ or PL/SQL. 2-10 Oracle Database Advanced Application Developer's Guide Locking Tables Explicitly See Also: Oracle Call Interface Programmer's Guide for information about canceling a cursor with the OCIStmtFetch2 statement Locking Tables Explicitly Oracle Database has default locking mechanisms that ensure data concurrency, data integrity, and statement-level read consistency. However, you can override these mechanisms by locking tables explicitly. Locking tables explicitly is useful in situations such as these: ■ ■ A transaction in your application needs exclusive access to a resource, so that the transaction does not have to wait for other transactions to complete. Your application needs transaction-level read consistency (repeatable reads). For other ways to ensure transaction-level read consistency, see "Ensuring Repeatable Reads with Read-Only Transactions" on page 2-8) and "Using Serializable Transactions for Concurrency Control" on page 2-23. To override default locking at the transaction level, use any of these SQL statements: ■ ■ ■ LOCK TABLE (described in Oracle Database SQL Language Reference) SELECT with the FOR UPDATE clause (described in Oracle Database SQL Language Reference) SET TRANSACTION with the READ ONLY or ISOLATION LEVEL SERIALIZABLE option (described in Oracle Database SQL Language Reference) Locks acquired by these statements are released after the transaction is committed or rolled back. See Also: Oracle Database SQL Language Reference for information about the ISOLATION_LEVEL parameter of the ALTER SESSION statement The initialization parameter DML_LOCKS (described in Oracle Database Reference) determines the maximum number of DML locks. Although its default value is usually enough, you might need to increase it if you use explicit locks. Caution: If you override the default locking of Oracle Database at any level, ensure that data integrity is guaranteed, data concurrency is acceptable, and deadlocks are either impossible or appropriately handled. Topics: ■ Privileges Required to Acquire Table Locks ■ Choosing a Locking Strategy ■ Letting Oracle Database Control Table Locking ■ Explicitly Acquiring Row Locks ■ Examples of Concurrency Under Explicit Locking Privileges Required to Acquire Table Locks No special privileges are required to acquire any type of table lock on a table in your own schema. To acquire a table lock on a table in another schema, you must have SQL Processing for Application Developers 2-11 Locking Tables Explicitly either the LOCK ANY TABLE system privilege or any object privilege (for example, SELECT or UPDATE) for the table. Choosing a Locking Strategy A transaction explicitly acquires the specified table locks when a LOCK TABLE statement is executed. A LOCK TABLE statement explicitly overrides default locking. When a LOCK TABLE statement is issued on a view, the underlying base tables are locked. This statement acquires exclusive table locks for the employees and departments tables on behalf of the containing transaction: LOCK TABLE employees, departments IN EXCLUSIVE MODE NOWAIT; You can specify several tables or views to lock in the same mode; however, only a single lock mode can be specified for each LOCK TABLE statement. When a table is locked, all rows of the table are locked. No other user can modify the table. For information about locking individual rows, see "Explicitly Acquiring Row Locks" on page 2-15. Note: In the LOCK TABLE statement, you can also indicate how long you want to wait for the table lock: ■ If you do not want to wait, specify either NOWAIT or WAIT 0. You acquire the table lock only if it is immediately available; otherwise, an error notifies you that the lock is not available now. ■ To wait up to n seconds to acquire the table lock, specify WAIT n, where n is greater than 0 and less than or equal to 100000. If the table lock is still unavailable after n seconds, an error notifies you that the lock is not available now. ■ To wait indefinitely to acquire the lock, specify neither NOWAIT nor WAIT. The database waits indefinitely until the table is available, locks it, and returns control to you. When the database is running DDL statements concurrently with DML statements, a timeout or deadlock can sometimes result. The database detects such timeouts and deadlocks and returns an error. Topics: ■ When to Lock with ROW SHARE MODE and ROW EXCLUSIVE MODE ■ When to Lock with SHARE MODE ■ When to Lock with SHARE ROW EXCLUSIVE MODE ■ When to Lock with EXCLUSIVE MODE Oracle Database SQL Language Reference for LOCK TABLE statement syntax See Also: When to Lock with ROW SHARE MODE and ROW EXCLUSIVE MODE ROW SHARE MODE and ROW EXCLUSIVE MODE table locks offer the highest degree of concurrency. You might use these locks if: 2-12 Oracle Database Advanced Application Developer's Guide Locking Tables Explicitly ■ Your transaction must prevent another transaction from acquiring an intervening share, share row, or exclusive table lock for a table before your transaction can update that table. If another transaction acquires an intervening share, share row, or exclusive table lock, no other transactions can update the table until the locking transaction commits or rolls back. ■ Your transaction must prevent a table from being altered or dropped before your transaction can modify that table. When to Lock with SHARE MODE SHARE MODE table locks are rather restrictive data locks. You might use these locks if: ■ ■ ■ Your transaction only queries the table, and requires a consistent set of the table data for the duration of the transaction. You can hold up other transactions that try to update the locked table, until all transactions that hold SHARE MODE locks on the table either commit or roll back. Other transactions might acquire concurrent SHARE MODE table locks on the same table, also giving them the option of transaction-level read consistency. Caution: Your transaction might not update the table later in the same transaction. However, if multiple transactions concurrently hold share table locks for the same table, no transaction can update the table (even if row locks are held as the result of a SELECT FOR UPDATE statement). Therefore, if concurrent share table locks on the same table are common, updates cannot proceed and deadlocks are common. In this case, use share row exclusive or exclusive table locks instead. Scenario: Tables employees and budget_tab require a consistent set of data in a third table, departments. For a given department number, you want to update the information in employees and budget_tab, and ensure that no members are added to the department between these two transactions. Solution: Lock the departments table in SHARE MODE, as shown in Example 2–1. Because the departments table is rarely updated, locking it probably does not cause many other transactions to wait long. Example 2–1 LOCK TABLE with SHARE MODE -- Create and populate table: DROP TABLE budget_tab; CREATE TABLE budget_tab ( sal NUMBER(8,2), deptno NUMBER(4) ); INSERT INTO budget_tab (sal, deptno) SELECT salary, department_id FROM employees; -- Lock departments and update employees and budget_tab: LOCK TABLE departments IN SHARE MODE; SQL Processing for Application Developers 2-13 Locking Tables Explicitly UPDATE employees SET salary = salary * 1.1 WHERE department_id IN (SELECT department_id FROM departments WHERE location_id = 1700); UPDATE budget_tab SET sal = sal * 1.1 WHERE deptno IN (SELECT department_id FROM departments WHERE location_id = 1700); -- COMMIT releases lock COMMIT; When to Lock with SHARE ROW EXCLUSIVE MODE You might use a SHARE ROW EXCLUSIVE MODE table lock if: ■ ■ ■ Your transaction requires both transaction-level read consistency for the specified table and the ability to update the locked table. You do not care if other transactions acquire explicit row locks (using SELECT FOR UPDATE), which might make UPDATE and INSERT statements in the locking transaction wait and might cause deadlocks. You only want a single transaction to have this action. When to Lock with EXCLUSIVE MODE You might use an EXCLUSIVE MODE table if: ■ ■ ■ Your transaction requires immediate update access to the locked table. When your transaction holds an exclusive table lock, other transactions cannot lock specific rows in the locked table. Your transaction also ensures transaction-level read consistency for the locked table until the transaction is committed or rolled back. You are not concerned about low levels of data concurrency, making transactions that request exclusive table locks wait in line to update the table sequentially. Letting Oracle Database Control Table Locking If you let Oracle Database control table locking, your application needs less programming logic, but also has less control than if you manage the table locks yourself. Issuing the statement SET TRANSACTION ISOLATION LEVEL SERIALIZABLE or ALTER SESSION ISOLATION LEVEL SERIALIZABLE preserves ANSI serializability without changing the underlying locking protocol. This technique gives concurrent access to the table while providing ANSI serializability. Getting table locks greatly reduces concurrency. See Also: ■ ■ Oracle Database SQL Language Reference for information about the SET TRANSACTION statement Oracle Database SQL Language Reference for information about the ALTER SESSION statements Change the settings for these parameters only when an instance is shut down. If multiple instances are accessing a single database, then all instances must use the same setting for these parameters. 2-14 Oracle Database Advanced Application Developer's Guide Locking Tables Explicitly Explicitly Acquiring Row Locks You can override default locking with a SELECT statement that includes the FOR UPDATE clause. This statement acquires exclusive row locks for selected rows (as an UPDATE statement does), in anticipation of updating the selected rows in a subsequent statement. You can use a SELECT FOR UPDATE statement to lock a row without actually changing it. For example, several triggers in Oracle Database PL/SQL Language Reference show how to implement referential integrity. In the EMP_DEPT_CHECK trigger, the row that contains the referenced parent key value is locked to guarantee that it remains for the duration of the transaction; if the parent key is updated or deleted, referential integrity is violated. SELECT FOR UPDATE statements are often used by interactive programs that enable a user to modify fields of one or more specific rows (which might take some time); row locks are acquired so that only a single interactive program user is updating the rows at any given time. If a SELECT FOR UPDATE statement is used when defining a cursor, the rows in the return set are locked when the cursor is opened (before the first fetch) rather than being locked as they are fetched from the cursor. Locks are only released when the transaction that opened the cursor is committed or rolled back, not when the cursor is closed. Each row in the return set of a SELECT FOR UPDATE statement is locked individually; the SELECT FOR UPDATE statement waits until the other transaction releases the conflicting row lock. If a SELECT FOR UPDATE statement locks many rows in a table, and if the table experiences a lot of update activity, it might be faster to acquire an EXCLUSIVE table lock instead. The return set for a SELECT FOR UPDATE statement might change while the query is running; for example, if columns selected by the query are updated or rows are deleted after the query started. When this happens, SELECT FOR UPDATE acquires locks on the rows that did not change, gets a read-consistent snapshot of the table using these locks, and then restarts the query to acquire the remaining locks. Note: If your application uses the SELECT FOR UPDATE statement and cannot guarantee that a conflicting locking request will not result in user-caused deadlocks—for example, through ensuring that concurrent DML statements on a table never affect the return set of the query of a SELECT FOR UPDATE statement—then code the application always to handle such a deadlock (ORA-00060) in an appropriate manner. By default, the SELECT FOR UPDATE statement waits until the requested row lock is acquired. To change this behavior, use the NOWAIT, WAIT, or SKIP LOCKED clause of the SELECT FOR UPDATE statement. For information about these clauses, see Oracle Database SQL Language Reference. Examples of Concurrency Under Explicit Locking Table 2–3 shows how Oracle Database maintains data concurrency, integrity, and consistency when the LOCK TABLE statement and the SELECT statement with the FOR UPDATE clause are used. For brevity, the message text for ORA-00054 ("resource busy and acquire with NOWAIT specified") is not included. User-entered text is bold. SQL Processing for Application Developers 2-15 Locking Tables Explicitly In tables compressed with Hybrid Columnar Compression (HCC), DML statements lock compression units rather than rows. HCC, a feature of certain Oracle storage systems, is described in Oracle Database Concepts. Note: Table 2–3 Examples of Concurrency Under Explicit Locking Transaction 1 LOCK TABLE hr.departments IN ROW SHARE MODE; Time Point Transaction 2 1 Statement processed. 2 DROP TABLE hr.departments; DROP TABLE hr.departments * ORA-00054 (Exclusive DDL lock not possible because Transaction 1 has table locked.) 3 LOCK TABLE hr.departments IN EXCLUSIVE MODE NOWAIT; ORA-00054 4 SELECT location_id FROM hr.departments WHERE department_id = 20 FOR UPDATE OF location_id; LOCATION_ID ----------DALLAS 1 row selected. UPDATE hr.departments SET location_id = 'NEW YORK' WHERE department_id = 20; 5 (Waits because Transaction 2 locked same rows.) 6 ROLLBACK; (Releases row locks.) 1 row processed. 7 ROLLBACK; LOCK TABLE hr.departments IN ROW EXCLUSIVE MODE; 8 Statement processed. 2-16 Oracle Database Advanced Application Developer's Guide Locking Tables Explicitly Table 2–3 (Cont.) Examples of Concurrency Under Explicit Locking Transaction 1 Time Point Transaction 2 9 LOCK TABLE hr.departments IN EXCLUSIVE MODE NOWAIT; ORA-00054 10 LOCK TABLE hr.departments IN SHARE ROW EXCLUSIVE MODE NOWAIT; ORA-00054 11 LOCK TABLE hr.departments IN SHARE ROW EXCLUSIVE MODE NOWAIT; ORA-00054 12 UPDATE hr.departments SET location_id = 'NEW YORK' WHERE department_id = 20; 1 row processed. 13 SELECT location_id FROM hr.departments WHERE department_id = 20 FOR UPDATE OF location_id; ROLLBACK; 14 LOCATION_ID ----------DALLAS 1 row selected. 15 UPDATE hr.departments SET location_id = 'NEW YORK' WHERE department_id = 20; 1 row processed. (Waits because Transaction 1 locked same rows.) ROLLBACK; 16 17 1 row processed. (Conflicting locks were released.) ROLLBACK; LOCK TABLE hr.departments IN ROW SHARE MODE 18 Statement processed. SQL Processing for Application Developers 2-17 Locking Tables Explicitly Table 2–3 (Cont.) Examples of Concurrency Under Explicit Locking Transaction 1 Time Point Transaction 2 19 LOCK TABLE hr.departments IN EXCLUSIVE MODE NOWAIT; ORA-00054 20 LOCK TABLE hr.departments IN SHARE ROW EXCLUSIVE MODE NOWAIT; ORA-00054 21 LOCK TABLE hr.departments IN SHARE MODE; Statement processed. 22 SELECT location_id FROM hr.departments WHERE department_id = 20; LOCATION_ID ----------DALLAS 1 row selected. 23 SELECT location_id FROM hr.departments WHERE department_id = 20 FOR UPDATE OF location_id; LOCATION_ID ----------DALLAS 1 row selected. 24 UPDATE hr.departments SET location_id = 'NEW YORK' WHERE department_id = 20; (Waits because Transaction 1 has conflicting table lock.) ROLLBACK; 25 26 1 row processed. (Conflicting table lock released.) ROLLBACK; LOCK TABLE hr.departments IN SHARE ROW EXCLUSIVE MODE; 27 Statement processed. 2-18 Oracle Database Advanced Application Developer's Guide Locking Tables Explicitly Table 2–3 (Cont.) Examples of Concurrency Under Explicit Locking Transaction 1 Time Point Transaction 2 28 LOCK TABLE hr.departments IN EXCLUSIVE MODE NOWAIT; ORA-00054 29 LOCK TABLE hr.departments IN SHARE ROW EXCLUSIVE MODE NOWAIT; ORA-00054 30 LOCK TABLE hr.departments IN SHARE MODE NOWAIT; ORA-00054 31 LOCK TABLE hr.departments IN ROW EXCLUSIVE MODE NOWAIT; ORA-00054 32 LOCK TABLE hr.departments IN SHARE MODE NOWAIT; ORA-00054 33 SELECT location_id FROM hr.departments WHERE department_id = 20; LOCATION_ID ----------DALLAS 1 row selected. 34 SELECT location_id FROM hr.departments WHERE department_id = 20 FOR UPDATE OF location_id; LOCATION_ID ----------DALLAS 1 row selected. 35 UPDATE hr.departments SET location_id = 'NEW YORK' WHERE department_id = 20; (Waits because Transaction 1 has conflicting table lock.) SQL Processing for Application Developers 2-19 Locking Tables Explicitly Table 2–3 (Cont.) Examples of Concurrency Under Explicit Locking Transaction 1 UPDATE hr.departments SET location_id = 'NEW YORK' WHERE department_id = 20; Time Point Transaction 2 36 (Deadlock.) (Waits because Transaction 2 locked same rows.) Cancel operation. 37 ROLLBACK; 38 LOCK TABLE hr.departments IN EXCLUSIVE MODE; 1 row processed. 39 40 LOCK TABLE hr.departments IN EXCLUSIVE MODE; ORA-00054 41 LOCK TABLE hr.departments IN ROW EXCLUSIVE MODE NOWAIT; ORA-00054 42 LOCK TABLE hr.departments IN SHARE MODE; ORA-00054 43 LOCK TABLE hr.departments IN ROW EXCLUSIVE MODE NOWAIT; ORA-00054 44 LOCK TABLE hr.departments IN ROW SHARE MODE NOWAIT; ORA-00054 45 SELECT location_id FROM hr.departments WHERE department_id = 20; LOCATION_ID ----------DALLAS 1 row selected. 2-20 Oracle Database Advanced Application Developer's Guide Locking Tables Explicitly Table 2–3 (Cont.) Examples of Concurrency Under Explicit Locking Transaction 1 Time Point Transaction 2 46 SELECT location_id FROM hr.departments WHERE department_id = 20 FOR UPDATE OF location_id; (Waits because Transaction 1 has conflicting table lock.) UPDATE hr.departments SET department_id = 30 WHERE department_id = 20; 47 1 row processed. COMMIT; 48 49 0 rows selected. (Transaction 1 released conflicting lock.) SET TRANSACTION READ ONLY; 50 SELECT location_id FROM hr.departments WHERE department_id = 10; 51 LOCATION_ID ----------BOSTON 52 UPDATE hr.departments SET location_id = 'NEW YORK' WHERE department_id = 10; 1 row processed. SELECT location_id FROM hr.departments WHERE department_id = 10; 53 LOCATION_ID ----------BOSTON (Transaction 1 does not see uncommitted data.) 54 SELECT location_id FROM hr.departments WHERE department_id = 10; COMMIT; 55 LOCATION_ID ----------BOSTON (Same result even after Transaction 2 commits.) SQL Processing for Application Developers 2-21 Using Oracle Lock Management Services (User Locks) Table 2–3 (Cont.) Examples of Concurrency Under Explicit Locking Transaction 1 Time Point Transaction 2 COMMIT; 56 SELECT location_id FROM hr.departments WHERE department_id = 10; 57 LOCATION_ID ----------NEW YORK (Sees committed data.) Using Oracle Lock Management Services (User Locks) Your applications can use Oracle Lock Management services (user locks) by invoking subprograms the DBMS_LOCK package. An application can request a lock of a specific mode, give it a unique name (recognizable in another subprogram in the same or another instance), change the lock mode, and release it. Because a reserved user lock is an Oracle Database lock, it has all the features of a database lock, such as deadlock detection. Ensure that any user locks used in distributed transactions are released upon COMMIT, otherwise an undetected deadlock can occur. See Also: Oracle Database PL/SQL Packages and Types Reference for detailed information about the DBMS_LOCK package Topics: ■ When to Use User Locks ■ Viewing and Monitoring Locks When to Use User Locks User locks can help: ■ Provide exclusive access to a device, such as a terminal ■ Provide application-level enforcement of read locks ■ Detect when a lock is released and clean up after the application ■ Synchronize applications and enforce sequential processing Example 2–2 shows how the Pro*COBOL precompiler uses locks to ensure that there are no conflicts when multiple people must access a single device. Example 2–2 How the Pro*COBOL Precompiler Uses Locks ****************************************************************** * Print Check * * Any cashier may issue a refund to a customer returning goods. * * Refunds under $50 are given in cash, more than $50 by check. * * This code prints the check. One printer is opened by all * * the cashiers to avoid the overhead of opening and closing it * * for every check, meaning that lines of output from multiple * * cashiers can become interleaved if you do not ensure exclusive * * access to the printer. The DBMS_LOCK package is used to * 2-22 Oracle Database Advanced Application Developer's Guide Using Serializable Transactions for Concurrency Control * ensure exclusive access. * ****************************************************************** CHECK-PRINT * Get the lock "handle" for the printer lock. MOVE "CHECKPRINT" TO LOCKNAME-ARR. MOVE 10 TO LOCKNAME-LEN. EXEC SQL EXECUTE BEGIN DBMS_LOCK.ALLOCATE_UNIQUE ( :LOCKNAME, :LOCKHANDLE ); END; END-EXEC. * Lock the printer in exclusive mode (default mode). EXEC SQL EXECUTE BEGIN DBMS_LOCK.REQUEST ( :LOCKHANDLE ); END; END-EXEC. * You now have exclusive use of the printer, print the check. ... * Unlock the printer so other people can use it EXEC SQL EXECUTE BEGIN DBMS_LOCK.RELEASE ( :LOCKHANDLE ); END; END-EXEC. Viewing and Monitoring Locks Table 2–4 describes the Oracle Database facilities that display locking information for ongoing transactions within an instance. Table 2–4 Ways to Display Locking Information Tool Description Oracle Enterprise Manager Database Control The Database Locks page shows user locks, all database locks, or locks that are blocking other users or applications. For more information, see Oracle Database 2 Day + Real Application Clusters Guide. Performance Monitoring Data Dictionary Views See Oracle Database Administrator's Guide. UTLLOCKT.SQL The UTLLOCKT.SQL script displays a simple character lock wait-for graph in tree structured fashion. Using any SQL tool (such as SQL*Plus) to run the script, it prints the sessions in the system that are waiting for locks and the corresponding blocking locks. The location of this script file is operating system dependent. (You must have run the CATBLOCK.SQL script before using UTLLOCKT.SQL.) Using Serializable Transactions for Concurrency Control By default, Oracle Database permits concurrently running transactions to modify, add, or delete rows in the same table, and in the same data block. When transaction A changes a table, the changes are invisible to concurrently running transactions until transaction A commits them. If transaction A tries to update or delete a row that transaction B has locked (by issuing a DML or SELECT FOR UPDATE statement), then the DML statement that A issued waits until B either commits or rolls back the transaction. This concurrency model, which provides higher concurrency and thus better performance, is appropriate for most applications. However, some rare applications require serializable transactions. Serializable transactions run concurrently in serialized mode. In serialized mode, concurrent transactions can make only the database changes that they could make if they were running serially (that is, one at a time). If a serialized transaction tries to change data SQL Processing for Application Developers 2-23 Using Serializable Transactions for Concurrency Control that another transaction changed after the serialized transaction began, then error ORA-08177 occurs. When a serializable transaction fails with ORA-08177, the application can take any of these actions: ■ ■ ■ Commit the work executed to that point. Run additional, different, statements, perhaps after rolling back to a prior savepoint in the transaction. Roll back the transaction and then rerun it. The transaction gets a transaction snapshot and the operation is likely to succeed. Tip: To minimize the performance overhead of rolling back and re running transactions, put DML statements that might conflict with concurrent transactions near the beginning of the transaction. Serializable transactions do not work with deferred segment creation or interval partitioning. Trying to insert data into an empty table with no segment created, or into a partition of an interval partitioned table that does not yet have a segment, causes an error. Note: Topics: Transaction Interaction and Isolation Level ■ ■ Setting Isolation Levels ■ Serializable Transactions and Referential Integrity ■ READ COMMITTED and SERIALIZABLE Isolation Levels Transaction Interaction and Isolation Level The ANSI/ISO SQL standard defines three kinds of transaction interaction: Transaction Interaction Definition Dirty read Transaction A reads uncommitted changes made by transaction B. Unrepeatable read Transaction A reads data, transaction B changes the data and commits the changes, and transaction A rereads the data and sees the changes. Phantom read Transaction A runs a query, transaction B inserts new rows and commits the change, and transaction A repeats the query and sees the new rows. The kinds of interactions that a transaction can have is determined by its isolation level. The ANSI/ISO SQL standard defines four transaction isolation levels. Table 2–5 shows what kind of interactions are possible at each isolation level. Table 2–5 ANSI/ISO SQL Isolation Levels and Possible Transaction Interactions Isolation Level Dirty Read Unrepeatable Read Phantom Read READ UNCOMMITTED Possible Possible Possible READ COMMITTED Not possible Possible Possible 2-24 Oracle Database Advanced Application Developer's Guide Using Serializable Transactions for Concurrency Control Table 2–5 (Cont.) ANSI/ISO SQL Isolation Levels and Possible Transaction Interactions Isolation Level Dirty Read Unrepeatable Read Phantom Read REPEATABLE READ Not possible Not possible Possible SERIALIZABLE Not possible Not possible Not possible Table 2–6 shows which ANSI/ISO SQL transaction isolation levels Oracle Database provides. Table 2–6 ANSI/ISO SQL Isolation Levels Provided by Oracle Database Isolation Level Provided by Oracle Database READ UNCOMMITTED No. Oracle Database never permits "dirty reads." Some other database products use this undesirable technique to improve thoughput, but it is not required for high throughput with Oracle Database. READ COMMITTED Yes, by default. In fact, because an Oracle Database query sees only data that was committed at the beginning of the query (the snapshot time), Oracle Database offers more consistency than the ANSI/ISO SQL standard for READ COMMITTED isolation requires. REPEATABLE READ Yes, if you set the transaction isolation level to SERIALIZABLE. SERIALIZABLE Yes, if you set the transaction isolation level to SERIALIZABLE. Figure 2–1 shows how an arbitrary transaction (that is, one that is either SERIALIZABLE or READ COMMITTED) interacts with a serializable transaction. SQL Processing for Application Developers 2-25 Using Serializable Transactions for Concurrency Control Figure 2–1 Interaction Between Serializable Transaction and Another Transaction TRANSACTION A (arbitrary) begin work update row 2 in block 1 insert row 4 Issue update "too recent" for B to see SET TRANSACTION ISOLATION LEVEL SERIALIZABLE read row 1 in block 1 Change other row in same block, see own changes update row 1 in block 1 read updated row 1 in block 1 Create possible "phantom" row Uncommitted changes invisible commit TRANSACTION B (serializable) read old row 2 in block 1 search for row 4 (notfound) Make changes visible to transactions that begin later Make changes after A commits update row 3 in block 1 B can see its own changes but not the committed changes of transaction A. re-read updated row 1 in block 1 search for row 4 (not found) read old row 2 in block 1 Failure on attempt to update row updated and committed since transaction B began update row 2 in block 1 FAILS; rollback and retry TIME Setting Isolation Levels To set the transaction isolation level for every transaction in your session, use the ALTER SESSION statement, described in Oracle Database SQL Language Reference. To set the transaction isolation level for a specific transaction, use the ISOLATION LEVEL clause of the SET TRANSACTION statement. The SET TRANSACTION statement, described in Oracle Database SQL Language Reference, must be the first statement in the transaction. Note: If you set the transaction isolation level to SERIALIZABLE, then you must use the ALTER TABLE statement to set the INITRANS parameter to at least 3. Use higher values for tables for which many transactions update the same blocks. For more information about INITRANS, see Oracle Database SQL Language Reference. 2-26 Oracle Database Advanced Application Developer's Guide Using Serializable Transactions for Concurrency Control Serializable Transactions and Referential Integrity Because Oracle Database does not use read locks, even in SERIALIZABLE transactions, data read by one transaction can be overwritten by another. Therefore, transactions that perform database consistency checks at the application level must not assume that the data they read does not change during the transaction (even though such changes are invisible to the transaction). Code your application-level consistency checks carefully, even when using SERIALIZABLE transactions. In Figure 2–2, transactions A and B (which are either READ COMMITTED or SERIALIZABLE) perform application-level checks to maintain the referential integrity of the parent/child relationship between two tables. Transaction A queries the parent table to check that it has a row with a specific primary key value before inserting corresponding child rows into the child table. Transaction B queries the child table to check that no child rows exist for a specific primary key value before deleting the corresponding parent row from the parent table. Both transactions assume (but do not ensure) that the data they read does not change before the transaction completes. Figure 2–2 Referential Integrity Check B's query does not prevent this insert TRANSACTION A TRANSACTION B read parent (it exists) read child rows (not found) insert child row(s) delete parent commit work commit work A's query does not prevent this delete The query by transaction A does not prevent transaction B from deleting the parent row, and the query by transaction B does not prevent transaction A from inserting child rows. Therefore, this can happen: 1. Transaction A queries the parent table and finds the specified parent row. 2. Transaction B queries the child table and finds no child rows for the specified parent row. 3. Having found the specified parent row, transaction A inserts the corresponding child rows into the child table. 4. Having found no child rows for the specified parent row, transaction B deletes the specified parent row from the parent table. Now the child rows that transaction A inserted in step 3 have no parent row. SQL Processing for Application Developers 2-27 Using Serializable Transactions for Concurrency Control The preceding result can occur even if both A and B are SERIALIZABLE transactions, because neither transaction prevents the other from changing the data that it reads to check consistency. Ensuring that data queried by one transaction is not concurrently changed or deleted by another requires more transaction isolation than the ANSI/ISO SQL standard SERIALIZABLE isolation level provides. However, in Oracle Database: ■ Transaction A can use a SELECT FOR UPDATE statement to query and lock the parent row, thereby preventing transaction B from deleting it. For information about the FOR UPDATE clause of the SELECT statement, see Oracle Database SQL Language Reference. ■ Transaction B can prevent transaction A from finding the parent row (thereby preventing A from inserting the child rows) by reversing the order of its processing steps. That is, transaction B can: 1. Delete the parent row. 2. Query the child table. 3. If the deleted parent row has child rows in the child table, then roll back the deletion of the parent row. Alternatively, you can enforce referential integrity with a trigger. Instead of having transaction A query the parent table, define on the child table a row-level BEFORE INSERT trigger that does this: ■ ■ Queries the parent table with a SELECT FOR UPDATE statement, thereby ensuring that if the parent row exists, then it remains in the database for the duration of the transaction that inserts the child rows. Rejects the insertion of the child rows if the parent row does not exist. Oracle Database PL/SQL Language Reference for more information about using triggers to maintain referential integrity between parent and child tables See Also: A trigger runs SQL statements in the context of the triggering statement (that is, the triggering and triggered statements see the database in the same state). Therefore, if a READ COMMITTED transaction runs the triggering statement, then the triggered statements see the database as it was when the triggering statement began to execute. If a SERIALIZABLE transaction runs the triggering statement, then the triggered statements see the database as it was at the beginning of the transaction. In either case, using SELECT FOR UPDATE in the trigger correctly enforces referential integrity. READ COMMITTED and SERIALIZABLE Isolation Levels Oracle Database provides two transaction isolation levels, READ COMMITTED and SERIALIZABLE. Both levels provide a high degree of consistency and concurrency, reduce contention, and are designed for real-world applications. This topic compares them and explains how to choose between them. Topics: Transaction Set Consistency Differences ■ ■ Choosing Transaction Isolation Levels 2-28 Oracle Database Advanced Application Developer's Guide Using Serializable Transactions for Concurrency Control Transaction Set Consistency Differences An operation (query or transaction) is transaction set consistent if all of its read operations return data written by the same set of committed transactions. When an operation is not transaction set consistent, some of its read operations reflect the changes of one set of transactions and others reflect the changes of other sets of transactions; that is, the operation sees the database in a state that reflects no single set of committed transactions. Topics: ■ Oracle Database ■ Other Database Systems Oracle Database Oracle Database transactions with READ COMMITTED isolation level are transaction set consistent on an individual-statement basis, because all rows that a query reads must be committed before the query begins. Oracle Database transactions with SERIALIZABLE isolation level are transaction set consistent on an individual-transaction basis, because all statements in a SERIALIZABLE transaction run on an image of the database as it was at the beginning of the transaction. Other Database Systems In other database systems, a single query with READ UNCOMMITTED isolation level is not transaction set consistent, because it might see only a subset of the changes made by another transaction. For example, a join of a master table with a detail table can see a master record inserted by another transaction, but not the corresponding details inserted by that transaction (or the reverse). READ COMMITTED isolation level avoids this problem, providing more consistency than read-locking systems do. In read-locking systems, at the cost of preventing concurrent updates, the REPEATABLE READ isolation level provides transaction set consistency at the statement level, but not at the transaction level. Due to the absence of phantom read protection, two queries in the same transaction can see data committed by different sets of transactions. In these systems, only the throughput-limiting and deadlock-susceptible SERIALIZABLE isolation level provides transaction set consistency at the transaction level. Choosing Transaction Isolation Levels The choice of transaction isolation level depends on performance and consistency needs and application coding requirements. There is a trade-off between concurrency (transaction throughput) and consistency. Consider the application and workload when choosing isolation levels for its transactions. Different transactions can have different isolation levels. For environments with many concurrent users rapidly submitting transactions, consider expected transaction arrival rate, response time demands, and required degree of consistency. READ COMMITTED isolation can provide considerably more concurrency with a somewhat increased risk of inconsistent results (from unrepeatable and phantom reads) for some transactions. SERIALIZABLE isolation provides somewhat more consistency (by protecting against phantoms and unrepeatable reads), which might be important where a read/write transaction runs a query more than once. However, SERIALIZABLE isolation requires applications to check for the "cannot serialize access" error, and this checking can SQL Processing for Application Developers 2-29 Autonomous Transactions significantly reduce throughput in an environment with many concurrent transactions accessing the same data for update. As explained in "Serializable Transactions and Referential Integrity" on page 2-27 reads do not block writes in either READ COMMITTED or SERIALIZABLE transactions. Table 2–7 summarizes the similarities and differences between READ COMMITTED and SERIALIZABLE transactions. Table 2–7 Comparison of READ COMMITTED and SERIALIZABLE Transactions Operation READ COMMITTED SERIALIZABLE Dirty write Not Possible Not Possible Dirty read Not Possible Not Possible Unrepeatable read Possible Not Possible Phantom read Possible Not Possible Compliant with ANSI/ISO SQL 92 Yes Yes Read snapshot time Statement Transaction Transaction set consistency Statement level Transaction level Row-level locking Yes Yes Readers block writers No No Writers block readers No No Different-row writers block writers No No Same-row writers block writers Yes Yes Waits for blocking transaction Yes Yes Subject to "cannot serialize access" error No Yes Error after blocking transaction terminates No No Error after blocking transaction commits No Yes Autonomous Transactions An autonomous transaction (AT) is an independent transaction started by another transaction, the main transaction (MT). An autonomous transaction lets you suspend the main transaction, do SQL operations, commit or roll back those operations, and then resume the main transaction. For example, in a stock purchase transaction, you might want to commit customer information regardless of whether the purchase succeeds. Or, you might want to log error messages to a debug table even if the transaction rolls back. Autonomous transactions enable you to do such tasks. An autonomous transaction runs within an autonomous scope; that is, within the scope of an autonomous routine—a routine that you mark with the AUTONOMOUS_ TRANSACTION pragma. For the definition of routine in this context, see Oracle Database PL/SQL Language Reference. Figure 2–3 shows how control flows from the main transaction (MT) to an autonomous transaction (AT) and back again. As you can see, the autonomous transaction can commit multiple transactions (AT1 and AT2) before control returns to the main transaction. 2-30 Oracle Database Advanced Application Developer's Guide Autonomous Transactions Figure 2–3 Transaction Control Flow Main Transaction Autonomous Transaction PROCEDURE proc1 IS emp_id NUMBER; BEGIN emp_id := 7788; INSERT ... SELECT ... proc2; DELETE ... COMMIT; END; PROCEDURE proc2 IS PRAGMA AUTON... dept_id NUMBER; BEGIN dept_id := 20; UPDATE ... INSERT ... UPDATE ... COMMIT; INSERT ... INSERT ... COMMIT; END; MT begins MT ends MT suspends AT1 begins AT1 ends AT2 begins AT2 ends MT resumes When you enter the executable section of an autonomous transaction, the main transaction suspends. When you exit the transaction, the main transaction resumes. COMMIT and ROLLBACK end the active autonomous transaction but do not exit the autonomous transaction. As Figure 2–3 shows, when one transaction ends, the next SQL statement begins another transaction. More characteristics of autonomous transactions: ■ ■ ■ The changes an autonomous transaction effects do not depend on the state or the eventual disposition of the main transaction. For example: – An autonomous transaction does not see changes made by the main transaction. – When an autonomous transaction commits or rolls back, it does not affect the outcome of the main transaction. The changes an autonomous transaction effects are visible to other transactions as soon as that autonomous transaction commits. Therefore, users can access the updated information without having to wait for the main transaction to commit. Autonomous transactions can start other autonomous transactions. Figure 2–4 shows some possible sequences that autonomous transactions can follow. SQL Processing for Application Developers 2-31 Autonomous Transactions Figure 2–4 Possible Sequences of Autonomous Transactions A main transaction scope (MT Scope) begins the main transaction, MTx. MTx invokes the first autonomous transaction scope (AT Scope1). MTx suspends. AT Scope 1 begins the transaction Tx1.1. At Scope 1 commits or rolls back Tx1.1, than ends. MTx resumes. MT Scope AT Scope 1 AT Scope 2 AT Scope 3 AT Scope 4 MTx Tx1.1 MTx MTx invokes AT Scope 2. MT suspends, passing control to AT Scope 2 which, initially, is performing queries. AT Scope 2 then begins Tx2.1 by, say, doing an update. AT Scope 2 commits or rolls back Tx2.1. Tx2.1 Later, AT Scope 2 begins a second transaction, Tx2.2, then commits or rolls it back. Tx2.2 AT Scope 2 performs a few queries, then ends, passing control back to MTx. MTx MTx invokes AT Scope 3. MTx suspends, AT Scope 3 begins. Tx3.1 AT Scope 3 begins Tx3.1 which, in turn, invokes AT Scope 4. Tx3.1 suspends, AT Scope 4 begins. Tx4.1 AT Scope 4 begins Tx4.1, commits or rolls it back, then ends. AT Scope 3 resumes. AT Scope 3 commits or rolls back Tx3.1, then ends. MTx resumes. Tx3.1 Finally, MT Scope commits or rolls back MTx, then ends. MTx Topics: ■ Examples of Autonomous Transactions ■ Defining Autonomous Transactions Oracle Database PL/SQL Language Reference for detailed information about autonomous transactions See Also: Examples of Autonomous Transactions ■ Ordering a Product ■ Withdrawing Money from a Bank Account As these examples show, there are four possible outcomes when you use autonomous and main transactions (see Table 2–8). There is no dependency between the outcome of an autonomous transaction and that of a main transaction. 2-32 Oracle Database Advanced Application Developer's Guide Autonomous Transactions Table 2–8 Possible Transaction Outcomes Autonomous Transaction Main Transaction Commits Commits Commits Rolls back Rolls back Commits Rolls back Rolls back Ordering a Product Figure 2–5 shows an example of a customer ordering a product. The customer information (such as name, address, phone) is committed to a customer information table—even though the sale does not go through. Figure 2–5 Example: A Buy Order MT Scope begins the main transaction, MTx inserts the buy order into a table. MT Scope AT Scope MTx invokes the autonomous transaction scope (AT Scope). When AT Scope begins, MT Scope suspends. ATx ATx, updates the audit table with customer information. MTx seeks to validate the order, finds that the selected item is unavailable, and therefore rolls back the main transaction. MTx Withdrawing Money from a Bank Account In this example, a customer tries to withdraw money from a bank account. In the process, a main transaction invokes one of two autonomous transaction scopes (AT Scope 1 or AT Scope 2). The possible scenarios for this transaction are: ■ Scenario 1: Sufficient Funds ■ Scenario 2: Insufficient Funds with Overdraft Protection ■ Scenario 3: Insufficient Funds Without Overdraft Protection Scenario 1: Sufficient Funds There are sufficient funds to cover the withdrawal, so the bank releases the funds (see Figure 2–6). SQL Processing for Application Developers 2-33 Autonomous Transactions Figure 2–6 Bank Withdrawal—Sufficient Funds MTx generates a transaction ID. MT Scope AT Scope 1 AT Scope 2 MTx Tx1.1 inserts the transaction ID into the audit table and commits. MTx validates the balance on the account. Tx1.1 MTx Tx2.1, updates the audit table using the transaction ID generated above, then commits. MTx releases the funds. MT Scope ends. Tx2.1 MTx Scenario 2: Insufficient Funds with Overdraft Protection There are insufficient funds to cover the withdrawal, but the customer has overdraft protection, so the bank releases the funds (see Figure 2–7). 2-34 Oracle Database Advanced Application Developer's Guide Autonomous Transactions Figure 2–7 Bank Withdrawal—Insufficient Funds with Overdraft Protection MT Scope AT Scope 1 AT Scope 2 MTx Tx1.1 MTx discovers that there are insufficient funds to cover the withdrawal. It finds that the customer has overdraft protection and sets a flag to the appropriate value. MTx Tx2.1, updates the audit table. MTx, releases the funds. MT Scope ends. Tx2.1 MTx Scenario 3: Insufficient Funds Without Overdraft Protection There are insufficient funds to cover the withdrawal and the customer does not have overdraft protection, so the bank withholds the requested funds (see Figure 2–8). SQL Processing for Application Developers 2-35 Autonomous Transactions Figure 2–8 Bank Withdrawal—Insufficient Funds Without Overdraft Protection MT Scope AT Scope 1 AT Scope 2 MTx Tx1.1 MTx discovers that there are insufficient funds to cover the withdrawal. It finds that the customer does not have overdraft protection and sets a flag to the appropriate value. MTx Tx2.1, updates the audit table. MTx Scope rolls back MTx, denying the release of funds. MT Scope ends. Tx2.1 MTx Defining Autonomous Transactions To define an autonomous transaction, use PRAGMA AUTONOMOUS_TRANSACTION, which instructs the PL/SQL compiler to mark the subprogram as autonomous. In Example 2–3, the function balance is autonomous. Example 2–3 Marking a Package Subprogram as Autonomous -- Create table for package to use: DROP TABLE accounts; CREATE TABLE accounts (account INTEGER, balance REAL); -- Create package: CREATE OR REPLACE PACKAGE banking AS FUNCTION balance (acct_id INTEGER) RETURN REAL; -- Additional functions and packages END banking; / CREATE OR REPLACE PACKAGE BODY banking AS FUNCTION balance (acct_id INTEGER) RETURN REAL IS PRAGMA AUTONOMOUS_TRANSACTION; my_bal REAL; BEGIN SELECT balance INTO my_bal FROM accounts WHERE account=acct_id; RETURN my_bal; END; -- Additional functions and packages END banking; 2-36 Oracle Database Advanced Application Developer's Guide Resuming Execution After Storage Allocation Errors / Oracle Database PL/SQL Language Reference for more information about PRAGMA AUTONOMOUS_TRANSACTION See Also: Resuming Execution After Storage Allocation Errors When a long-running transaction is interrupted by a storage allocation error, the application can suspend the statement that encountered the problem, correct the problem, and then resume executing the statement. This capability, called resumable storage allocation, avoids time-consuming rollbacks. It also makes it unnecessary to split the operation into smaller pieces and write code to track its progress. See Also: Oracle Database Administrator's Guide for more information about resumable storage allocation Topics: ■ What Operations Have Resumable Storage Allocation? ■ Handling Suspended Storage Allocation What Operations Have Resumable Storage Allocation? Queries, DML statements, and some DDL statements have resumable storage allocation after these kinds of errors: ■ Out-of-space errors, such as ORA-01653. ■ Space-limit errors, such as ORA-01628. ■ Space-quota errors, such as ORA-01536. Resumable storage allocation is possible whether the operation is performed directly by a SQL statement or within SQL*Loader, a stored subprogram, an anonymous PL/SQL block, or an OCI call such as OCIStmtExecute. In dictionary-managed tablespaces, you cannot resume an index- or table-creating operation that encounters the limit for rollback segments or the maximum number of extents. You must use locally managed tablespaces and automatic undo management in combination with resumable storage allocation. Handling Suspended Storage Allocation When a statement in an application is suspended because of a storage allocation error, the application does not receive an error code. Therefore, either the application must use an AFTER SUSPEND trigger or the DBA must periodically check for suspended statements. After the problem is corrected (usually by the DBA), the suspended statement automatically resumes execution. If the timeout period expires before the problem is corrected, then the statement raises a SERVERERROR exception. Topics: ■ Using an AFTER SUSPEND Trigger in the Application ■ Checking for Suspended Statements SQL Processing for Application Developers 2-37 Resuming Execution After Storage Allocation Errors Using an AFTER SUSPEND Trigger in the Application In the application, an AFTER SUSPEND trigger can get information about the problem by invoking subprograms in the DBMS_RESUMABLE package (described in Oracle Database PL/SQL Packages and Types Reference). Then the trigger can send the information to an operator, using email (for example). To reduce the chance of out-of-space errors within the trigger itself, declare the trigger as an autonomous transaction. As an autonomous transaction, the trigger uses a rollback segment in the SYSTEM tablespace. If the trigger encounters a deadlock condition because of locks held by the suspended statement, then the trigger terminates and the application receives the original error code, as if the statement were never suspended. If the trigger encounters an out-of-space condition, then both the trigger and the suspended statement are rolled back. To prevent rollback, use an exception handler in the trigger to wait for the statement to resume. For general information about triggers, see Oracle Database PL/SQL Language Reference. The trigger in Example 2–4 handles storage errors within the database. For some kinds of errors, the trigger terminates the statement and alerts the DBA, using e-mail. For other errors, which might be temporary, the trigger specifies that the statement waits for eight hours before resuming, expecting the storage problem to be fixed by then. To run this example, you must connect to the database as SYSDBA. Example 2–4 AFTER SUSPEND Trigger Handles Suspended Storage Allocation -- Create table used by trigger body DROP TABLE rbs_error; CREATE TABLE rbs_error ( SQL_TEXT VARCHAR2(64), ERROR_MSG VARCHAR2(64), SUSPEND_TIME VARCHAR2(64) ); -- Resumable Storage Allocation CREATE OR REPLACE TRIGGER suspend_example AFTER SUSPEND ON DATABASE DECLARE cur_sid NUMBER; cur_inst NUMBER; err_type VARCHAR2(64); object_owner VARCHAR2(64); object_type VARCHAR2(64); table_space_name VARCHAR2(64); object_name VARCHAR2(64); sub_object_name VARCHAR2(64); msg_body VARCHAR2(64); ret_value BOOLEAN; error_txt VARCHAR2(64); mail_conn UTL_SMTP.CONNECTION; BEGIN SELECT DISTINCT(SID) INTO cur_sid FROM V$MYSTAT; cur_inst := USERENV('instance'); ret_value := DBMS_RESUMABLE.SPACE_ERROR_INFO (err_type, object_owner, object_type, table_space_name, 2-38 Oracle Database Advanced Application Developer's Guide Resuming Execution After Storage Allocation Errors object_name, sub_object_name); IF object_type = 'ROLLBACK SEGMENT' THEN INSERT INTO rbs_error (SELECT SQL_TEXT, ERROR_MSG, SUSPEND_TIME FROM DBA_RESUMABLE WHERE SESSION_ID = cur_sid AND INSTANCE_ID = cur_inst); SELECT ERROR_MSG INTO error_txt FROM DBA_RESUMABLE WHERE SESSION_ID = cur_sid AND INSTANCE_ID = cur_inst; msg_body := 'Space error occurred: Space limit reached for rollback segment ' || object_name || ' on ' || to_char(SYSDATE, 'Month dd, YYYY, HH:MIam') || '. Error message was: ' || error_txt; mail_conn := UTL_SMTP.OPEN_CONNECTION('localhost', 25); UTL_SMTP.HELO(mail_conn, 'localhost'); UTL_SMTP.MAIL(mail_conn, 'sender@localhost'); UTL_SMTP.RCPT(mail_conn, 'recipient@localhost'); UTL_SMTP.DATA(mail_conn, msg_body); UTL_SMTP.QUIT(mail_conn); DBMS_RESUMABLE.ABORT(cur_sid); ELSE DBMS_RESUMABLE.SET_TIMEOUT(3600*8); END IF; COMMIT; END; / Checking for Suspended Statements If the application does not use an AFTER SUSPEND trigger, then the DBA must periodically check for suspended statements, using the static data dictionary view DBA_RESUMABLE (described in Oracle Database Reference). The DBA can get additional information from the dynamic performance view V$_ SESSION_WAIT (described in Oracle Database Reference). SQL Processing for Application Developers 2-39 Resuming Execution After Storage Allocation Errors 2-40 Oracle Database Advanced Application Developer's Guide 3 Using Regular Expressions in Database Applications 3 This chapter describes regular expressions and explains how to use them in database applications. Topics: ■ Overview of Regular Expressions ■ Oracle SQL Support for Regular Expressions ■ Oracle SQL and POSIX Regular Expression Standard ■ Operators in Oracle SQL Regular Expressions ■ Using Regular Expressions in SQL Statements: Scenarios See Also: ■ ■ ■ Oracle Database Globalization Support Guide for information about using SQL regular expression functions in a multilingual environment Oracle Regular Expressions Pocket Reference by Jonathan Gennick, O'Reilly & Associates Mastering Regular Expressions by Jeffrey E. F. Friedl, O'Reilly & Associates Overview of Regular Expressions A regular expression specifies a search pattern, using metacharacters (which are, or belong to, operators) and character literals (described in Oracle Database SQL Language Reference). The search pattern can be complex. For example, this regular expression matches any string that begins with either f or ht, followed by tp, optionally followed by s, followed by the colon (:): (f|ht)tps?: The metacharacters (which are also operators) in the preceding example are the parentheses, the pipe symbol (|), and the question mark (?). The character literals are f, ht, tp, s, and the colon (:). Parentheses group multiple pattern elements into a single element. The pipe symbol (|) indicates a choice between the elements on either side of it, f and ht. The question Using Regular Expressions in Database Applications 3-1 Oracle SQL Support for Regular Expressions mark (?) indicates that the preceding element, s, is optional. Thus, the preceding regular expression matches these strings: ■ http: ■ https: ■ ftp: ■ ftps: Regular expressions are a powerful text-processing component of the programming languages Java and PERL. For example, a PERL script can read the contents of each HTML file in a directory into a single string variable and then use a regular expression to search that string for URLs. This robust pattern-matching functionality is one reason that many application developers use PERL. Oracle SQL Support for Regular Expressions Oracle SQL support for regular expressions lets application developers implement complex pattern-matching logic in the database, which is useful for these reasons: ■ By centralizing pattern-matching logic in the database, you avoid intensive string processing of SQL results sets by middle-tier applications. For example, life science customers often rely on PERL to do pattern analysis on bioinformatics data stored in huge databases of DNA and proteins. Previously, finding a match for a protein sequence such as [AG].{4}GK[ST] was handled in the middle tier. The SQL regular expression functions move the processing logic closer to the data, thereby providing a more efficient solution. ■ By using server-side regular expressions to enforce constraints, you avoid duplicating validation logic on multiple clients. Oracle SQL supports regular expressions with the pattern-matching condition and functions summarized in Table 3–1. Each pattern matcher searches a given string for a given pattern (described with a regular expression), and each has the pattern-matching options described in Table 3–2. The functions have additional options (for example, the character position at which to start searching the string for the pattern). For details, see Oracle Database SQL Language Reference. Table 3–1 Oracle SQL Pattern-Matching Condition and Functions Name Description REGEXP_LIKE Condition that can appear in the WHERE clause of a query, causing the query to return rows that match the given pattern. Example: This WHERE clause identifies employees with the first name of Steven or Stephen: WHERE REGEXP_LIKE((hr.employees.first_name, '^Ste(v|ph)en$') REGEXP_COUNT Function that returns the number of times the given pattern appears in the given string. Example: This function invocation returns the number of times that e (but not E) appears in the string 'Albert Einstein', starting at character position 7: REGEXP_COUNT('Albert Einstein', 'e', 7, 'c') (The returned value is 1, because the c option specifies case-sensitive matching.) 3-2 Oracle Database Advanced Application Developer's Guide Oracle SQL Support for Regular Expressions Table 3–1 (Cont.) Oracle SQL Pattern-Matching Condition and Functions Name Description REGEXP_INSTR Function that returns an integer that indicates the starting position of the given pattern in the given string. Alternatively, the integer can indicate the position immediately following the end of the pattern. Example: This function invocation returns the starting position of the first valid email address in the column hr.employees.email: REGEXP_INSTR(hr.employees.email, '\w+@\w+(\.\w+)+') If the returned value is greater than zero, then the column contains a valid email address. REGEXP_REPLACE Function that returns the string that results from replacing occurrences of the given pattern in the given string with a replacement string. Example: This function invocation puts a space after each character in the column hr.countries.country_name: REGEXP_REPLACE(hr.countries.country_name, '(.)', '\1 ') REGEXP_SUBSTR Function that is like REGEXP_INSTR except that instead of returning the starting position of the given pattern in the given string, it returns the matching substring itself. Example: This function invocation returns ’Oracle’ because the x option ignores the spaces in the pattern: REGEXP_SUBSTR('Oracle 2010', 'O r a c l e', 1, 1, 'x') Table 3–2 describes the pattern-matching options that are available to each pattern matcher in Table 3–1. Table 3–2 Pattern-Matching Options for Oracle SQL Pattern-Matching Condition and Functions Option Description Example i Specifies case-insensitive matching. This function invocation returns 3: REGEXP_COUNT('Albert Einstein', 'e', 'i') c Specifies case-sensitive matching. This function invocation returns 2: REGEXP_COUNT('Albert Einstein', 'e', 'c') n m Allows the Dot operator (.) to match the newline character, which is not the default (see Table 3–3). Specifies multiline mode, where a newline character inside a string terminates a line. The string can contain multiple lines. In this function invocation, the string and search pattern match only because the n option is specified: REGEXP_SUBSTR('a'||CHR(10)||'d', 'a.d', 1, 1, 'n') This function invocation returns ac: REGEXP_SUBSTR('ab'||CHR(10)||'ac', '^a.', 1, 2, 'm') Multiline mode affects POSIX operators Beginning-of-Line Anchor (^) and End-of-Line Anchor ($) (described in Table 3–3) but not PERL-influenced operators \A, \Z, and \z (described in Table 3–5). x Ignores whitespace characters in the search pattern. By default, whitespace characters match themselves. This function invocation returns abcd: REGEXP_SUBSTR('abcd', 'a b c d', 1, 1, 'x') Using Regular Expressions in Database Applications 3-3 Oracle SQL and POSIX Regular Expression Standard Oracle SQL and POSIX Regular Expression Standard Oracle SQL implementation of regular expressions conforms to these standards: ■ IEEE Portable Operating System Interface (POSIX) standard draft 1003.2/D11.2 Oracle SQL follows exactly the syntax and matching semantics for regular expression operators as defined in the POSIX standard for matching ASCII (English language) data. You can find the POSIX standard draft at this URL: http://www.opengroup.org/onlinepubs/007908799/xbd/re.html For more information, see "POSIX Operators in Oracle SQL Regular Expressions" on page 3-4. ■ Unicode Regular Expression Guidelines of the Unicode Consortium Oracle SQL extends regular expression support beyond the POSIX standard in these ways: ■ Extends the matching capabilities for multilingual data For details, see "Oracle SQL Multilingual Extensions to POSIX Standard" on page 3-7. ■ Supports some commonly used PERL regular expression operators that are not included in the POSIX standard but do not conflict with it (for example, character class shortcuts and the nongreedy modifier (?)) For details, see "Oracle SQL PERL-Influenced Extensions to POSIX Standard" on page 3-7. Operators in Oracle SQL Regular Expressions Oracle SQL supports a set of common operators (composed of metacharacters) used in regular expressions. Caution: The interpretation of metacharacters differs between tools that support regular expressions. If you are porting regular expressions from another environment to Oracle Database, ensure that Oracle SQL supports their syntax and interprets them as you expect. Topics: ■ POSIX Operators in Oracle SQL Regular Expressions ■ Oracle SQL Multilingual Extensions to POSIX Standard ■ Oracle SQL PERL-Influenced Extensions to POSIX Standard POSIX Operators in Oracle SQL Regular Expressions Table 3–3 summarizes the POSIX operators defined in the POSIX standard Extended Regular Expression (ERE) syntax. Oracle SQL follows the exact syntax and matching semantics for these operators as defined in the POSIX standard for matching ASCII (English language) data. Any differences in action between Oracle SQL and the POSIX standard are noted in the Description column. 3-4 Oracle Database Advanced Application Developer's Guide Operators in Oracle SQL Regular Expressions Table 3–3 POSIX Operators in Oracle SQL Regular Expressions Operator Syntax Names . Any Character Dot Description Examples Matches any character in the database character set, The expression a.b matches the including the newline character if you specify strings abb, acb, and adb, but does matching option n (see Table 3–2). not match acc. The Linux, UNIX, and Windows platforms recognize the newline character as the linefeed character (\x0a). The Macintosh platforms recognize the newline character as the carriage return character (\x0d). Note: In the POSIX standard, this operator matches any English character except NULL and the newline character. + One or More Plus Quantifier * Zero or More Star Quantifier ? Zero or One Question Mark Quantifier {m} Interval Exact Count {m,} Interval At-Least Count {m,n} Interval Between Count [char...] Matching Character List Matches one or more occurrences of the preceding subexpression (greedy1). The expression a+ matches the strings a, aa, and aaa, but does not match ba or ab. Matches zero or more occurrences of the preceding subexpression (greedy1). The expression ab*c matches the strings ac, abc, and abbc, but does not match abb or bbc. Matches zero or one occurrences of the preceding subexpression (greedy1). The expression ab?c matches the strings abc and ac, but does not match abbc or adc. Matches exactly m occurrences of the preceding subexpression. The expression a{3} matches the string aaa, but does not match aa. Matches at least m occurrences of the preceding subexpression (greedy1). The expression a{3,} matches the strings aaa and aaaa, but does not match aa. Matches at least m but not more than n occurrences of the preceding subexpression (greedy1). The expression a{3,5} matches the strings aaa, aaaa, and aaaaa, but does not match aa or aaaaaa. Matches any single character in the list within the brackets. In the list, all operators except these are treated as literals: The expression [abc] matches the first character in the strings all, bill, and cold, but does not match any characters in doll. ■ Range operator: - ■ POSIX character class: [: :] ■ POSIX collation element: [. .] ■ POSIX character equivalence class: [= =] A dash (-) is a literal when it occurs first or last in the list, or as an ending range point in a range expression, as in [#--]. A right bracket (]) is treated as a literal if it occurs first in the list. Note: In the POSIX standard, a range includes all collation elements between the start and end of the range in the linguistic definition of the current locale. Thus, ranges are linguistic rather than byte value ranges; the semantics of the range expression are independent of the character set. In Oracle Database, the linguistic range is determined by the NLS_SORT initialization parameter. [^char...] Nonmatching Character List Matches any single character not in the list within the brackets. For information about operators and ranges in the character list, see the description of the Matching Character List operator. [alt1 |alt2] Or Matches either alternative. The expression [^abc]def matches the string xdef, but not adef, bdef, or cdef. The expression [^a-i]x matches the string jx, but does not match ax, fx, or ix. The expression a|b matches the character a or b. Using Regular Expressions in Database Applications 3-5 Operators in Oracle SQL Regular Expressions Table 3–3 (Cont.) POSIX Operators in Oracle SQL Regular Expressions Operator Syntax Names (expr) Subexpression Grouping Description Examples Treats the expression within the parentheses as a unit. The expression can be a string or a complex expression containing operators. The expression (abc)?def matches the strings abcdef and def, but does not match abcdefg or xdef. You can refer to a subexpression in a back reference. Back Reference \n Matches the nth preceding subexpression, where n is an integer from 1 through 9. A back reference counts subexpressions from left to right, starting with the opening parenthesis of each preceding subexpression. The expression is invalid if fewer than n subexpressions precede \n. A back reference lets you search for a repeated string without knowing what it is. The expression (abc|def)xy\1 matches the strings abcxyabc and defxydef, but does not match abcxydef or abcxy. The expression ^(.*)\1$ matches a line consisting of two adjacent instances of the same string. For the REGEXP_REPLACE function, Oracle SQL supports back references in both the regular expression pattern and the replacement string. Escape Character \ Treats the subsequent character as a literal. A backslash (\) lets you search for a character that would otherwise be treated as a metacharacter. Use consecutive backslashes (\\) to match the backslash literal itself. ^ $ [:class:] Beginning-of-Line Anchor Default mode: Matches the beginning of a string. End-of-Line Anchor Default mode: Matches the end of a string. POSIX Character Class Matches any character in the specified POSIX character class (such as uppercase characters, digits, or punctuation characters). 2 Multiline mode: Matches the beginning of any line the source string. 2 Multiline mode: Matches the end of any line the source string. Note: In English regular expressions, range expressions often indicate a character class. For example, [a-z] indicates any lowercase character. This convention is not useful in multilingual environments, where the first and last character of a given character class might not be the same in all languages. [.element.] POSIX Collating Element Operator Specifies a collating element defined in the current locale. The NLS_SORT initialization parameter determines the supported collation elements. This syntax lets you use a multicharacter collating element where otherwise only single-character collating elements are allowed. For example, you can ensure that the collating element ch, when defined in a locale such as Traditional Spanish, is treated as one character in operations that depend on the ordering of characters. [=char=] POSIX Character Equivalence Class Matches all characters that belong to the same POSIX character equivalence class as the specified character, in the current locale. This syntax must appear within a character list; that is, it must be nested within the brackets for a character list. The expression abc\+def matches the string abc+def, but does not match abcdef or abccdef. The expression ^def matches the substring def in the string defghi but not in the string abcdef. The expression def$ matches the substring def in the string abcdef but not in the string defghi. The expression [:upper:]+, which specifies one or more consecutive uppercase characters, matches the substring DEF in the string abcDEFghi, but does not match any substring in abcdefghi. The expression [.ch.], which specifies the collating element ch, matches ch in the string chabc, but does not match any substring in cdefg. The expression [a-[.ch.]] specifies the range from a through ch. The expression [[=n=]], which specifies characters equivalent to n in a Spanish locale, matches both N and ñ in the string El Niño. Character equivalents depend on how canonical rules are defined for your database locale. For details, see Oracle Database Globalization Support Guide. 1 A greedy operator matches as many occurrences as possible while allowing the rest of the match to succeed. To make the operator nongreedy, follow it with the nongreedy modifier (?) (see Table 3–5). 3-6 Oracle Database Advanced Application Developer's Guide Operators in Oracle SQL Regular Expressions 2 Specify multiline mode with the pattern-matching option m, described in Table 3–2. Oracle SQL Multilingual Extensions to POSIX Standard When applied to multilingual data, Oracle SQL POSIX operators extend beyond the matching capabilities specified in the POSIX standard. Table 3–4 shows, for each POSIX operator, which POSIX standards define its syntax and whether Oracle SQL extends its semantics for handling multilingual data. The POSIX standards are Basic Regular Expression (BRE) and Extended Regular Expression (ERE). Table 3–4 POSIX Operators and Multilingual Operator Relationships Operator POSIX BRE Syntax POSIX ERE Syntax Multilingual Enhancement \ Yes Yes -- * Yes Yes -- + -- Yes -- ? -- Yes -- | -- Yes -- ^ Yes Yes Yes $ Yes Yes Yes . Yes Yes Yes [ ] Yes Yes Yes ( ) Yes Yes -- {m} Yes Yes -- {m,} Yes Yes -- {m,n} Yes Yes -- \n Yes Yes Yes [..] Yes Yes Yes [::] Yes Yes Yes [==] Yes Yes Yes Multilingual data might have multibyte characters. Oracle Database lets you enter multibyte characters directly (if you have a direct input method) or use functions to compose them. You cannot use the Unicode hexadecimal encoding value of the form \xxxx. Oracle Database evaluates the characters based on the byte values used to encode the character, not the graphical representation of the character. Oracle SQL PERL-Influenced Extensions to POSIX Standard Oracle SQL supports some commonly used PERL regular expression operators that are not included in the POSIX standard but do not conflict with it. Table 3–5 summarizes the PERL-influenced operators that Oracle SQL supports. Using Regular Expressions in Database Applications 3-7 Operators in Oracle SQL Regular Expressions Caution: PERL character class matching is based on the locale model of the operating system, whereas Oracle SQL regular expressions are based on the language-specific data of the database. In general, you cannot expect a regular expression involving locale data to produce the same results in PERL and Oracle SQL. Table 3–5 PERL-Influenced Operators in Oracle SQL Regular Expressions Operator Syntax Description Examples \d Matches a digit character. The expression ^\(\d{3}\) \d{3}-\d{4}$ matches (650) 555-0100 but does not match 650-555-0100. Equivalent to POSIX expression [[:digit:]]. \D Matches a nondigit character. Equivalent to POSIX expression [^[:digit:]]. \w Matches a word character (that is, an alphanumeric or underscore (_) character). Equivalent to POSIX expression [[:alnum:]_ ]. \W Matches a nonword character. Equivalent to POSIX expression [^[:alnum:]_]. \s Matches a whitespace character. Equivalent to POSIX expression [[:space:]]. \S Matches a nonwhitespace character. Equivalent to POSIX expression [^[:space:]]. \A Matches the beginning of a string, in either single-line or multiline mode. Not equivalent to POSIX operator ^. \Z Matches the end of a string, in either single-line or multiline mode. Not equivalent to POSIX operator $. \z Matches the end of a string, in either single-line or multiline mode. Not equivalent to POSIX operator $. The expression \w\d\D matches b2b and b2_ but does not match b22. The expression \w+@\w+(\.\w+)+ matches the string jdoe@company.co.uk but does not match jdoe@company. The expression \w+\W\s\w+ matches the string to: bill but does not match to bill. The expression \(\w\s\w\s\) matches the string (a b ) but does not match (ab) or (a,b.). The expression \(\w\S\w\S\) matches the strings (abde) and (a,b.) but does not match (a b d e). The expression \AL matches only the first L in the string Line1\nLine2\n (where \n is the newline character), in either single-line or multiline mode. The expression \s\Z matches the last space in the string L i n e \n (where \n is the newline character), in either single-line or multiline mode. The expression \s\z matches the newline character (\n) in the string L i n e \n, in either single-line or multiline mode. The expression \w+?x\w matches abxc in the string abxcxd (and the greedy expression \w+x\w matches abxcxd). +? Matches one or more occurrences of the preceding subexpression (nongreedy1). *? The expression \w*?x\w matches xa in the string Matches zero or more occurrences of the xaxbxc (and the greedy expression \w*x\w matches preceding subexpression (nongreedy1). Matches the empty string whenever possible. xaxbxc. ?? Matches zero or one occurrences of the The expression a??aa matches aa in the string aaaa (and the greedy expression a?aa matches aaa). preceding subexpression (nongreedy1). Matches the empty string whenever possible. 3-8 Oracle Database Advanced Application Developer's Guide Using Regular Expressions in SQL Statements: Scenarios Table 3–5 (Cont.) PERL-Influenced Operators in Oracle SQL Regular Expressions Operator Syntax {m}? Description Examples Matches exactly m occurrences of the preceding subexpression (nongreedy1). The expression (a|aa){2}? matches aa in the string aaaa (and the greedy expression (a|aa){2} matches aaaa. Both the expression b{2}? and the greedy expression b{2} match bb in the string bbbb. {m,}? Matches at least m occurrences of the preceding subexpression (nongreedy1). The expression a{2,}? matches aa in the string aaaaa (and the greedy expression a{2,} matches aaaaa. {m,n}? Matches at least m but not more than n occurrences of the preceding subexpression (nongreedy1). {0,n}? matches the empty string whenever possible. The expression a{2,4}? matches aa in the string aaaaa (and the greedy expression a{2,4} matches aaaa. 1 A nongreedy operator matches as few occurrences as possible while allowing the rest of the match to succeed. To make the operator greedy, omit the nongreedy modifier (?). Using Regular Expressions in SQL Statements: Scenarios Scenarios: ■ Using a Constraint to Enforce a Phone Number Format ■ Using Back References to Reposition Characters Using a Constraint to Enforce a Phone Number Format Regular expressions are useful for enforcing constraints—for example, to ensure that phone numbers are entered into the database in a standard format. Example 3–1 creates a contacts table and adds a CHECK constraint to the p_number column to enforce this format model: (XXX) XXX-XXXX Example 3–1 Enforcing a Phone Number Format with Regular Expressions DROP TABLE contacts; CREATE TABLE contacts ( l_name VARCHAR2(30), p_number VARCHAR2(30) CONSTRAINT c_contacts_pnf CHECK (REGEXP_LIKE (p_number, '^\(\d{3}\) \d{3}-\d{4}$')) ); Table 3–6 explains the elements of the regular expression. Table 3–6 Explanation of the Regular Expression Elements in Example 3–1 Regular Expression Element Matches . . . ^ The beginning of the string. \( A left parenthesis. The backslash (\) is an escape character that indicates that the left parenthesis after it is a literal rather than a subexpression delimiter. \d{3} Exactly three digits. Using Regular Expressions in Database Applications 3-9 Using Regular Expressions in SQL Statements: Scenarios Table 3–6 (Cont.) Explanation of the Regular Expression Elements in Example 3–1 Regular Expression Element Matches . . . \) A right parenthesis. The backslash (\) is an escape character that indicates that the right parenthesis after it is a literal rather than a subexpression delimiter. space character A space character. \d{3} Exactly three digits. - A hyphen. \d{4} Exactly four digits. $ The end of the string. Example 3–2 shows some statements that correctly and incorrectly insert phone numbers into the contacts table. Example 3–2 Inserting Phone Numbers in Correct and Incorrect Formats These are correct: INSERT INTO contacts (p_number) VALUES('(650) 555-0100'); INSERT INTO contacts (p_number) VALUES('(215) 555-0100'); These generate CHECK constraint errors: INSERT INSERT INSERT INSERT INSERT INTO INTO INTO INTO INTO contacts contacts contacts contacts contacts (p_number) (p_number) (p_number) (p_number) (p_number) VALUES('650 555-0100'); VALUES('650 555 0100'); VALUES('650-555-0100'); VALUES('(650)555-0100'); VALUES(' (650) 555-0100'); Using Back References to Reposition Characters A back reference (described in Table 3–3) stores the referenced subexpression in a temporary buffer. Therefore, you can use back references to reposition characters, as in Example 3–3. For an explanation of the elements of the regular expression in Example 3–3, see Table 3–7. Example 3–3 Using Back References to Reposition Characters Create table and populate it with names in different formats: DROP TABLE famous_people; CREATE TABLE famous_people (names INSERT INTO famous_people (names) INSERT INTO famous_people (names) INSERT INTO famous_people (names) INSERT INTO famous_people (names) INSERT INTO famous_people (names) VARCHAR2(20)); VALUES ('John Quincy Adams'); VALUES ('Harry S. Truman'); VALUES ('John Adams'); VALUES (' John Quincy Adams'); VALUES ('John_Quincy_Adams'); SQL*Plus formatting command: COLUMN "names after regexp" FORMAT A20 For each name in the table whose format is "first middle last", use back references to reposition characters so that the format becomes "last, first middle": 3-10 Oracle Database Advanced Application Developer's Guide Using Regular Expressions in SQL Statements: Scenarios SELECT names "names", REGEXP_REPLACE(names, '^(\S+)\s(\S+)\s(\S+)$', '\3, \1 \2') AS "names after regexp" FROM famous_people ORDER BY "names"; Result: names -------------------John Quincy Adams Harry S. Truman John Adams John Quincy Adams John_Quincy_Adams names after regexp -------------------John Quincy Adams Truman, Harry S. John Adams Adams, John Quincy John_Quincy_Adams 5 rows selected. Table 3–7 explains the elements of the regular expression. Table 3–7 Explanation of the Regular Expression Elements in Example 3–3 Regular Expression Element Description ^ Matches the beginning of the string. $ Matches the end of the string. (\S+) Matches one or more nonspace characters. The parentheses are not escaped so they function as a grouping expression. \s Matches a whitespace character. \1 Substitutes the first subexpression, that is, the first group of parentheses in the matching pattern. \2 Substitutes the second subexpression, that is, the second group of parentheses in the matching pattern. \3 Substitutes the third subexpression, that is, the third group of parentheses in the matching pattern. , Inserts a comma character. Using Regular Expressions in Database Applications 3-11 Using Regular Expressions in SQL Statements: Scenarios 3-12 Oracle Database Advanced Application Developer's Guide 4 Using Indexes in Database Applications 4 Indexes are optional structures, associated with tables and clusters, which allow SQL queries to execute more quickly. Just as the index in this document helps you locate information faster than if there were no index, an Oracle Database index provides a faster access path to table data. You can use indexes without rewriting any queries. Your results are the same, but you see them more quickly. This chapter supplements this information: ■ The explanation of indexes and index-organized tables in Oracle Database Concepts ■ The information about managing indexes in Oracle Database Administrator's Guide ■ The explanation of how indexes and clusters can enhance or degrade performance in Oracle Database Performance Tuning Guide Topics: Guidelines for Managing Indexes ■ ■ Managing Indexes ■ When to Use Domain Indexes ■ When to Use Function-Based Indexes Guidelines for Managing Indexes Here is a summary of the guidelines for managing indexes. For details, see Oracle Database Administrator's Guide: ■ Create indexes after inserting table data ■ Index the correct tables and columns ■ Order index columns for performance ■ Limit the number of indexes for each table ■ Drop indexes that are no longer needed ■ Understand deferred segment creation ■ Estimate index size and set storage parameters ■ Specify the tablespace for each index ■ Consider parallelizing index creation ■ Consider creating indexes with NOLOGGING ■ Understand when to use unusable or invisible indexes Using Indexes in Database Applications 4-1 Managing Indexes ■ Consider costs and benefits of coalescing or rebuilding indexes ■ Consider cost before disabling or dropping constraints Managing Indexes Oracle Database Administrator's Guide has this information about managing indexes: ■ Creating indexes ■ Altering indexes ■ Monitoring space use of indexes ■ Dropping indexes ■ Data dictionary views that display information about indexes See Also: "Creating Indexes for Use with Constraints" on page 5-4 When to Use Domain Indexes A domain index (also called an application domain index) is a customized index specific to an application that was implemented using a data cartridge (for example, a search engine or geographic information system). For information about domain indexes, see Oracle Database Concepts. See Also: Oracle Database Data Cartridge Developer's Guide for conceptual background to help you decide when to build domain indexes When to Use Function-Based Indexes A function-based index computes the value of an expression that involves one or more columns and stores it in the index. The index expression can be an arithmetic expression or an expression that contains a SQL function, PL/SQL function, package function, or C callout. Function-based indexes also support linguistic sorts based on collation keys, efficient linguistic collation of SQL statements, and case-insensitive sorts. A function-based index improves the performance of queries that use the index expression (especially if the expression is computationally intensive). However: ■ ■ The database must also evaluate the index expression to process statements that do not use it. Function-based indexes on columns that are frequently modified are expensive for the database to maintain. The optimizer can use function-based indexes only for cost-based optimization, while it can use indexes on columns for both cost-based and rule-based optimization. 4-2 Oracle Database Advanced Application Developer's Guide When to Use Function-Based Indexes Note: ■ ■ A function-based index cannot contain the value NULL. Therefore, either ensure that no column involved in the index expression can contain NULL or use the NVL function in the index expression to substitute another value for NULL. (For information about NVL, see Oracle Database SQL Language Reference.) Oracle Database treats descending indexes as if they were function-based indexes (for more information, see Oracle Database SQL Language Reference). Topics: ■ Advantages of Function-Based Indexes ■ Disadvantages of Function-Based Indexes ■ Examples of Function-Based Indexes See Also: ■ ■ ■ ■ ■ Oracle Database Concepts for additional conceptual information about function-based indexes Oracle Database Administrator's Guide for information about creating function-based indexes Oracle Database Globalization Support Guide for information about function-based linguistic indexes Oracle Database Concepts for more information about how the optimizer uses function-based indexes Oracle Database Performance Tuning Guide for information about using function-based indexes for performance Advantages of Function-Based Indexes A function-based index has these advantages: ■ A function-based index increases the number of situations where the database can perform an index range scan (described in Oracle Database Concepts) instead of a full index scan (described in Oracle Database Concepts). An index range scan typically has a fast response time when the WHERE clause selects fewer than 15% of the rows of a large table. The optimizer can more accurately estimate how many rows an expression selects if the expression is materialized in a function-based index. Oracle Database represents the index expression as a virtual column, on which the ANALYZE statement (described in Oracle Database SQL Language Reference) can build a histogram. ■ A function-based index precomputes and stores the value of an expression. Queries can get the value of the expression from the index instead of computing it. The more queries that need the value, and the more computationally intensive the index expression, the more the index improves application performance. (See Example 4–1.) ■ You can create a function-based index on an object column or REF column. Using Indexes in Database Applications 4-3 When to Use Function-Based Indexes The index expression can be the invocation of a method that returns an object type. For more information, see Oracle Database Object-Relational Developer's Guide. (See Example 4–2 and the example in Oracle Database SQL Language Reference.) ■ A function-based index lets you perform more powerful sorts. The index expression can invoke the SQL functions UPPER and LOWER for case-insensitive sorts (as in Example 4–3) and the SQL function NLSSORT for linguistic-based sorts (as in Example 4–4). Disadvantages of Function-Based Indexes A function-based index has these disadvantages: ■ The optimizer can use a function-based index only for cost-based optimization, not for rule-based optimization. The cost-based optimizer uses statistics stored in the dictionary. To gather statistics for a function-based index, invoke either DBMS_STATS.GATHER_TABLE_STATS (described in Oracle Database PL/SQL Packages and Types Reference) or DBMS_ STATS.GATHER_SCHEMA_STATS (described in Oracle Database PL/SQL Packages and Types Reference). ■ The database does not use a function-based index until you analyze the index itself and the table on which it is defined. To analyze the index and the table on which the index is defined, invoke either DBMS_STATS.GATHER_TABLE_STATS or DBMS_STATS.GATHER_SCHEMA_STATS. ■ ■ The database does not use function-based indexes when doing OR expansion. You must ensure that any schema-level or package-level PL/SQL function that the index expression invokes is deterministic (that is, that the function always return the same result for the same input). You must declare the function as DETERMINISTIC, but because Oracle Database does not check this assertion, you must ensure that the function really is deterministic. If you change the semantics of a DETERMINISTIC function and recompile it, then you must manually rebuild any dependent function-based indexes and materialized views. Otherwise, they report results for the prior version of the function. ■ If the index expression is a function invocation, then the function return type cannot be constrained. Because you cannot constrain the function return type with NOT NULL, you must ensure that the query that uses the index cannot fetch NULL values. Otherwise, the database performs a full table scan. ■ ■ ■ The index expression cannot invoke an aggregate function (described in Oracle Database SQL Language Reference). A bitmapped function-based index cannot be a descending index (see Oracle Database SQL Language Reference). The data type of the index expression cannot be VARCHAR2, RAW, LONGRAW, or a PL/SQL data type of unknown length. That is, you cannot index an expression of unknown length. However, you can index a known-length substring of that expression. For example: CREATE OR REPLACE FUNCTION initials ( 4-4 Oracle Database Advanced Application Developer's Guide When to Use Function-Based Indexes name IN VARCHAR2 ) RETURN VARCHAR2 DETERMINISTIC IS BEGIN RETURN('A. J.'); END; / /* Invoke SUBSTR both when creating index and when referencing function in queries. */ CREATE INDEX func_substr_index ON EMPLOYEES(SUBSTR(initials(FIRST_NAME),1,10)); SELECT SUBSTR(initials(FIRST_NAME),1,10) FROM EMPLOYEES; See Also: ■ ■ ■ Oracle Database SQL Language Reference for notes on function-based indexes Oracle Database SQL Language Reference for restrictions on function-based indexes Oracle Database PL/SQL Language Reference for information about the CREATE FUNCTION statement, including restrictions Examples of Function-Based Indexes Examples: ■ Example 4–1, "Function-Based Index for Precomputing Arithmetic Expression" ■ Example 4–2, "Function-Based Indexes on Object Column" ■ Example 4–3, "Function-Based Index for Faster Case-Insensitive Searches" ■ Example 4–4, "Function-Based Index for Language-Dependent Sorting" Example 4–1 and Example 4–2 use composite indexes (indexes on multiple table columns), described in Oracle Database Concepts. Note: Example 4–1 creates a table with columns a, b, and c; creates an index on the table, and then queries the table. The index is a composite index on three columns: a virtual column that represents the expression a+b*(c-1), column a, and column b. The query uses the indexed expression in its WHERE clause; therefore, it can use an index range scan instead of a full index scan. Example 4–1 Function-Based Index for Precomputing Arithmetic Expression Create table on which to create index: DROP TABLE Fbi_tab; CREATE TABLE Fbi_tab ( a INTEGER, b INTEGER, c INTEGER ); Using Indexes in Database Applications 4-5 When to Use Function-Based Indexes Create index: CREATE INDEX Idx ON Fbi_tab (a+b*(c-1), a, b); This query can use an index range scan instead of a full index scan: SELECT a FROM Fbi_tab WHERE a+b*(c-1) < 100; See Also: Oracle Database Concepts for information about fast full index scans In Example 4–2, assume that the object type Reg_obj has been defined, and that it stores information about a city. The example creates a table whose first column has type Reg_obj, a deterministic function with a parameter of type Reg_obj, and two function-based indexes that invoke the function. The first query uses the first index to quickly find cities further than 1000 miles from the equator. The second query uses the second index (which is composite) to quickly find cities where the temperature delta is less than 20 and the maximum temperature is greater than 75. (The table is not populated for the example, so the queries return no rows.) Example 4–2 Function-Based Indexes on Object Column Create table with object column: DROP TABLE Weatherdata_tab; CREATE TABLE Weatherdata_tab ( Reg_obj INTEGER, Maxtemp INTEGER, Mintemp INTEGER ); Create deterministic function with parameter of type Reg_obj: CREATE OR REPLACE FUNCTION Distance_from_equator ( Reg_obj IN INTEGER ) RETURN INTEGER DETERMINISTIC IS BEGIN RETURN(3000); END; / Create first function-based index: CREATE INDEX Distance_index ON Weatherdata_tab (Distance_from_equator (Reg_obj)); Use index expression in query: SELECT * FROM Weatherdata_tab WHERE (Distance_from_equator (Reg_Obj)) > '1000'; Result: no rows selected Create second function-based (and composite) index: CREATE INDEX Compare_index ON Weatherdata_tab ((Maxtemp - Mintemp) DESC, Maxtemp); 4-6 Oracle Database Advanced Application Developer's Guide When to Use Function-Based Indexes Use index expression and indexed column in query: SELECT * FROM Weatherdata_tab WHERE ((Maxtemp - Mintemp) < '20' AND Maxtemp > '75'); Result: no rows selected Example 4–3 creates an index that allows faster case-insensitive searches in the EMPLOYEES table and then uses the index expression in a query. Example 4–3 Function-Based Index for Faster Case-Insensitive Searches Create index: CREATE INDEX emp_lastname ON EMPLOYEES (UPPER(LAST_NAME)); Use index expression in query: SELECT first_name, last_name FROM EMPLOYEES WHERE UPPER(LAST_NAME) LIKE 'J%S_N'; Result: FIRST_NAME LAST_NAME -------------------- ------------------------Charles Johnson 1 row selected. Example 4–4 creates a table with one column, NAME, and a function-based index to sort that column using the collation sequence GERMAN, and then selects all columns of the table, ordering them by NAME. Because the query can use the index, the query is faster. (Assume that the query is run in a German session, where NLS_SORT is set to GERMAN and NLS_COMP is set to ANSI. Otherwise, the query would have to specify the values of these Globalization Support parameters.) Example 4–4 Function-Based Index for Language-Dependent Sorting Create table on which to create index: DROP TABLE nls_tab; CREATE TABLE nls_tab (NAME VARCHAR2(80)); Create index: CREATE INDEX nls_index ON nls_tab (NLSSORT(NAME, 'NLS_SORT = GERMAN')); Select all table columns, ordered by NAME: SELECT * FROM nls_tab WHERE NAME IS NOT NULL ORDER BY NAME; Using Indexes in Database Applications 4-7 When to Use Function-Based Indexes 4-8 Oracle Database Advanced Application Developer's Guide 5 Maintaining Data Integrity in Database Applications 5 In a database application, maintaining data integrity means ensuring that the data in the tables that the application manipulates conform to the appropriate business rules. A business rule specifies a condition or relationship that must always be true or must always be false. For example, a business rule might be that no employee can have a salary over $100,000 or that every employee in the EMPLOYEES table must belong to a department in the DEPARTMENTS table. Business rules vary from company to company, because each company defines its own policies about salaries, employee numbers, inventory tracking, and so on. As explained in Oracle Database Concepts, there are several ways to ensure data integrity, and the one to use whenever possible is the integrity constraint (or constraint). This chapter supplements this information: ■ ■ ■ The explanation of data integrity and constraints in Oracle Database Concepts The information about managing constraints in Oracle Database Administrator's Guide The syntactic and semantic information about constraints in Oracle Database SQL Language Reference This chapter applies to only to constraints on tables. Constraints on views do not help maintain data integrity or have associated indexes. Instead, they enable query rewrites on queries involving views, thereby improving performance when using materialized views and other data warehousing features. Note: For more information about constraints on views, see Oracle Database SQL Language Reference. For information about using constraints in data warehouses, see Oracle Database Data Warehousing Guide. Topics: ■ Enforcing Business Rules with Constraints ■ Enforcing Business Rules with Both Constraints and Application Code ■ Creating Indexes for Use with Constraints ■ When to Use NOT NULL Constraints Maintaining Data Integrity in Database Applications 5-1 Enforcing Business Rules with Constraints ■ When to Use Default Column Values ■ Choosing a Primary Key for a Table (PRIMARY KEY Constraint) ■ When to Use UNIQUE Constraints ■ Enforcing Referential Integrity with FOREIGN KEY Constraints ■ Minimizing Space and Time Overhead for Indexes Associated with Constraints ■ Guidelines for Indexing Foreign Keys ■ Referential Integrity in a Distributed Database ■ When to Use CHECK Constraints ■ Examples of Defining Constraints ■ Enabling and Disabling Constraints ■ Modifying Constraints ■ Renaming Constraints ■ Dropping Constraints ■ Managing FOREIGN KEY Constraints ■ Viewing Information About Constraints Enforcing Business Rules with Constraints Whenever possible, enforce business rules with constraints. In addition to the advantages explained in Oracle Database Concepts, constraints have the advantage of speed: Oracle Database can check that all the data in a table obeys a constraint faster than application code can do the equivalent checking. Example 5–1 creates a table of departments, a table of employees, a constraint to enforce the rule that all values in the department table are unique, and a constraint to enforce the rule that every employee must work for a valid department. Example 5–1 Enforcing Business Rules with Constraints Create table of departments: DROP TABLE dept_tab; CREATE TABLE dept_tab ( deptname VARCHAR2(20), deptno INTEGER ); Create table of employees: DROP TABLE emp_tab; CREATE TABLE emp_tab ( empname VARCHAR2(80), empno INTEGER, deptno INTEGER ); Create constraint to enforce rule that all values in department table are unique: ALTER TABLE dept_tab ADD PRIMARY KEY (deptno); Create constraint to enforce rule that every employee must work for a valid department: 5-2 Oracle Database Advanced Application Developer's Guide Enforcing Business Rules with Both Constraints and Application Code ALTER TABLE emp_tab ADD FOREIGN KEY (deptno) REFERENCES dept_tab(deptno); Now, whenever you insert an employee record into emp_tab, Oracle Database checks that its deptno value appears in dept_tab. Suppose that instead of using a constraint to enforce the rule that every employee must work for a valid department, you use a trigger that queries dept_tab to check that it contains the deptno value of the employee record to be inserted into emp_tab. Because the query uses consistent read (CR), it might miss uncommitted changes from other transactions. For more information about using triggers to enforce business rules, see Oracle Database Concepts. See Also: Oracle Database SQL Language Reference for syntactic and semantic information about constraints Enforcing Business Rules with Both Constraints and Application Code Enforcing business rules with both constraints and application code is recommended when application code can determine that data values are invalid without querying tables. The application code can provide immediate feedback to the user and reduce the load on the database by preventing attempts to insert invalid data into tables. For Example 5–2, assume that Example 5–1 was run and then this column was added to the table emp_tab: empgender VARCHAR2(1) The only valid values for empgender are 'M' and 'F'. When someone tries to insert a row into emp_tab or update the value of emp_tab.empgender, application code can determine whether the new value for emp_tab.empgender is valid without querying a table. If the value is invalid, the application code can notify the user instead of trying to insert the invalid value, as in Example 5–2. Example 5–2 Enforcing Business Rules with Both Constraints and Application Code CREATE OR REPLACE PROCEDURE add_employee ( e_name emp_tab.empname%TYPE, e_gender emp_tab.empgender%TYPE, e_number emp_tab.empno%TYPE, e_dept emp_tab.deptno%TYPE ) AUTHID DEFINER IS BEGIN IF UPPER(e_gender) IN ('M','F') THEN INSERT INTO emp_tab VALUES (e_name, e_gender, e_number, e_dept); ELSE DBMS_OUTPUT.PUT_LINE('Gender must be M or F.'); END IF; END; / BEGIN add_employee ('Smith', 'H', 356, 20); END; / Result: Gender must be M or F. Maintaining Data Integrity in Database Applications 5-3 Creating Indexes for Use with Constraints Creating Indexes for Use with Constraints When a unique or primary key constraint is enabled, Oracle Database creates an index automatically, but Oracle recommends that you create these indexes explicitly. If you want to use an index with a foreign key constraint, then you must create the index explicitly. For information about creating indexes explicitly, see Oracle Database Administrator's Guide or Oracle Database SQL Language Reference. When a constraint can use an existing index, Oracle Database does not create an index for that constraint. Note that: ■ ■ ■ ■ A unique or primary key constraint can use either a unique index, an entire nonunique index, or the first few columns of a nonunique index. If a unique or primary key constraint uses a nonunique index, then no other unique or primary key constraint can use that nonunique index. The column order in the constraint and index need not match. The object number of the index used by a unique or primary key constraint is stored in CDEF$.ENABLED for that constraint. No static data dictionary view or dynamic performance view shows this information. If an enabled unique or primary key constraint is using an index, you cannot drop only the index. To drop the index, you must either drop the constraint itself or disable the constraint and then drop the index. For information about disabling and dropping constraints, see Oracle Database Administrator's Guide. See Also: ■ ■ Oracle Database Administrator's Guide for more information about indexes associated with constraints Chapter 4, "Using Indexes in Database Applications" When to Use NOT NULL Constraints By default, a column can contain a NULL value. To ensure that the column never contains a NULL value, use the NOT NULL constraint (described in Oracle Database SQL Language Reference). Use a NOT NULL constraint in both of these situations: ■ A column must contain a non-NULL value. For example, in the table HR.EMPLOYEES, each employee must have an employee ID. Therefore, the column HR.EMPLOYEES.EMPLOYEE_ID has a NOT NULL constraint, and nobody can insert a new employee record into HR.EMPLOYEES without specifying a non-NULL value for EMPLOYEE_ID. You can insert a new employee record into HR.EMPLOYEES without specifying a salary; therefore, the column HR.EMPLOYEES.SALARY does not have a NOT NULL constraint. ■ You want to allow index scans of the table, or allow an operation that requires indexing all rows. Oracle Database indexes do not store keys whose values are all NULL. Therefore, for the preceding kinds of operations, at least one indexed column must have a NOT NULL constraint. Example 5–3 uses the SQL*Plus command DESCRIBE to show which columns of the DEPARTMENTS table have NOT NULL constraints, and then shows what happens if you try to insert NULL values in columns that have NOT NULL constraints. 5-4 Oracle Database Advanced Application Developer's Guide When to Use Default Column Values Example 5–3 Inserting NULL Values into Columns with NOT NULL Constraints DESCRIBE DEPARTMENTS; Result: Name Null? Type ----------------------------------------- -------- -----------DEPARTMENT_ID DEPARTMENT_NAME MANAGER_ID LOCATION_ID NOT NULL NUMBER(4) NOT NULL VARCHAR2(30) NUMBER(6) NUMBER(4) Try to insert NULL into DEPARTMENT_ID column: INSERT INTO DEPARTMENTS ( DEPARTMENT_ID, DEPARTMENT_NAME, MANAGER_ID, LOCATION_ID ) VALUES (NULL, 'Sales', 200, 1700); Result: VALUES (NULL, 'Sales', 200, 1700) * ERROR at line 4: ORA-01400: cannot insert NULL into ("HR"."DEPARTMENTS"."DEPARTMENT_ID") Omitting a value for a column that cannot be NULL is the same as assigning it the value NULL: INSERT INTO DEPARTMENTS ( DEPARTMENT_NAME, MANAGER_ID, LOCATION_ID ) VALUES ('Sales', 200, 1700); Result: INSERT INTO DEPARTMENTS ( * ERROR at line 1: ORA-01400: cannot insert NULL into ("HR"."DEPARTMENTS"."DEPARTMENT_ID") You can prevent the preceding error by giving DEPARTMENT_ID a non-NULL default value. For more information, see "When to Use Default Column Values" on page 5-5. You can combine NOT NULL constraints with other constraints to further restrict the values allowed in specific columns. For example, the combination of NOT NULL and UNIQUE constraints forces the input of values in the UNIQUE key, eliminating the possibility that data in a new conflicts with data in an existing row. For more information, see "UNIQUE and NOT NULL Constraints on the Foreign Key" on page 5-11. When to Use Default Column Values When an INSERT statement (described in Oracle Database SQL Language Reference) does not specify a value for a specific column, that column receives its default value. By default, that default value is NULL. You can change the default value when you define the column (with the CREATE TABLE statement, described in Oracle Database SQL Language Reference) or when you alter the column (with the ALTER TABLE statement, described in Oracle Database SQL Language Reference). Maintaining Data Integrity in Database Applications 5-5 Choosing a Primary Key for a Table (PRIMARY KEY Constraint) Note: Giving a column a non-NULL default value does not ensure that the value of the column will never have the value NULL, as the NOT NULL constraint does. For information about the NOT NULL constraint, see "When to Use NOT NULL Constraints" on page 5-4. Use a default column value in these situations: ■ The column has a NOT NULL constraint. Giving the column a non-NULL default value prevents the error that would occur if someone inserted a row without specifying a value for the column. ■ There is a most common value for the column. For example, if most departments in the company are in New York, then set the default value of the column DEPARTMENTS.LOCATION to 'NEW YORK'. ■ There is a non-NULL value that signifies no entry. For example, if the value zero in the column EMPLOYEES.SALARY means that the salary has not yet been determined, then set the default value of that column to zero. A default column value that signifies no entry can simplify testing. For example, it lets you change this test: IF (employees.salary IS NOT NULL) AND (employees.salary < 50000) To this test: IF employees.salary < 50000 ■ You want to automatically record the names of users who modify a table. For example, suppose that you allow users to insert rows into a table through a view. You give the base table a column named inserter (which need not be included in the definition of the view), to store the name of the user who inserted the row. To record the user name automatically, define a default value that invokes the USER function. For example: CREATE TABLE audit_trail ( value1 NUMBER, value2 VARCHAR2(32), inserter VARCHAR2(30) DEFAULT USER); Choosing a Primary Key for a Table (PRIMARY KEY Constraint) The primary key of a table uniquely identifies each row and ensures that no duplicate rows exist (and typically, this is its only purpose). Therefore, a primary key value cannot be NULL. A table can have at most one primary key, but that key can have multiple columns (that is, it can be a composite key). To designate a primary key, use the PRIMARY KEY constraint. Whenever practical, choose as the primary key a single column whose values are generated by a sequence. For information about sequences, see Oracle Database SQL Language Reference. The second-best choice for a primary key is a single column whose values are all of the following: 5-6 Oracle Database Advanced Application Developer's Guide When to Use UNIQUE Constraints ■ Unique ■ Never changed ■ Never NULL ■ Short and numeric (and therefore easy to type) Minimize your use of composite primary keys, whose values are long and cannot be generated by a sequence. See Also: Oracle Database Concepts for general information about primary key constraints ■ Oracle Database SQL Language Reference for complete information about primary key constraints, including restrictions ■ When to Use UNIQUE Constraints Use a UNIQUE constraint (which designates a unique key) on any column or combination of columns (except the primary key) where duplicate non-NULL values are not allowed. For example: Unique Key Primary Key Employee Social Security Number Employee number Truck license plate number Truck number Customer phone number (country code column, area code column, and local phone number column) Customer number Department name column and location column Department number Figure 5–1 shows a table with a UNIQUE constraint, a row that violates the constraint, and a row that satisfies it. Figure 5–1 Rows That Violate and Satisfy a UNIQUE Constraint Table DEPARTMENTS DEPID DNAME LOC 10 20 30 40 Administration Marketing Purchasing Human Resources 1700 1800 1700 2400 UNIQUE Key Constraint (no row may duplicate a value in the constraint's column) INSERT INTO 50 60 MARKETING 1700 This row violates the UNIQUE key constraint, because "MARKETING" is already present in another row; therefore, it is not allowed in the table. 2400 This row is allowed because a null value is entered for the DNAME column; however, if a NOT NULL constraint is also defined on the DNAME column, this row is not allowed. Maintaining Data Integrity in Database Applications 5-7 Enforcing Referential Integrity with FOREIGN KEY Constraints See Also: ■ ■ Oracle Database Concepts for general information about UNIQUE constraints Oracle Database SQL Language Reference for complete information about UNIQUE constraints, including restrictions Enforcing Referential Integrity with FOREIGN KEY Constraints When two tables share one or more columns, you use can use a FOREIGN KEY constraint to enforce referential integrity—that is, to ensure that the shared columns always have the same values in both tables. Note: A FOREIGN KEY constraint is also called a referential integrity constraint, and its CONSTRAINT_TYPE is R in the static data dictionary views *_CONSTRAINTS. Designate one table as the referenced or parent table and the other as the dependent or child table. In the parent table, define either a PRIMARY KEY or UNIQUE constraint on the shared columns. In the child table, define a FOREIGN KEY constraint on the shared columns. The shared columns now comprise a foreign key. Defining additional constraints on the foreign key affects the parent-child relationship—for details, see "Defining Relationships Between Parent and Child Tables" on page 5-10. Figure 5–2 shows a foreign key defined on the department number. It guarantees that every value in this column must match a value in the primary key of the department table. This constraint prevents erroneous department numbers from getting into the employee table. Figure 5–2 shows parent and child tables that share one column, a row that violates the FOREIGN KEY constraint, and a row that satisfies it. 5-8 Oracle Database Advanced Application Developer's Guide Enforcing Referential Integrity with FOREIGN KEY Constraints Figure 5–2 Rows That Violate and Satisfy a FOREIGN KEY Constraint Parent Key Primary key of referenced table Table DEPARTMENTS DEPID DNAME LOC 10 20 30 40 Administration Marketing Purchasing Human Resources 1700 1800 1700 2400 Foreign Key (values in dependent table must match a value in unique key or primary key of referenced table) Referenced or Parent Table Table EMPLOYEES ID LNAME JOB MGR HIREDATE 100 101 102 103 King Kochhar De Hann Hunold AD_PRES AD_VP AD_VP IT_PROG 100 100 102 17–JUN–87 21–SEP–89 13–JAN–93 03–JAN–90 SAL COMM DEPTNO 24000 17000 17000 9000 90 90 90 60 25 Dependent or Child Table INSERT INTO 556 CRICKET PU_CLERK 31–OCT–96 5000 556 CRICKET PU_CLERK 31–OCT–96 5000 This row violates the referential constraint because "25" is not present in the referenced table's primary key; therefore, the row is not allowed in the table. This row is allowed in the table because a null value is entered in the DEPTNO column; however, if a not null constraint is also defined for this column, this row is not allowed. Topics: ■ FOREIGN KEY Constraints and NULL Values ■ Defining Relationships Between Parent and Child Tables ■ Rules for Multiple FOREIGN KEY Constraints ■ Deferring Constraint Checks See Also: ■ ■ Oracle Database Concepts for general information about foreign key constraints Oracle Database SQL Language Reference for complete information about foreign key constraints, including restrictions Maintaining Data Integrity in Database Applications 5-9 Enforcing Referential Integrity with FOREIGN KEY Constraints FOREIGN KEY Constraints and NULL Values Foreign keys allow key values that are all NULL, even if there are no matching PRIMARY or UNIQUE keys. ■ ■ By default (without any NOT NULL or CHECK clauses), the FOREIGN KEY constraint enforces the match none rule for composite foreign keys in the ANSI/ISO standard. To enforce the match full rule for NULL values in composite foreign keys, which requires that all components of the key be NULL or all be non-null, define a CHECK constraint that allows only all nulls or all non-nulls in the composite foreign key. For example, with a composite key comprised of columns A, B, and C: CHECK ((A IS NULL AND B IS NULL AND C IS NULL) OR (A IS NOT NULL AND B IS NOT NULL AND C IS NOT NULL)) ■ In general, it is not possible to use declarative referential integrity to enforce the match partial rule for NULL values in composite foreign keys, which requires the non-null portions of the key to appear in the corresponding portions in the primary or unique key of a single row in the referenced table. You can often use triggers to handle this case, as described in Oracle Database PL/SQL Language Reference. Defining Relationships Between Parent and Child Tables Several relationships between parent and child tables can be determined by the other types of constraints defined on the foreign key in the child table. When no other constraints are defined on the foreign key, any number of rows in the child table can reference the same parent key value. This model allows nulls in the foreign key. No Constraints on the Foreign Key This model establishes a one-to-many relationship between the parent and foreign keys that allows undetermined values (nulls) in the foreign key. An example of such a relationship is shown in Figure 5–2 between the employee and department tables. Each department (parent key) has many employees (foreign key), and some employees might not be in a department (nulls in the foreign key). When nulls are not allowed in a foreign key, each row in the child table must explicitly reference a value in the parent key because nulls are not allowed in the foreign key. NOT NULL Constraint on the Foreign Key Any number of rows in the child table can reference the same parent key value, so this model establishes a one-to-many relationship between the parent and foreign keys. However, each row in the child table must have a reference to a parent key value; the absence of a value (a null) in the foreign key is not allowed. The same example in the previous section illustrates such a relationship. However, in this case, employees must have a reference to a specific department. When a UNIQUE constraint is defined on the foreign key, only one row in the child table can reference a given parent key value. This model allows nulls in the foreign key. UNIQUE Constraint on the Foreign Key This model establishes a one-to-one relationship between the parent and foreign keys that allows undetermined values (nulls) in the foreign key. For example, assume that the employee table had a column named MEMBERNO, referring to an employee membership number in the company insurance plan. Also, a table named INSURANCE has a primary key named MEMBERNO, and other columns of the table keep respective 5-10 Oracle Database Advanced Application Developer's Guide Enforcing Referential Integrity with FOREIGN KEY Constraints information relating to an employee insurance policy. The MEMBERNO in the employee table must be both a foreign key and a unique key: ■ ■ To enforce referential integrity rules between the EMP_TAB and INSURANCE tables (the FOREIGN KEY constraint) To guarantee that each employee has a unique membership number (the UNIQUE key constraint) UNIQUE and NOT NULL Constraints on the Foreign Key When both UNIQUE and NOT NULL constraints are defined on the foreign key, only one row in the child table can reference a given parent key value, and because NULL values are not allowed in the foreign key, each row in the child table must explicitly reference a value in the parent key. This model establishes a one-to-one relationship between the parent and foreign keys that does not allow undetermined values (nulls) in the foreign key. If you expand the previous example by adding a NOT NULL constraint on the MEMBERNO column of the employee table, in addition to guaranteeing that each employee has a unique membership number, you also ensure that no undetermined values (nulls) are allowed in the MEMBERNO column of the employee table. Rules for Multiple FOREIGN KEY Constraints Oracle Database allows a column to be referenced by multiple FOREIGN KEY constraints; there is no limit on the number of dependent keys. This situation might be present if a single column is part of two different composite foreign keys. Deferring Constraint Checks When Oracle Database checks a constraint, it signals an error if the constraint is not satisfied. To defer checking constraints until the end of the current transaction, use the SET CONSTRAINTS statement. Note: You cannot use the SET CONSTRAINTS statement inside a trigger. When deferring constraint checks: ■ Select appropriate data. You might want to defer constraint checks on UNIQUE and FOREIGN keys if the data you are working with has any of these characteristics: – Tables are snapshots. – Some tables contain a large amount of data being manipulated by another application, which might not return the data in the same order. ■ Update cascade operations on foreign keys. ■ Ensure that constraints are deferrable. After identifying the appropriate tables, ensure that their FOREIGN, UNIQUE and PRIMARY key constraints are created DEFERRABLE. ■ Within the application that manipulates the data, set all constraints deferred before you begin processing any data, as follows: SET CONSTRAINTS ALL DEFERRED; Maintaining Data Integrity in Database Applications 5-11 Enforcing Referential Integrity with FOREIGN KEY Constraints ■ (Optional) Check for constraint violations immediately before committing the transaction. Immediately before the COMMIT statement, run the SET CONSTRAINTS ALL IMMEDIATE statement. If there are any problems with a constraint, this statement fails, and identifies the constraint that caused the error. If you commit while constraints are violated, the transaction rolls back and you get an error message. In Example 5–4, the PRIMARY and FOREIGN keys of the table emp are created DEFERRABLE and then deferred. Example 5–4 Deferring Constraint Checks DROP TABLE dept; CREATE TABLE dept ( deptno NUMBER PRIMARY KEY, dname VARCHAR2 (30) ); DROP TABLE emp; CREATE TABLE emp ( empno NUMBER, ename VARCHAR2(30), deptno NUMBER, CONSTRAINT pk_emp_empno PRIMARY KEY (empno) DEFERRABLE, CONSTRAINT fk_emp_deptno FOREIGN KEY (deptno) REFERENCES dept(deptno) DEFERRABLE ); INSERT INTO dept (deptno, dname) VALUES (10, 'Accounting'); INSERT INTO dept (deptno, dname) VALUES (20, 'SALES'); INSERT INTO emp (empno, ename, deptno) VALUES (1, 'Corleone', 10); INSERT INTO emp (empno, ename, deptno) VALUES (2, 'Costanza', 20); COMMIT; SET CONSTRAINTS ALL DEFERRED; UPDATE dept SET deptno = deptno + 10 WHERE deptno = 20; Query: SELECT * from dept ORDER BY deptno; Result: DEPTNO ---------10 30 DNAME -----------------------------Accounting SALES 2 rows selected. Update: UPDATE emp SET deptno = deptno + 10 WHERE deptno = 20; Result: 1 row updated. Query: 5-12 Oracle Database Advanced Application Developer's Guide Referential Integrity in a Distributed Database SELECT * from emp ORDER BY deptno; Result: EMPNO ---------1 2 ENAME DEPTNO ------------------------------ ---------Corleone 10 Costanza 30 2 rows selected. The SET CONSTRAINTS applies only to the current transaction, and its setting lasts for the duration of the transaction, or until another SET CONSTRAINTS statement resets the mode. The ALTER SESSION SET CONSTRAINTS statement applies only for the current session. The defaults specified when you create a constraint remain while the constraint exists. See Also: Oracle Database SQL Language Reference for more information about the SET CONSTRAINTS statement Minimizing Space and Time Overhead for Indexes Associated with Constraints When you create a UNIQUE or PRIMARY key, Oracle Database checks to see if an existing index enforces uniqueness for the constraint. If there is no such index, the database creates one. When Oracle Database uses a unique index to enforce a constraint, and constraints associated with the unique index are dropped or disabled, the index is dropped. To preserve the statistics associated with the index (which would take a long time to re-create), specify the KEEP INDEX clause on the DROP CONSTRAINT statement. While enabled foreign keys reference a PRIMARY or UNIQUE key, you cannot disable or drop the PRIMARY or UNIQUE key constraint or the index. Note: UNIQUE and PRIMARY keys with deferrable constraints must all use nonunique indexes. To use existing indexes when creating unique and primary key constraints, include USING INDEX in the CONSTRAINT clause. For details and examples, see Oracle Database SQL Language Reference. Guidelines for Indexing Foreign Keys Index foreign keys unless the matching unique or primary key is never updated or deleted. Oracle Database Concepts for more information about indexing foreign keys See Also: Referential Integrity in a Distributed Database The declaration of a referential constraint cannot specify a foreign key that references a primary or unique key of a remote table. Maintaining Data Integrity in Database Applications 5-13 When to Use CHECK Constraints However, you can maintain parent/child table relationships across nodes using triggers. Oracle Database PL/SQL Language Reference for more information about triggers that enforce referential integrity See Also: If you decide to define referential integrity across the nodes of a distributed database using triggers, be aware that network failures can make both the parent table and the child table inaccessible. Note: For example, assume that the child table is in the SALES database, and the parent table is in the HQ database. If the network connection between the two databases fails, then some data manipulation language (DML) statements against the child table (those that insert rows or update a foreign key value) cannot proceed, because the referential integrity triggers must have access to the parent table in the HQ database. When to Use CHECK Constraints Use CHECK constraints when you must enforce integrity rules based on logical expressions, such as comparisons. Never use CHECK constraints when any of the other types of constraints can provide the necessary checking. See Also: "Choosing Between CHECK and NOT NULL Constraints" on page 5-15 Examples of CHECK constraints include: ■ ■ ■ A CHECK constraint on employee salaries so that no salary value is greater than 10000. A CHECK constraint on department locations so that only the locations "BOSTON", "NEW YORK", and "DALLAS" are allowed. A CHECK constraint on the salary and commissions columns to prevent the commission from being larger than the salary. Restrictions on CHECK Constraints A CHECK constraint requires that a condition be true or unknown for every row of the table. If a statement causes the condition to evaluate to false, then the statement is rolled back. The condition of a CHECK constraint has these limitations: ■ The condition must be a boolean expression that can be evaluated using the values in the row being inserted or updated. ■ The condition cannot contain subqueries or sequences. ■ The condition cannot include the SYSDATE, UID, USER, or USERENV SQL functions. ■ The condition cannot contain the pseudocolumns LEVEL or ROWNUM. ■ The condition cannot contain the PRIOR operator. ■ The condition cannot contain a user-defined function. 5-14 Oracle Database Advanced Application Developer's Guide When to Use CHECK Constraints See Also: ■ ■ ■ Oracle Database SQL Language Reference for information about the LEVEL pseudocolumn Oracle Database SQL Language Reference for information about the ROWNUM pseudocolumn Oracle Database SQL Language Reference for information about the PRIOR operator (used in hierarchical queries) Designing CHECK Constraints When using CHECK constraints, remember that a CHECK constraint is violated only if the condition evaluates to false; true and unknown values (such as comparisons with nulls) do not violate a check condition. Ensure that any CHECK constraint that you define is specific enough to enforce the rule. For example, consider this CHECK constraint: CHECK (Sal > 0 OR Comm >= 0) At first glance, this rule may be interpreted as "do not allow a row in the employee table unless the employee salary is greater than zero or the employee commission is greater than or equal to zero." But if a row is inserted with a null salary, that row does not violate the CHECK constraint, regardless of whether the commission value is valid, because the entire check condition is evaluated as unknown. In this case, you can prevent such violations by placing NOT NULL constraints on both the SAL and COMM columns. If you are not sure when unknown values result in NULL conditions, review the truth tables for the logical conditions in Oracle Database SQL Language Reference Note: Rules for Multiple CHECK Constraints A single column can have multiple CHECK constraints that reference the column in its definition. There is no limit to the number of CHECK constraints that can be defined that reference a column. The order in which the constraints are evaluated is not defined, so be careful not to rely on the order or to define multiple constraints that conflict with each other. Choosing Between CHECK and NOT NULL Constraints According to the ANSI/ISO standard, a NOT NULL constraint is an example of a CHECK constraint, where the condition is: CHECK (column_name IS NOT NULL) Therefore, you can write NOT NULL constraints for a single column using either a NOT NULL constraint or a CHECK constraint. The NOT NULL constraint is easier to use than the CHECK constraint. In the case where a composite key can allow only all nulls or all values, you must use a CHECK constraint. For example, this CHECK constraint allows a key value in the composite key made up of columns C1 and C2 to contain either all nulls or all values: CHECK ((C1 IS NULL AND C2 IS NULL) OR (C1 IS NOT NULL AND C2 IS NOT NULL)) Maintaining Data Integrity in Database Applications 5-15 Examples of Defining Constraints Examples of Defining Constraints Example 5–5 and Example 5–6 show how to create simple constraints during the prototype phase of your database design. In these examples, each constraint is given a name. Naming the constraints prevents the database from creating multiple copies of the same constraint, with different system-generated names, if the data definition language (DDL) statement runs multiple times. Example 5–5 creates tables and their constraints at the same time, using the CREATE TABLE statement. Example 5–5 Defining Constraints with the CREATE TABLE Statement DROP TABLE DeptTab; CREATE TABLE DeptTab ( Deptno NUMBER(3) CONSTRAINT pk_DeptTab_Deptno PRIMARY KEY, Dname VARCHAR2(15), Loc VARCHAR2(15), CONSTRAINT u_DeptTab_Dname_Loc UNIQUE (Dname, Loc), CONSTRAINT c_DeptTab_Loc CHECK (Loc IN ('NEW YORK', 'BOSTON', 'CHICAGO'))); DROP TABLE EmpTab; CREATE TABLE EmpTab ( Empno NUMBER(5) CONSTRAINT pk_EmpTab_Empno PRIMARY KEY, Ename VARCHAR2(15) NOT NULL, Job VARCHAR2(10), Mgr NUMBER(5) CONSTRAINT r_EmpTab_Mgr REFERENCES EmpTab, Hiredate DATE, Sal NUMBER(7,2), Comm NUMBER(5,2), Deptno NUMBER(3) NOT NULL CONSTRAINT r_EmpTab_DeptTab REFERENCES DeptTab ON DELETE CASCADE); Example 5–6 creates constraints for existing tables, using the ALTER TABLE statement. You cannot create a validated constraint on a table if the table contains rows that violate the constraint. Example 5–6 Defining Constraints with the ALTER TABLE Statement -- Create tables without constraints: DROP TABLE DeptTab; CREATE TABLE DeptTab ( Deptno NUMBER(3), Dname VARCHAR2(15), Loc VARCHAR2(15) ); DROP TABLE EmpTab; CREATE TABLE EmpTab ( Empno NUMBER(5), Ename VARCHAR2(15), Job VARCHAR2(10), Mgr NUMBER(5), Hiredate DATE, Sal NUMBER(7,2), Comm NUMBER(5,2), Deptno NUMBER(3) ); 5-16 Oracle Database Advanced Application Developer's Guide Enabling and Disabling Constraints --Define constraints with the ALTER TABLE statement: ALTER TABLE DeptTab ADD CONSTRAINT pk_DeptTab_Deptno PRIMARY KEY (Deptno); ALTER TABLE EmpTab ADD CONSTRAINT fk_DeptTab_Deptno FOREIGN KEY (Deptno) REFERENCES DeptTab; ALTER TABLE EmpTab MODIFY (Ename VARCHAR2(15) NOT NULL); See Also: Oracle Database Administrator's Guide for information about creating and maintaining constraints for a large production database Privileges Needed to Define Constraints If you have the CREATE TABLE or CREATE ANY TABLE system privilege, then you can define constraints on the tables that you create. If you have the ALTER ANY TABLE system privilege, then you can define constraints on any existing table. If you have the ALTER object privilege for a specific table, then you can define constraints on that table. UNIQUE and PRIMARY KEY constraints require that the table owner has either the UNLIMITED TABLESPACE system privilege or a quota for the tablespace that contains the associated index. You can define FOREIGN KEY constraints if the parent table or view is in your schema or you have the REFERENCES privilege on the columns of the referenced key in the parent table or view. For more information, see "Privileges Required to Create FOREIGN KEY Constraints" on page 5-24. Naming Constraints Assign names to constraints NOT NULL, UNIQUE, PRIMARY KEY, FOREIGN KEY, and CHECK using the CONSTRAINT option of the constraint clause. This name must be unique among the constraints that you own. If you do not specify a constraint name, one is assigned automatically by Oracle Database. Choosing your own name makes error messages for constraint violations more understandable, and prevents the creation of duplicate constraints with different names if the SQL statements are run more than once. See the previous examples of the CREATE TABLE and ALTER TABLE statements for examples of the CONSTRAINT option of the constraint clause. The name of each constraint is included with other information about the constraint in the data dictionary. See Also: "Viewing Information About Constraints" on page 5-25 for examples of static data dictionary views Enabling and Disabling Constraints This section explains the mechanisms and procedures for manually enabling and disabling constraints. Maintaining Data Integrity in Database Applications 5-17 Enabling and Disabling Constraints enabled constraint. When a constraint is enabled, the corresponding rule is enforced on the data values in the associated columns. The definition of the constraint is stored in the data dictionary. disabled constraint. When a constraint is disabled, the corresponding rule is not enforced. The definition of the constraint is still stored in the data dictionary. An integrity constraint represents an assertion about the data in a database. This assertion is always true when the constraint is enabled. The assertion might not be true when the constraint is disabled, because data that violates the integrity constraint can be in the database. Topics: ■ Why Disable Constraints? ■ Creating Enabled Constraints (Default) ■ Creating Disabled Constraints ■ Enabling Existing Constraints ■ Disabling Existing Constraints ■ Guidelines for Enabling and Disabling Key Constraints ■ Fixing Constraint Exceptions Why Disable Constraints? During day-to-day operations, keep constraints enabled. In certain situations, temporarily disabling the constraints of a table makes sense for performance reasons. For example: ■ ■ ■ When loading large amounts of data into a table using SQL*Loader When performing batch operations that make massive changes to a table (such as changing each employee number by adding 1000 to the existing number) When importing or exporting one table at a time Temporarily turning off constraints can speed up these operations. Creating Enabled Constraints (Default) When you define an integrity constraint (using either CREATE TABLE or ALTER TABLE), Oracle Database enables the constraint by default. For code clarity, you can explicitly enable the constraint by including the ENABLE clause in its definition, as in Example 5–7. Example 5–7 Creating Enabled Constraints /* Use CREATE TABLE statement to create enabled constraint (ENABLE keyword is optional): */ DROP TABLE t1; CREATE TABLE t1 (Empno NUMBER(5) PRIMARY KEY ENABLE); /* Create table without constraint and then use ALTER TABLE statement to add enabled constraint (ENABLE keyword is optional): */ DROP TABLE t2; 5-18 Oracle Database Advanced Application Developer's Guide Enabling and Disabling Constraints CREATE TABLE t2 (Empno NUMBER(5)); ALTER TABLE t2 ADD PRIMARY KEY (Empno) ENABLE; Include the ENABLE clause when defining a constraint for a table to be populated a row at a time by individual transactions. This ensures that data is always consistent, and reduces the performance overhead of each DML statement. An ALTER TABLE statement that tries to enable an integrity constraint fails if an existing row of the table violates the integrity constraint. The statement rolls back and the constraint definition is neither stored nor enabled. See Also: "Fixing Constraint Exceptions" on page 5-21 for more information about rows that violate constraints Creating Disabled Constraints You define and disable an integrity constraint (using either CREATE TABLE or ALTER TABLE), by including the DISABLE clause in its definition, as in Example 5–8. Example 5–8 Creating Disabled Constraints /* Use CREATE TABLE statement to create disabled constraint */ DROP TABLE t1; CREATE TABLE t1 (Empno NUMBER(5) PRIMARY KEY DISABLE); /* Create table without constraint and then use ALTER TABLE statement to add disabled constraint */ DROP TABLE t2; CREATE TABLE t2 (Empno NUMBER(5)); ALTER TABLE t2 ADD PRIMARY KEY (Empno) DISABLE; Include the DISABLE clause when defining a constraint for a table to have large amounts of data inserted before anybody else accesses it, particularly if you must cleanse data after inserting it, or must fill empty columns with sequence numbers or parent/child relationships. An ALTER TABLE statement that defines and disables a constraint never fails, because its rule is not enforced. Enabling Existing Constraints After you have cleansed the data and filled the empty columns, you can enable constraints that were disabled during data insertion. To enable an existing constraint, use the ALTER TABLE statement with the ENABLE clause, as in Example 5–9. Example 5–9 Enabling Existing Constraints -- Create table with disabled constraints: DROP TABLE DeptTab; CREATE TABLE DeptTab ( Deptno NUMBER(3) PRIMARY KEY DISABLE, Dname VARCHAR2(15), Loc VARCHAR2(15), Maintaining Data Integrity in Database Applications 5-19 Enabling and Disabling Constraints CONSTRAINT uk_DeptTab_Dname_Loc UNIQUE (Dname, Loc) DISABLE, CONSTRAINT c_DeptTab_Loc CHECK (Loc IN ('NEW YORK', 'BOSTON', 'CHICAGO')) DISABLE ); -- Enable constraints: ALTER ENABLE ENABLE ENABLE TABLE DeptTab PRIMARY KEY CONSTRAINT uk_DeptTab_Dname_Loc CONSTRAINT c_DeptTab_Loc; An ALTER TABLE statement that attempts to enable an integrity constraint fails if any of the table rows violate the integrity constraint. The statement is rolled back and the constraint is not enabled. See Also: "Fixing Constraint Exceptions" on page 5-21 for more information about rows that violate constraints Disabling Existing Constraints If you must perform a large insert or update when a table contains data, you can temporarily disable constraints to improve performance of the bulk operation. To disable an existing constraint, use the ALTER TABLE statement with the DISABLE clause, as in Example 5–10. Example 5–10 Disabling Existing Constraints -- Create table with enabled constraints: DROP TABLE DeptTab; CREATE TABLE DeptTab ( Deptno NUMBER(3) PRIMARY KEY ENABLE, Dname VARCHAR2(15), Loc VARCHAR2(15), CONSTRAINT uk_DeptTab_Dname_Loc UNIQUE (Dname, Loc) ENABLE, CONSTRAINT c_DeptTab_Loc CHECK (Loc IN ('NEW YORK', 'BOSTON', 'CHICAGO')) ENABLE ); -- Disable constraints: ALTER TABLE DeptTab DISABLE PRIMARY KEY DISABLE CONSTRAINT uk_DeptTab_Dname_Loc DISABLE CONSTRAINT c_DeptTab_Loc; Guidelines for Enabling and Disabling Key Constraints When enabling or disabling UNIQUE, PRIMARY KEY, and FOREIGN KEY constraints, be aware of several important issues and prerequisites. UNIQUE key and PRIMARY KEY constraints are usually managed by the database administrator. See Also: Oracle Database Administrator's Guide and "Managing FOREIGN KEY Constraints" on page 5-24 5-20 Oracle Database Advanced Application Developer's Guide Modifying Constraints Fixing Constraint Exceptions If a row of a table disobeys an integrity constraint, then this row is in violation of the constraint and is called an exception to the constraint. If any exceptions exist, then the constraint cannot be enabled. The rows that violate the constraint must be updated or deleted before the constraint can be enabled. You can identify exceptions for a specific integrity constraint as you try to enable the constraint. See Also: "Fixing Constraint Exceptions" on page 5-21 for more information about this procedure When you try to create or enable a constraint, and the statement fails because integrity constraint exceptions exist, the statement is rolled back. You cannot enable the constraint until all exceptions are either updated or deleted. To determine which rows violate the integrity constraint, include the EXCEPTIONS option in the ENABLE clause of a CREATE TABLE or ALTER TABLE statement. See Also: Oracle Database Administrator's Guide for more information about responding to constraint exceptions Modifying Constraints Starting with Oracle8i, you can modify an existing constraint with the MODIFY CONSTRAINT clause, as in Example 5–11. See Also: Oracle Database SQL Language Reference for information about the parameters you can modify Example 5–11 Modifying Constraints /* Create & then modify a CHECK constraint: */ DROP TABLE X1Tab; CREATE TABLE X1Tab ( a1 NUMBER CONSTRAINT c_X1Tab_a1 CHECK (a1>3) DEFERRABLE DISABLE ); ALTER TABLE X1Tab MODIFY CONSTRAINT c_X1Tab_a1 ENABLE; ALTER TABLE X1Tab MODIFY CONSTRAINT c_X1Tab_a1 RELY; ALTER TABLE X1Tab MODIFY CONSTRAINT c_X1Tab_a1 INITIALLY DEFERRED; ALTER TABLE X1Tab MODIFY CONSTRAINT c_X1Tab_a1 ENABLE NOVALIDATE; /* Create & then modify a PRIMARY KEY constraint: */ DROP TABLE t1; CREATE TABLE t1 (a1 INT, b1 INT); ALTER TABLE t1 Maintaining Data Integrity in Database Applications 5-21 Renaming Constraints ADD CONSTRAINT pk_t1_a1 PRIMARY KEY(a1) DISABLE; ALTER TABLE t1 MODIFY PRIMARY KEY INITIALLY IMMEDIATE USING INDEX PCTFREE = 30 ENABLE NOVALIDATE; ALTER TABLE t1 MODIFY PRIMARY KEY ENABLE NOVALIDATE; Renaming Constraints One property of a constraint that you can modify is its name. Situations in which you would rename a constraint include: ■ You want to clone a table and its constraints. Constraint names must be unique, even across multiple schemas. Therefore, the constraints in the original table cannot have the same names as those in the cloned table. ■ You created a constraint with a default system-generated name, and now you want to give it a name that is easy to remember, so that you can easily enable and disable it. Example 5–12 shows how to find the system-generated name of a constraint and change it. Example 5–12 Renaming a Constraint DROP TABLE T; CREATE TABLE T ( C1 NUMBER PRIMARY KEY, C2 NUMBER ); Query: SELECT CONSTRAINT_NAME FROM USER_CONSTRAINTS WHERE TABLE_NAME = 'T' AND CONSTRAINT_TYPE = 'P'; Result (system-generated name of constraint name varies): CONSTRAINT_NAME -----------------------------SYS_C0013059 1 row selected. Rename constraint from name reported in preceding query to T_C1_PK: ALTER TABLE T RENAME CONSTRAINT SYS_C0013059 TO T_C1_PK; Query: SELECT CONSTRAINT_NAME FROM USER_CONSTRAINTS WHERE TABLE_NAME = 'T' AND CONSTRAINT_TYPE = 'P'; Result: 5-22 Oracle Database Advanced Application Developer's Guide Dropping Constraints CONSTRAINT_NAME -----------------------------T_C1_PK 1 row selected. Dropping Constraints You can drop a constraint using the DROP clause of the ALTER TABLE statement. Situations in which you would drop a constraint include: ■ The constraint enforces a rule that is no longer true. ■ The constraint is no longer needed. To drop a constraint and all other integrity constraints that depend on it, specify CASCADE. Example 5–13 Dropping Constraints -- Create table with constraints: DROP TABLE DeptTab; CREATE TABLE DeptTab ( Deptno NUMBER(3) PRIMARY KEY, Dname VARCHAR2(15), Loc VARCHAR2(15), CONSTRAINT uk_DeptTab_Dname_Loc UNIQUE (Dname, Loc), CONSTRAINT c_DeptTab_Loc CHECK (Loc IN ('NEW YORK', 'BOSTON', 'CHICAGO')) ); -- Drop constraints: ALTER TABLE DeptTab DROP PRIMARY KEY DROP CONSTRAINT uk_DeptTab_Dname_Loc DROP CONSTRAINT c_DeptTab_Loc; When dropping UNIQUE, PRIMARY KEY, and FOREIGN KEY constraints, be aware of several important issues and prerequisites. UNIQUE and PRIMARY KEY constraints are usually managed by the database administrator. See Also: ■ ■ ■ Oracle Database SQL Language Reference for more information about the DROP clause of the ALTER TABLE statement. Oracle Database Administrator's Guide for more information about dropping constraints. Oracle Database SQL Language Reference for information about the CASCADE CONSTRAINTS clause of the DROP TABLE statement, which drops all referential integrity constraints that refer to primary and unique keys in the dropped table Maintaining Data Integrity in Database Applications 5-23 Managing FOREIGN KEY Constraints Managing FOREIGN KEY Constraints FOREIGN KEY constraints enforce relationships between columns in different tables. Therefore, they cannot be enabled if the constraint of the referenced primary or unique key is not present or not enabled. Data Types and Names for Foreign Key Columns You must use the same data type for corresponding columns in the dependent and referenced tables. The column names need not match. Limit on Columns in Composite Foreign Keys Because foreign keys reference primary and unique keys of the parent table, and PRIMARY KEY and UNIQUE key constraints are enforced using indexes, composite foreign keys are limited to 32 columns. Foreign Key References Primary Key by Default If the column list is not included in the REFERENCES option when defining a FOREIGN KEY constraint (single column or composite), then Oracle Database assumes that you intend to reference the primary key of the specified table. Alternatively, you can explicitly specify the column(s) to reference in the parent table within parentheses. Oracle Database automatically checks to verify that this column list references a primary or unique key of the parent table. If it does not, then an informative error is returned. Privileges Required to Create FOREIGN KEY Constraints To create a FOREIGN KEY constraint, the creator of the constraint must have privileged access to the parent and child tables. ■ ■ Parent Table The creator of the referential integrity constraint must own the parent table or have REFERENCES object privileges on the columns that constitute the parent key of the parent table. Child Table The creator of the referential integrity constraint must have the ability to create tables (that is, the CREATE TABLE or CREATE ANY TABLE system privilege) or the ability to alter the child table (that is, the ALTER object privilege for the child table or the ALTER ANY TABLE system privilege). In both cases, necessary privileges cannot be obtained through a role; they must be explicitly granted to the creator of the constraint. These restrictions allow: ■ ■ The owner of the child table to explicitly decide which constraints are enforced and which other users can create constraints The owner of the parent table to explicitly decide if foreign keys can depend on the primary and unique keys in her tables Choosing How Foreign Keys Enforce Referential Integrity Oracle Database allows different types of referential integrity actions to be enforced, as specified with the definition of a FOREIGN KEY constraint: 5-24 Oracle Database Advanced Application Developer's Guide Viewing Information About Constraints ■ Prevent Delete or Update of Parent Key The default setting prevents the deletion or update of a parent key if there is a row in the child table that references the key. For example: CREATE TABLE Emp_tab ( FOREIGN KEY (Deptno) REFERENCES Dept_tab); ■ Delete Child Rows When Parent Key Deleted The ON DELETE CASCADE action allows parent key data that is referenced from the child table to be deleted, but not updated. When data in the parent key is deleted, all rows in the child table that depend on the deleted parent key values are also deleted. To specify this referential action, include the ON DELETE CASCADE option in the definition of the FOREIGN KEY constraint. For example: CREATE TABLE Emp_tab ( FOREIGN KEY (Deptno) REFERENCES Dept_tab ON DELETE CASCADE); ■ Set Foreign Keys to Null When Parent Key Deleted The ON DELETE SET NULL action allows data that references the parent key to be deleted, but not updated. When referenced data in the parent key is deleted, all rows in the child table that depend on those parent key values have their foreign keys set to null. To specify this referential action, include the ON DELETE SET NULL option in the definition of the FOREIGN KEY constraint. For example: CREATE TABLE Emp_tab ( FOREIGN KEY (Deptno) REFERENCES Dept_tab ON DELETE SET NULL); Viewing Information About Constraints To find the names of constraints, what columns they affect, and other information to help you manage them, query the static data dictionary views *_CONSTRAINTS and *_ CONS_COLUMNS, as in Example 5–14. Oracle Database Reference for information about *_ CONSTRAINTS and *_CONS_COLUMNS See Also: Example 5–14 Viewing Information About Constraints DROP TABLE DeptTab; CREATE TABLE DeptTab ( Deptno NUMBER(3) PRIMARY KEY, Dname VARCHAR2(15), Loc VARCHAR2(15), CONSTRAINT uk_DeptTab_Dname_Loc UNIQUE (Dname, Loc), CONSTRAINT c_DeptTab_Loc CHECK (Loc IN ('NEW YORK', 'BOSTON', 'CHICAGO')) ); DROP TABLE EmpTab; CREATE TABLE EmpTab ( Empno NUMBER(5) PRIMARY KEY, Ename VARCHAR2(15) NOT NULL, Job VARCHAR2(10), Mgr NUMBER(5) CONSTRAINT r_EmpTab_Mgr REFERENCES EmpTab ON DELETE CASCADE, Hiredate DATE, Sal NUMBER(7,2), Comm NUMBER(5,2), Maintaining Data Integrity in Database Applications 5-25 Viewing Information About Constraints Deptno NUMBER(3) NOT NULL CONSTRAINT r_EmpTab_Deptno REFERENCES DeptTab ); -- Format columns (optional): COLUMN COLUMN COLUMN COLUMN COLUMN COLUMN CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME R_CONSTRAINT_NAME SEARCH_CONDITION COLUMN_NAME FORMAT FORMAT FORMAT FORMAT FORMAT FORMAT A20; A4 HEADING 'TYPE'; A10; A17; A40; A12; List accessible constraints in DeptTab and EmpTab: SELECT CONSTRAINT_NAME, CONSTRAINT_TYPE, TABLE_NAME, R_CONSTRAINT_NAME FROM USER_CONSTRAINTS WHERE (TABLE_NAME = 'DEPTTAB' OR TABLE_NAME = 'EMPTAB') ORDER BY CONSTRAINT_NAME; Result: CONSTRAINT_NAME -------------------C_DEPTTAB_LOC R_EMPTAB_DEPTNO R_EMPTAB_MGR SYS_C006286 SYS_C006288 SYS_C006289 SYS_C006290 UK_DEPTTAB_DNAME_LOC TYPE ---C R R P C C P U TABLE_NAME ---------DEPTTAB EMPTAB EMPTAB DEPTTAB EMPTAB EMPTAB EMPTAB DEPTTAB R_CONSTRAINT_NAME ----------------SYS_C006286 SYS_C006290 8 rows selected. Distinguish between NOT NULL and CHECK constraints in DeptTab and EmpTab: SELECT CONSTRAINT_NAME, SEARCH_CONDITION FROM USER_CONSTRAINTS WHERE (TABLE_NAME = 'DEPTTAB' OR TABLE_NAME = 'EMPTAB') AND CONSTRAINT_TYPE = 'C' ORDER BY CONSTRAINT_NAME; Result: CONSTRAINT_NAME -------------------C_DEPTTAB_LOC SYS_C006288 SYS_C006289 SEARCH_CONDITION ---------------------------------------Loc IN ('NEW YORK', 'BOSTON', 'CHICAGO') "ENAME" IS NOT NULL "DEPTNO" IS NOT NULL 3 rows selected. For DeptTab and EmpTab, list columns that constitute constraints: SELECT CONSTRAINT_NAME, TABLE_NAME, COLUMN_NAME FROM USER_CONS_COLUMNS WHERE (TABLE_NAME = 'DEPTTAB' OR TABLE_NAME = 'EMPTAB') ORDER BY CONSTRAINT_NAME; Result: 5-26 Oracle Database Advanced Application Developer's Guide Viewing Information About Constraints CONSTRAINT_NAME -------------------C_DEPTTAB_LOC R_EMPTAB_DEPTNO R_EMPTAB_MGR SYS_C006286 SYS_C006288 SYS_C006289 SYS_C006290 UK_DEPTTAB_DNAME_LOC UK_DEPTTAB_DNAME_LOC TABLE_NAME ---------DEPTTAB EMPTAB EMPTAB DEPTTAB EMPTAB EMPTAB EMPTAB DEPTTAB DEPTTAB COLUMN_NAME -----------LOC DEPTNO MGR DEPTNO ENAME DEPTNO EMPNO LOC DNAME 9 rows selected. Note that: ■ ■ Some constraint names are user specified (such as UK_DEPTTAB_DNAME_LOC), while others are system specified (such as SYS_C006290). Each constraint type is denoted with a different character in the CONSTRAINT_TYPE column. This table summarizes the characters used for each constraint type: Constraint Type Character PRIMARY KEY P UNIQUE KEY U FOREIGN KEY R CHECK, NOT NULL C An additional constraint type is indicated by the character "V" in the CONSTRAINT_TYPE column. This constraint type corresponds to constraints created using the WITH CHECK OPTION for views. Note: These constraints are explicitly listed in the SEARCH_CONDITION column: ■ NOT NULL constraints ■ The conditions for user-defined CHECK constraints Maintaining Data Integrity in Database Applications 5-27 Viewing Information About Constraints 5-28 Oracle Database Advanced Application Developer's Guide Part II Part II PL/SQL for Application Developers This part presents information that application developers need about PL/SQL, the Oracle procedural extension of SQL. Chapters: ■ Chapter 6, "Coding PL/SQL Subprograms and Packages" ■ Chapter 7, "Using PL/Scope" ■ Chapter 8, "Using the PL/SQL Hierarchical Profiler" ■ Chapter 9, "Developing PL/SQL Web Applications" ■ Chapter 10, "Developing PL/SQL Server Pages (PSP)" ■ Chapter 11, "Using Continuous Query Notification (CQN)" Oracle Database PL/SQL Language Reference for a complete description of PL/SQL See Also: 6 Coding PL/SQL Subprograms and Packages 6 This chapter describes some procedural capabilities of Oracle Database for application development. Topics: ■ Overview of PL/SQL Units ■ Compiling PL/SQL Subprograms for Native Execution ■ Cursor Variables ■ Handling PL/SQL Compile-Time Errors ■ Handling Runtime PL/SQL Errors ■ Debugging Stored Subprograms ■ Invoking Stored Subprograms ■ Invoking Remote Subprograms ■ Invoking Stored PL/SQL Functions from SQL Statements ■ Returning Large Amounts of Data from a Function ■ Coding Your Own Aggregate Functions See Also: ■ ■ ■ Oracle Database PL/SQL Language Reference for more information about PL/SQL subprograms Oracle Database PL/SQL Language Reference for more information about PL/SQL packages Oracle Database Performance Tuning Guide for information about application tracing tools, which can help you find problems in PL/SQL code Overview of PL/SQL Units PL/SQL is a modern, block-structured programming language. It provides several features that make developing powerful database applications very convenient. For example, PL/SQL provides procedural constructs, such as loops and conditional statements, that are not available in standard SQL. You can directly enter SQL data manipulation language (DML) statements inside PL/SQL blocks, and you can use subprograms supplied by Oracle to perform data definition language (DDL) statements. Coding PL/SQL Subprograms and Packages 6-1 Overview of PL/SQL Units PL/SQL code runs on the server, so using PL/SQL lets you centralize significant parts of your database applications for increased maintainability and security. It also enables you to achieve a significant reduction of network overhead in client/server applications. Some Oracle tools, such as Oracle Forms, contain a PL/SQL engine that lets you run PL/SQL locally. Note: You can even use PL/SQL for some database applications instead of 3GL programs that use embedded SQL or Oracle Call Interface (OCI). PL/SQL units include: ■ Anonymous Blocks ■ Stored PL/SQL Units ■ Triggers See Also: ■ ■ ■ Oracle Database PL/SQL Language Reference for syntax and examples of operations on PL/SQL packages Oracle Database PL/SQL Packages and Types Reference for information about the PL/SQL packages that come with Oracle Database "Dependencies Among Local and Remote Database Procedures" on page 18-11 for information about dependencies among stored PL/SQL units Anonymous Blocks An anonymous block is a PL/SQL unit that has no name. An anonymous block consists of an optional declarative part, an executable part, and one or more optional exception handlers. The declarative part declares PL/SQL variables, exceptions, and cursors. The executable part contains PL/SQL code and SQL statements, and can contain nested blocks. Exception handlers contain code that is invoked when the exception is raised, either as a predefined PL/SQL exception (such as NO_DATA_FOUND or ZERO_DIVIDE) or as an exception that you define. Anonymous blocks are usually used interactively from a tool, such as SQL*Plus, or in a precompiler, OCI, or SQL*Module application. They are usually used to invoke stored subprograms or to open cursor variables. The anonymous block in Example 6–1 uses the DBMS_OUTPUT package to print the names of all employees in the HR.EMPLOYEES table who are in department 20. Example 6–1 Anonymous Block DECLARE last_name cursor VARCHAR2(10); c1 IS SELECT LAST_NAME FROM EMPLOYEES WHERE DEPARTMENT_ID = 20 6-2 Oracle Database Advanced Application Developer's Guide Overview of PL/SQL Units ORDER BY LAST_NAME; BEGIN OPEN c1; LOOP FETCH c1 INTO last_name; EXIT WHEN c1%NOTFOUND; DBMS_OUTPUT.PUT_LINE(last_name); END LOOP; END; / Result: Fay Hartstein Exceptions let you handle Oracle Database error conditions with PL/SQL program logic, enabling your application to prevent the server from issuing an error that can cause the client application to end. The anonymous block in Example 6–2 handles the predefined Oracle Database exception NO_DATA_FOUND (which results in ORA-01403 if not handled). Example 6–2 Anonymous Block with Exception Handler for Predefined Error DECLARE Emp_number INTEGER := 9999 Emp_name VARCHAR2(10); BEGIN SELECT LAST_NAME INTO Emp_name FROM EMPLOYEES WHERE EMPLOYEE_ID = Emp_number; DBMS_OUTPUT.PUT_LINE('Employee name is ' || Emp_name); EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('No such employee: ' || Emp_number); END; / Result: No such employee: 9999 You can also define your own exceptions; that is, you can declare them in the declaration part of a block and define them in the exception part of the block, as in Example 6–3. Example 6–3 Anonymous Block with Exception Handler for User-Defined Exception DECLARE Emp_name VARCHAR2(10); Emp_number INTEGER; Empno_out_of_range EXCEPTION; BEGIN Emp_number := 10001; IF Emp_number > 9999 OR Emp_number < 1000 THEN RAISE Empno_out_of_range; ELSE SELECT LAST_NAME INTO Emp_name FROM EMPLOYEES WHERE EMPLOYEE_ID = Emp_number; DBMS_OUTPUT.PUT_LINE('Employee name is ' || Emp_name); END IF; EXCEPTION Coding PL/SQL Subprograms and Packages 6-3 Overview of PL/SQL Units WHEN Empno_out_of_range THEN DBMS_OUTPUT.PUT_LINE('Employee number ' || Emp_number || ' is out of range.'); END; / Result: Employee number 10001 is out of range. See Also: ■ ■ ■ Oracle Database PL/SQL Packages and Types Reference for complete information about the DBMS_OUTPUT package Oracle Database PL/SQL Language Reference and "Handling Runtime PL/SQL Errors" on page 6-22 "Cursor Variables" on page 6-18 Stored PL/SQL Units A stored PL/SQL unit is a subprogram (procedure or function) or package that: ■ Has a name. ■ Can take parameters, and can return values. ■ Is stored in the data dictionary. ■ Can be invoked by many users. If a subprogram belongs to a package, it is called a package subprogram; if not, it is called a standalone subprogram. Topics: Naming Subprograms ■ ■ Subprogram Parameters ■ Creating Subprograms ■ Altering Subprograms ■ Dropping Subprograms and Packages ■ External Subprograms ■ PL/SQL Function Result Cache ■ PL/SQL Packages ■ PL/SQL Object Size Limits ■ Creating Packages ■ Naming Packages and Package Objects ■ Package Invalidations and Session State ■ Packages Supplied with Oracle Database ■ Overview of Bulk Binding ■ When to Use Bulk Binds 6-4 Oracle Database Advanced Application Developer's Guide Overview of PL/SQL Units Naming Subprograms Because a subprogram is stored in the database, it must be named. This distinguishes it from other stored subprograms and makes it possible for applications to invoke it. Each publicly-visible subprogram in a schema must have a unique name, and the name must be a legal PL/SQL identifier. If you plan to invoke a stored subprogram using a stub generated by SQL*Module, then the stored subprogram name must also be a legal identifier in the invoking host 3GL language, such as Ada or C. Note: Subprogram Parameters Stored subprograms can take parameters. In the procedure in Example 6–4, the department number is an input parameter that is used when the parameterized cursor c1 is opened. Example 6–4 Stored Procedure with Parameters CREATE OR REPLACE PROCEDURE get_emp_names ( dept_num IN NUMBER ) IS emp_name VARCHAR2(10); CURSOR c1 (dept_num NUMBER) IS SELECT LAST_NAME FROM EMPLOYEES WHERE DEPARTMENT_ID = dept_num; BEGIN OPEN c1(dept_num); LOOP FETCH c1 INTO emp_name; EXIT WHEN C1%NOTFOUND; DBMS_OUTPUT.PUT_LINE(emp_name); END LOOP; CLOSE c1; END; / The formal parameters of a subprogram have three major attributes, described in Table 6–1. Table 6–1 Attributes of Subprogram Parameters Parameter Attribute Description Name This must be a legal PL/SQL identifier. Mode This indicates whether the parameter is an input-only parameter (IN), an output-only parameter (OUT), or is both an input and an output parameter (IN OUT). If the mode is not specified, then IN is assumed. Data Type This is a standard PL/SQL data type. Topics: ■ Parameter Modes ■ Parameter Data Types ■ %TYPE and %ROWTYPE Attributes Coding PL/SQL Subprograms and Packages 6-5 Overview of PL/SQL Units ■ Passing Composite Variables as Parameters ■ Initial Parameter Values Parameter Modes Parameter modes define the action of formal parameters. You can use the three parameter modes, IN (the default), OUT, and IN OUT, with any subprogram. Avoid using the OUT and IN OUT modes with functions. Good programming practice dictates that a function returns a single value and does not change the values of variables that are not local to the subprogram. Oracle Database PL/SQL Language Reference for details about parameter modes See Also: Parameter Data Types The data type of a formal parameter consists of one of these: ■ An unconstrained type name, such as NUMBER or VARCHAR2. ■ A type that is constrained using the %TYPE or %ROWTYPE attributes. Numerically constrained types such as NUMBER(2) or VARCHAR2(20) are not allowed in a parameter list. Note: %TYPE and %ROWTYPE Attributes Use the type attributes %TYPE and %ROWTYPE to constrain the parameter. For example, the procedure heading in Example 6–4 can be written as follows: PROCEDURE get_emp_names(dept_num IN EMPLOYEES.DEPARTMENT_ID%TYPE) This gives the dept_num parameter the same data type as the DEPARTMENT_ID column in the EMPLOYEES table. The column and table must be available when a declaration using %TYPE (or %ROWTYPE) is elaborated. Using %TYPE is recommended, because if the type of the column in the table changes, it is not necessary to change the application code. If the get_emp_names procedure is part of a package, you can use previously-declared public (package) variables to constrain its parameter data types. For example: dept_number NUMBER(2); ... PROCEDURE get_emp_names(dept_num IN dept_number%TYPE); Use the %ROWTYPE attribute to create a record that contains all the columns of the specified table. The procedure in Example 6–5 returns all the columns of the EMPLOYEES table in a PL/SQL record for the given employee ID. Example 6–5 %TYPE and %ROWTYPE Attributes CREATE OR REPLACE PROCEDURE get_emp_rec ( emp_number IN EMPLOYEES.EMPLOYEE_ID%TYPE, emp_info OUT EMPLOYEES%ROWTYPE ) IS BEGIN SELECT * INTO emp_info FROM EMPLOYEES WHERE EMPLOYEE_ID = emp_number; END; / 6-6 Oracle Database Advanced Application Developer's Guide Overview of PL/SQL Units Invoke procedure from PL/SQL block: DECLARE emp_row EMPLOYEES%ROWTYPE; BEGIN get_emp_rec(206, emp_row); DBMS_OUTPUT.PUT('EMPLOYEE_ID: ' || emp_row.EMPLOYEE_ID); DBMS_OUTPUT.NEW_LINE; DBMS_OUTPUT.PUT('FIRST_NAME: ' || emp_row.FIRST_NAME); DBMS_OUTPUT.NEW_LINE; DBMS_OUTPUT.PUT('LAST_NAME: ' || emp_row.LAST_NAME); DBMS_OUTPUT.NEW_LINE; DBMS_OUTPUT.PUT('EMAIL: ' || emp_row.EMAIL); DBMS_OUTPUT.NEW_LINE; DBMS_OUTPUT.PUT('PHONE_NUMBER: ' || emp_row.PHONE_NUMBER); DBMS_OUTPUT.NEW_LINE; DBMS_OUTPUT.PUT('HIRE_DATE: ' || emp_row.HIRE_DATE); DBMS_OUTPUT.NEW_LINE; DBMS_OUTPUT.PUT('JOB_ID: ' || emp_row.JOB_ID); DBMS_OUTPUT.NEW_LINE; DBMS_OUTPUT.PUT('SALARY: ' || emp_row.SALARY); DBMS_OUTPUT.NEW_LINE; DBMS_OUTPUT.PUT('COMMISSION_PCT: ' || emp_row.COMMISSION_PCT); DBMS_OUTPUT.NEW_LINE; DBMS_OUTPUT.PUT('MANAGER_ID: ' || emp_row.MANAGER_ID); DBMS_OUTPUT.NEW_LINE; DBMS_OUTPUT.PUT('DEPARTMENT_ID: ' || emp_row.DEPARTMENT_ID); DBMS_OUTPUT.NEW_LINE; END; / Result: EMPLOYEE_ID: 206 FIRST_NAME: William LAST_NAME: Gietz EMAIL: WGIETZ PHONE_NUMBER: 515.123.8181 HIRE_DATE: 07-JUN-02 JOB_ID: AC_ACCOUNT SALARY: 8300 COMMISSION_PCT: MANAGER_ID: 205 DEPARTMENT_ID: 110 Stored functions can return values that are declared using %ROWTYPE. For example: FUNCTION get_emp_rec (dept_num IN EMPLOYEES.DEPARTMENT_ID%TYPE) RETURN EMPLOYEES%ROWTYPE IS ... Passing Composite Variables as Parameters You can pass PL/SQL composite variables (collections and records) as parameters to stored subprograms. If the subprogram is remote, you must create a redundant loop-back DBLINK, so that when the remote subprogram compiles, the type checker that verifies the source uses the same definition of the user-defined composite variable type as the invoker uses. Initial Parameter Values Parameters can take initial values. Use either the assignment operator or the DEFAULT keyword to give a parameter an initial value. For example, these are equivalent: Coding PL/SQL Subprograms and Packages 6-7 Overview of PL/SQL Units PROCEDURE Get_emp_names (Dept_num IN NUMBER := 20) IS ... PROCEDURE Get_emp_names (Dept_num IN NUMBER DEFAULT 20) IS ... When a parameter takes an initial value, it can be omitted from the actual parameter list when you invoke the subprogram. When you do specify the parameter value on the invocation, it overrides the initial value. Unlike in an anonymous PL/SQL block, you do not use the keyword DECLARE before the declarations of variables, cursors, and exceptions in a stored subprogram. In fact, it is an error to use it. Note: Creating Subprograms Use a text editor to write the subprogram. Then, using an interactive tool such as SQL*Plus, load the text file containing the procedure by entering: @get_emp This loads the procedure into the current schema from the get_emp.sql file (.sql is the default file extension). The slash (/) after the code is not part of the code, it only activates the loading of the procedure. Caution: When developing a subprogram, it is usually preferable to use the statement CREATE OR REPLACE PROCEDURE or CREATE OR REPLACE FUNCTION. This statement replaces any previous version of that subprogram in the same schema with the newer version, but without warning. You can use either the keyword IS or AS after the subprogram parameter list. See Also: ■ ■ Oracle Database SQL Language Reference for the syntax of the CREATE FUNCTION statement Oracle Database SQL Language Reference for the syntax of the CREATE PROCEDURE statement Privileges Needed To create a subprogram, a package specification, or a package body, you must meet these prerequisites: ■ You must have the CREATE PROCEDURE system privilege to create a subprogram or package in your schema, or the CREATE ANY PROCEDURE system privilege to create a subprogram or package in another user's schema. In either case, the package body must be created in the same schema as the package. To create without errors (to compile the subprogram or package successfully) requires these additional privileges: Note: ■ ■ The owner of the subprogram or package must be explicitly granted the necessary object privileges for all objects referenced within the body of the code. The owner cannot obtain required privileges through roles. 6-8 Oracle Database Advanced Application Developer's Guide Overview of PL/SQL Units If the privileges of the owner of a subprogram or package change, then the subprogram must be reauthenticated before it is run. If a necessary privilege to a referenced object is revoked from the owner of the subprogram or package, then the subprogram cannot be run. The EXECUTE privilege on a subprogram gives a user the right to run a subprogram owned by another user. Privileged users run the subprogram under the security domain of the owner of the subprogram. Therefore, users need not be granted the privileges to the objects referenced by a subprogram. This allows for more disciplined and efficient security strategies with database applications and their users. Furthermore, all subprograms and packages are stored in the data dictionary (in the SYSTEM tablespace). No quota controls the amount of space available to a user who creates subprograms and packages. Altering Subprograms To alter a subprogram, you must first drop it using the DROP PROCEDURE or DROP FUNCTION statement, then re-create it using the CREATE PROCEDURE or CREATE FUNCTION statement. Alternatively, use the CREATE OR REPLACE PROCEDURE or CREATE OR REPLACE FUNCTION statement, which first drops the subprogram if it exists, then re-creates it as specified. Caution: The subprogram is dropped without warning. Dropping Subprograms and Packages A standalone subprogram, a standalone function, a package body, or an entire package can be dropped using the SQL statements DROP PROCEDURE, DROP FUNCTION, DROP PACKAGE BODY, and DROP PACKAGE, respectively. A DROP PACKAGE statement drops both the specification and body of a package. This statement drops the Old_sal_raise procedure in your schema: DROP PROCEDURE Old_sal_raise; Privileges Needed To drop a subprogram or package, the subprogram or package must be in your schema, or you must have the DROP ANY PROCEDURE privilege. An individual subprogram within a package cannot be dropped; the containing package specification and body must be re-created without the subprograms to be dropped. External Subprograms A PL/SQL subprogram running on an Oracle Database instance can invoke an external subprogram written in a third-generation language (3GL). The 3GL subprogram runs in a separate address space from that of the database. See Also: Chapter 14, "Developing Applications with Multiple Programming Languages," for information about external subprograms PL/SQL Function Result Cache Using the PL/SQL function result cache can save significant space and time. Each time a result-cached PL/SQL function is invoked with different parameter values, those parameters and their result are stored in the cache. Subsequently, when the same function is invoked with the same parameter values, the result is retrieved from the Coding PL/SQL Subprograms and Packages 6-9 Overview of PL/SQL Units cache, instead of being recomputed. Because the cache is stored in a shared global area (SGA), it is available to any session that runs your application. If a database object that was used to compute a cached result is updated, the cached result becomes invalid and must be recomputed. The best candidates for result-caching are functions that are invoked frequently but depend on information that changes infrequently or never. For more information about the PL/SQL function result cache, see Oracle Database PL/SQL Language Reference. PL/SQL Packages A package is a collection of related program objects (for example, subprogram, variables, constants, cursors, and exceptions) stored as a unit in the database. Using packages is an alternative to creating subprograms as standalone schema objects. Packages have many advantages over standalone subprograms. For example, they: ■ Let you organize your application development more efficiently. ■ Let you grant privileges more efficiently. ■ Let you modify package objects without recompiling dependent schema objects. ■ Enable Oracle Database to read multiple package objects into memory at once. ■ ■ Can contain global variables and cursors that are available to all subprograms in the package. Let you overload subprograms. Overloading a subprogram means creating multiple subprograms with the same name in the same package, each taking arguments of different number or data type. Oracle Database PL/SQL Language Reference for more information about subprogram name overloading See Also: The specification part of a package declares the public types, variables, constants, and subprograms that are visible outside the immediate scope of the package. The body of a package defines both the objects declared in the specification and private objects that are not visible to applications outside the package. Example 6–6 creates a package that contains one stored function and two stored procedures, and then invokes a procedure. Example 6–6 Creating PL/SQL Package and Invoking Package Subprogram -- Sequence that package function needs: CREATE SEQUENCE emp_sequence START WITH 8000 INCREMENT BY 10; -- Package specification: CREATE or REPLACE PACKAGE employee_management IS FUNCTION hire_emp ( firstname VARCHAR2, lastname VARCHAR2, email VARCHAR2, phone VARCHAR2, 6-10 Oracle Database Advanced Application Developer's Guide Overview of PL/SQL Units hiredate DATE, job VARCHAR2, sal NUMBER, comm NUMBER, mgr NUMBER, deptno NUMBER ) RETURN NUMBER; PROCEDURE fire_emp( emp_id IN NUMBER ); PROCEDURE sal_raise ( emp_id IN NUMBER, sal_incr IN NUMBER ); END employee_management; / -- Package body: CREATE or REPLACE PACKAGE BODY employee_management IS FUNCTION hire_emp ( firstname VARCHAR2, lastname VARCHAR2, email VARCHAR2, phone VARCHAR2, hiredate DATE, job VARCHAR2, sal NUMBER, comm NUMBER, mgr NUMBER, deptno NUMBER ) RETURN NUMBER IS new_empno NUMBER(10); BEGIN new_empno := emp_sequence.NEXTVAL; INSERT INTO EMPLOYEES ( employee_id, first_name, last_name, email, phone_number, hire_date, job_id, salary, commission_pct, manager_id, department_id ) VALUES ( new_empno, firstname, lastname, email, phone, hiredate, job, Coding PL/SQL Subprograms and Packages 6-11 Overview of PL/SQL Units sal, comm, mgr, deptno ); RETURN (new_empno); END hire_emp; PROCEDURE fire_emp ( emp_id IN NUMBER ) IS BEGIN DELETE FROM EMPLOYEES WHERE EMPLOYEE_ID = emp_id; IF SQL%NOTFOUND THEN raise_application_error( -20011, 'Invalid Employee Number: ' || TO_CHAR(Emp_id) ); END IF; END fire_emp; PROCEDURE sal_raise ( emp_id IN NUMBER, sal_incr IN NUMBER ) IS BEGIN UPDATE EMPLOYEES SET SALARY = SALARY + sal_incr WHERE EMPLOYEE_ID = emp_id; IF SQL%NOTFOUND THEN raise_application_error( -20011, 'Invalid Employee Number: ' || TO_CHAR(Emp_id) ); END IF; END sal_raise; END employee_management; / Invoke package procedures: DECLARE empno NUMBER(6); sal NUMBER(6); temp NUMBER(6); BEGIN empno := employee_management.hire_emp( 'John', 'Doe', 'john.doe@company.com', '555-0100', '20-SEP-07', 'ST_CLERK', 2500, 0, 100, 20); 6-12 Oracle Database Advanced Application Developer's Guide Overview of PL/SQL Units DBMS_OUTPUT.PUT_LINE('New employee ID is ' || TO_CHAR(empno)); END; / PL/SQL Object Size Limits The size limit for PL/SQL stored database objects such as subprograms, triggers, and packages is the size of the Descriptive Intermediate Attributed Notation for Ada (DIANA) code in the shared pool in bytes. The Linux and UNIX limit on the size of the flattened DIANA/code size is 64K but the limit might be 32K on desktop platforms. The most closely related number that a user can access is the PARSED_SIZE in the static data dictionary view *_OBJECT_SIZE. That gives the size of the DIANA in bytes as stored in the SYS.IDL_xxx$ tables. This is not the size in the shared pool. The size of the DIANA part of PL/SQL code (used during compilation) is significantly larger in the shared pool than it is in the system table. Creating Packages Each part of a package is created with a different statement. Create the package specification using the CREATE PACKAGE statement. The CREATE PACKAGE statement declares public package objects. To create a package body, use the CREATE PACKAGE BODY statement. The CREATE PACKAGE BODY statement defines the procedural code of the public subprograms declared in the package specification. You can also define private, or local, package subprograms, and variables in a package body. These objects can only be accessed by other subprograms in the body of the same package. They are not visible to external users, regardless of the privileges they hold. It is often more convenient to add the OR REPLACE clause in the CREATE PACKAGE or CREATE PACKAGE BODY statements when you are first developing your application. The effect of this option is to drop the package or the package body without warning. The CREATE statements are: CREATE OR REPLACE PACKAGE Package_name AS ... and CREATE OR REPLACE PACKAGE BODY Package_name AS ... Creating Package Objects The body of a package can contain: ■ Subprograms declared in the package specification. ■ Definitions of cursors declared in the package specification. ■ Local subprograms, not declared in the package specification. ■ Local variables. Subprograms, cursors, and variables that are declared in the package specification are global. They can be invoked, or used, by external users that have EXECUTE permission for the package or that have EXECUTE ANY PROCEDURE privileges. When you create the package body, ensure that each subprogram that you define in the body has the same parameters, by name, data type, and mode, as the declaration in the package specification. For functions in the package body, the parameters and the return type must agree in name and type. Coding PL/SQL Subprograms and Packages 6-13 Overview of PL/SQL Units Privileges to Needed to Create or Drop Packages The privileges required to create or drop a package specification or package body are the same as those required to create or drop a standalone subprogram. See "Creating Subprograms" on page 6-8 and "Dropping Subprograms and Packages" on page 6-9. Naming Packages and Package Objects The names of a package and all public objects in the package must be unique within a given schema. The package specification and its body must have the same name. All package constructs must have unique names within the scope of the package, unless overloading of subprogram names is desired. Package Invalidations and Session State Each session that references a package object has its own instance of the corresponding package, including persistent state for any public and private variables, cursors, and constants. If any of the session's instantiated packages (specification or body) are invalidated, then all package instances in the session are invalidated and recompiled. Therefore, the session state is lost for all package instances in the session. When a package in a given session is invalidated, the session receives ORA-04068 the first time it attempts to use any object of the invalid package instance. The second time a session makes such a package call, the package is reinstantiated for the session without error. However, if you handle this error in your application, be aware of the following: ■ ■ For optimal performance, Oracle Database returns this error message only when the package state is discarded. When a subprogram in one package invokes a subprogram in another package, the session state is lost for both packages. If a server session traps ORA-04068, then ORA-04068 is not raised for the client session. Therefore, when the client session attempts to use an object in the package, the package is not reinstantiated. To reinstantiate the package, the client session must either reconnect to the database or recompile the package. In Example 6–7, the RAISE statement raises the current exception, ORA-04068, which is the cause of the exception being handled, ORA-06508. ORA-04068 is not trapped. Example 6–7 Raising ORA-04068 PROCEDURE p IS package_exception EXCEPTION; PRAGMA EXCEPTION_INIT (package_exception, -6508); BEGIN ... EXCEPTION WHEN package_exception THEN RAISE; END; / In Example 6–8, the RAISE statement raises the exception ORA-20001 in response to ORA-06508, instead of the current exception, ORA-04068. ORA-04068 is trapped. When this happens, the ORA-04068 error is masked, which stops the package from being reinstantiated. Example 6–8 Trapping ORA-04068 PROCEDURE p IS package_exception EXCEPTION; 6-14 Oracle Database Advanced Application Developer's Guide Overview of PL/SQL Units other_exception EXCEPTION; PRAGMA EXCEPTION_INIT (package_exception, -6508); PRAGMA EXCEPTION_INIT (other_exception, -20001); BEGIN ... EXCEPTION WHEN package_exception THEN ... RAISE other_exception; END; / In most production environments, DDL operations that can cause invalidations are usually performed during inactive working hours; therefore, this situation might not be a problem for end-user applications. However, if package invalidations are common in your system during working hours, then you might want to code your applications to handle this error when package calls are made. Packages Supplied with Oracle Database There are many packages provided with Oracle Database, either to extend the functionality of the database or to give PL/SQL access to SQL features. You can invoke these packages from your application. See Also: Oracle Database PL/SQL Packages and Types Reference for an overview of these Oracle Database packages Overview of Bulk Binding Oracle Database uses two engines to run PL/SQL blocks and subprograms. The PL/SQL engine runs procedural statements, while the SQL engine runs SQL statements. During execution, every SQL statement causes a context switch between the two engines, resulting in performance overhead. Performance can be improved substantially by minimizing the number of context switches required to run a particular block or subprogram. When a SQL statement runs inside a loop that uses collection elements as bind variables, the large number of context switches required by the block can cause poor performance. Collections include: ■ Varrays ■ Nested tables ■ Index-by tables ■ Host arrays Binding is the assignment of values to PL/SQL variables in SQL statements. Bulk binding is binding an entire collection at once. Bulk binds pass the entire collection back and forth between the two engines in a single operation. Typically, using bulk binds improves performance for SQL statements that affect four or more database rows. The more rows affected by a SQL statement, the greater the performance gain from bulk binds. Coding PL/SQL Subprograms and Packages 6-15 Overview of PL/SQL Units This section provides an overview of bulk binds to help you decide whether to use them in your PL/SQL applications. For detailed information about using bulk binds, including ways to handle exceptions that occur in the middle of a bulk bind operation, see Oracle Database PL/SQL Language Reference. Note: Parallel DML statements are disabled with bulk binds. When to Use Bulk Binds Consider using bulk binds to improve the performance of: ■ DML Statements that Reference Collections ■ SELECT Statements that Reference Collections ■ FOR Loops that Reference Collections and Return DML DML Statements that Reference Collections A bulk bind, which uses the FORALL keyword, can improve the performance of INSERT, UPDATE, or DELETE statements that reference collection elements. The PL/SQL block in Example 6–9 increases the salary for employees whose manager's ID number is 7902, 7698, or 7839, with and without bulk binds. Without bulk bind, PL/SQL sends a SQL statement to the SQL engine for each updated employee, leading to context switches that slow performance. Example 6–9 DML Statements that Reference Collections DECLARE TYPE numlist IS VARRAY (100) OF NUMBER; id NUMLIST := NUMLIST(7902, 7698, 7839); BEGIN -- Efficient method, using bulk bind: FORALL i IN id.FIRST..id.LAST UPDATE EMPLOYEES SET SALARY = 1.1 * SALARY WHERE MANAGER_ID = id(i); -- Slower method: FOR i IN id.FIRST..id.LAST LOOP UPDATE EMPLOYEES SET SALARY = 1.1 * SALARY WHERE MANAGER_ID = id(i); END LOOP; END; / SELECT Statements that Reference Collections The BULK COLLECT INTO clause can improve the performance of queries that reference collections. You can use BULK COLLECT INTO with tables of scalar values, or tables of %TYPE values. The PL/SQL block in Example 6–10 queries multiple values into PL/SQL tables, with and without bulk binds. Without bulk bind, PL/SQL sends a SQL statement to the SQL engine for each selected employee, leading to context switches that slow performance. 6-16 Oracle Database Advanced Application Developer's Guide Overview of PL/SQL Units Example 6–10 SELECT Statements that Reference Collections DECLARE TYPE var_tab IS TABLE OF VARCHAR2(20) INDEX BY PLS_INTEGER; empno ename counter VAR_TAB; VAR_TAB; NUMBER; CURSOR c IS SELECT EMPLOYEE_ID, LAST_NAME FROM EMPLOYEES WHERE MANAGER_ID = 7698; BEGIN -- Efficient method, using bulk bind: SELECT EMPLOYEE_ID, LAST_NAME BULK COLLECT INTO empno, ename FROM EMPLOYEES WHERE MANAGER_ID = 7698; -- Slower method: counter := 1; FOR rec IN c LOOP empno(counter) := rec.EMPLOYEE_ID; ename(counter) := rec.LAST_NAME; counter := counter + 1; END LOOP; END; / FOR Loops that Reference Collections and Return DML You can use the FORALL keyword with the BULK COLLECT INTO keywords to improve the performance of FOR loops that reference collections and return DML. The PL/SQL block in Example 6–11 updates the EMPLOYEES table by computing bonuses for a collection of employees. Then it returns the bonuses in a column called bonus_list_inst. The actions are performed with and without bulk binds. Without bulk bind, PL/SQL sends a SQL statement to the SQL engine for each updated employee, leading to context switches that slow performance. Example 6–11 FOR Loops that Reference Collections and Return DML DECLARE TYPE emp_list IS VARRAY(100) OF EMPLOYEES.EMPLOYEE_ID%TYPE; empids emp_list := emp_list(182, 187, 193, 200, 204, 206); TYPE bonus_list IS TABLE OF EMPLOYEES.SALARY%TYPE; bonus_list_inst bonus_list; BEGIN -- Efficient method, using bulk bind: FORALL i IN empids.FIRST..empids.LAST UPDATE EMPLOYEES SET SALARY = 0.1 * SALARY WHERE EMPLOYEE_ID = empids(i) RETURNING SALARY BULK COLLECT INTO bonus_list_inst; Coding PL/SQL Subprograms and Packages 6-17 Compiling PL/SQL Subprograms for Native Execution -- Slower method: FOR i IN empids.FIRST..empids.LAST LOOP UPDATE EMPLOYEES SET SALARY = 0.1 * SALARY WHERE EMPLOYEE_ID = empids(i) RETURNING SALARY INTO bonus_list_inst(i); END LOOP; END; / Triggers A trigger is a special kind of PL/SQL anonymous block. You can define triggers to fire before or after SQL statements, either on a statement level or for each row that is affected. You can also define INSTEAD OF triggers or system triggers (triggers on DATABASE and SCHEMA). Oracle Database PL/SQL Language Reference for more information about triggers See Also: Compiling PL/SQL Subprograms for Native Execution You can speed up PL/SQL subprograms by compiling them into native code residing in shared libraries. You can use native compilation with both the supplied packages and the subprograms you write yourself. Subprograms compiled this way work in all server environments, such as the shared server configuration (formerly known as multithreaded server) and Oracle Real Application Clusters (Oracle RAC). This technique is most effective for computation-intensive subprograms that do not spend much time running SQL, because it can do little to speed up SQL statements invoked from these subprograms. With Java, you can use the ncomp tool to compile your own packages and classes. See Also: ■ ■ Oracle Database PL/SQL Language Reference for details on PL/SQL native compilation Oracle Database Java Developer's Guide for details on Java native compilation Cursor Variables A cursor is a static object; a cursor variable is a pointer to a cursor. Because cursor variables are pointers, they can be passed and returned as parameters to subprograms. A cursor variable can also refer to different cursors in its lifetime. Additional advantages of cursor variables include: ■ Encapsulation Queries are centralized in the stored subprogram that opens the cursor variable. ■ Easy maintenance If you must change the cursor, then you only make the change in the stored subprogram, not in each application. 6-18 Oracle Database Advanced Application Developer's Guide Cursor Variables ■ Convenient security The user of the application is the user name used when the application connects to the server. The user must have EXECUTE permission on the stored subprogram that opens the cursor. But, the user need not have READ permission on the tables used in the query. Use this capability to limit access to the columns in the table and access to other stored subprograms. Oracle Database PL/SQL Language Reference for more information about cursor variables See Also: Topics: ■ Declaring and Opening Cursor Variables ■ Examples of Cursor Variables Declaring and Opening Cursor Variables Memory is usually allocated for a cursor variable in the client application using the appropriate ALLOCATE statement. In Pro*C, use the EXEC SQL ALLOCATE cursor_name statement. In OCI, use the Cursor Data Area. You can also use cursor variables in applications that run entirely in a single server session. You can declare cursor variables in PL/SQL subprograms, open them, and use them as parameters for other PL/SQL subprograms. Examples of Cursor Variables This section has these examples of cursor variable usage in PL/SQL: ■ Example 6–12, "Fetching Data with Cursor Variable" ■ Example 6–13, "Cursor Variable with Discriminator" See Also: For additional cursor variable examples that use programmatic interfaces: ■ Pro*COBOL Programmer's Guide ■ Oracle Call Interface Programmer's Guide Example 6–12 creates a package that defines a PL/SQL cursor variable type and two procedures, and then invokes the procedures from a PL/SQL block. The first procedure opens a cursor variable using a bind variable in the WHERE clause. The second procedure uses a cursor variable to fetch rows from the EMPLOYEES table. Example 6–12 Fetching Data with Cursor Variable CREATE OR REPLACE PACKAGE emp_data AS TYPE emp_val_cv_type IS REF CURSOR RETURN EMPLOYEES%ROWTYPE; PROCEDURE open_emp_cv ( emp_cv IN OUT emp_val_cv_type, dept_number IN EMPLOYEES.DEPARTMENT_ID%TYPE ); PROCEDURE fetch_emp_data ( emp_cv IN emp_val_cv_type, emp_row OUT EMPLOYEES%ROWTYPE Coding PL/SQL Subprograms and Packages 6-19 Cursor Variables ); END emp_data; / CREATE OR REPLACE PACKAGE BODY emp_data AS PROCEDURE open_emp_cv ( emp_cv IN OUT emp_val_cv_type, dept_number IN EMPLOYEES.DEPARTMENT_ID%TYPE ) IS BEGIN OPEN emp_cv FOR SELECT * FROM EMPLOYEES WHERE DEPARTMENT_ID = dept_number ORDER BY last_name; END open_emp_cv; PROCEDURE fetch_emp_data ( emp_cv IN emp_val_cv_type, emp_row OUT EMPLOYEES%ROWTYPE ) IS BEGIN FETCH emp_cv INTO emp_row; END fetch_emp_data; END emp_data; / Invoke package procedures: DECLARE emp_curs dept_number emp_row emp_data.emp_val_cv_type; EMPLOYEES.DEPARTMENT_ID%TYPE; EMPLOYEES%ROWTYPE; BEGIN dept_number := 20; -- Open cursor, using variable: emp_data.open_emp_cv(emp_curs, dept_number); -- Fetch and display data: LOOP emp_data.fetch_emp_data(emp_curs, emp_row); EXIT WHEN emp_curs%NOTFOUND; DBMS_OUTPUT.PUT(emp_row.LAST_NAME || ' '); DBMS_OUTPUT.PUT_LINE(emp_row.SALARY); END LOOP; END; / In Example 6–13, the procedure opens a cursor variable for either the EMPLOYEES table or the DEPARTMENTS table, depending on the value of the parameter discrim. The anonymous block invokes the procedure to open the cursor variable for the EMPLOYEES table, but fetches from the DEPARTMENTS table, which raises the predefined exception ROWTYPE_MISMATCH. 6-20 Oracle Database Advanced Application Developer's Guide Handling PL/SQL Compile-Time Errors Example 6–13 Cursor Variable with Discriminator CREATE OR REPLACE PACKAGE emp_dept_data AS TYPE cv_type IS REF CURSOR; PROCEDURE open_cv ( cv IN OUT cv_type, discrim IN POSITIVE ); END emp_dept_data; / CREATE OR REPLACE PACKAGE BODY emp_dept_data AS PROCEDURE open_cv ( cv IN OUT cv_type, discrim IN POSITIVE) IS BEGIN IF discrim = 1 THEN OPEN cv FOR SELECT * FROM EMPLOYEES ORDER BY employee_id; ELSIF discrim = 2 THEN OPEN cv FOR SELECT * FROM DEPARTMENTS ORDER BY department_id; END IF; END open_cv; END emp_dept_data; / Invoke procedure open_cv from anonymous block: DECLARE emp_rec EMPLOYEES%ROWTYPE; dept_rec DEPARTMENTS%ROWTYPE; cv Emp_dept_data.CV_TYPE; BEGIN emp_dept_data.open_cv(cv, 1); -- Open cv for EMPLOYEES fetch. FETCH cv INTO dept_rec; -- Fetch from DEPARTMENTS. DBMS_OUTPUT.PUT(dept_rec.DEPARTMENT_ID); DBMS_OUTPUT.PUT_LINE(' ' || dept_rec.LOCATION_ID); EXCEPTION WHEN ROWTYPE_MISMATCH THEN BEGIN DBMS_OUTPUT.PUT_LINE ('Row type mismatch, fetching EMPLOYEES data ...'); FETCH cv INTO emp_rec; DBMS_OUTPUT.PUT(emp_rec.DEPARTMENT_ID); DBMS_OUTPUT.PUT_LINE(' ' || emp_rec.LAST_NAME); END; END; / Result: Row type mismatch, fetching EMPLOYEES data ... 90 King Handling PL/SQL Compile-Time Errors To list compile-time errors, query the static data dictionary view *_ERRORS. From these views, you can retrieve original source code. The error text associated with the compilation of a subprogram is updated when the subprogram is replaced, and it is deleted when the subprogram is dropped. Coding PL/SQL Subprograms and Packages 6-21 Handling Runtime PL/SQL Errors SQL*Plus issues a warning message for compile-time errors, but for more information about them, you must use the command SHOW ERRORS. Before issuing the SHOW ERRORS statement, use the SET LINESIZE statement to get long lines on output. The value 132 is usually a good choice. For example: Note: SET LINESIZE 132 Example 6–14 has two compile-time errors: WHER should be WHERE, and END should be followed by a semicolon. SHOW ERRORS shows the line, column, and description of each error. Example 6–14 Compile-Time Errors CREATE OR REPLACE PROCEDURE fire_emp ( emp_id NUMBER ) AS BEGIN DELETE FROM EMPLOYEES WHER EMPLOYEE_ID = Emp_id; END / Result: Warning: Procedure created with compilation errors. Command: SHOW ERRORS; Result: Errors for PROCEDURE FIRE_EMP: LINE/COL ERROR -------- ----------------------------------------------------------------5/3 PL/SQL: SQL Statement ignored 6/8 PL/SQL: ORA-00933: SQL command not properly ended 7/3 PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following: ;current delete exists prior The symbol ";" was substituted for "end-of-file" to continue. See Also: ■ ■ Oracle Database Reference for more information about the static data dictionary view *_SOURCE SQL*Plus User's Guide and Reference for more information about the SHOW ERRORS statement Handling Runtime PL/SQL Errors Oracle Database allows user-defined errors in PL/SQL code to be handled so that user-specified error numbers and messages are returned to the client application, which can handle the error. 6-22 Oracle Database Advanced Application Developer's Guide Handling Runtime PL/SQL Errors User-specified error messages are returned using the RAISE_APPLICATION_ERROR procedure. For example: RAISE_APPLICATION_ERROR(error_number, 'text', keep_error_stack) This procedure stops subprogram execution, rolls back any effects of the subprogram, and returns a user-specified error number and message (unless the error is trapped by an exception handler). error_number must be in the range of -20000 to -20999. Use error number -20000 as a generic number for messages where it is important to relay information to the user, but having a unique error number is not required. Text must be a character expression, 2 KB or less (longer messages are ignored). To add the error to errors on the stack, set Keep_error_stack to TRUE; to replace the existing errors, set it to FALSE (the default). Some Oracle Database packages, such as DBMS_OUTPUT, DBMS_DESCRIBE, and DBMS_ALERT, use application error numbers in the range -20000 to -20005. See the descriptions of these packages for more information. Note: The RAISE_APPLICATION_ERROR procedure is often used in exception handlers or in the logic of PL/SQL code. For example, this exception handler selects the string for the associated user-defined error message and invokes the RAISE_APPLICATION_ERROR procedure: ... WHEN NO_DATA_FOUND THEN SELECT Error_string INTO Message FROM Error_table, V$NLS_PARAMETERS V WHERE Error_number = -20101 AND Lang = v.value AND v.parameter = "NLS_LANGUAGE"; Raise_application_error(-20101, Message); ... Topics: ■ Declaring Exceptions and Exception Handlers ■ Unhandled Exceptions ■ Handling Errors in Distributed Queries ■ Handling Errors in Remote Subprograms Declaring Exceptions and Exception Handlers User-defined exceptions are explicitly defined and raised within the PL/SQL block, to process errors specific to the application. When an exception is raised, the usual execution of the PL/SQL block stops, and an exception handler is invoked. Specific exception handlers can be written to handle any internal or user-defined exception. Application code can check for a condition that requires special attention using an IF statement. If there is an error condition, then two options are available: ■ Enter a RAISE statement that names the appropriate exception. A RAISE statement stops the execution of the subprogram, and control passes to an exception handler (if any). Coding PL/SQL Subprograms and Packages 6-23 Handling Runtime PL/SQL Errors ■ Invoke the RAISE_APPLICATION_ERROR procedure to return a user-specified error number and message. You can also define an exception handler to handle user-specified error messages. For example, Figure 6–1 shows: ■ ■ ■ An exception and associated exception handler in a subprogram A conditional statement that checks for an error (such as transferring funds not available) and enters a user-specified error number and message within a trigger How user-specified error numbers are returned to the invoking environment (in this case, a subprogram), and how that application can define an exception that corresponds to the user-specified error number Declare a user-defined exception in a subprogram or package body (private exceptions), or in the specification of a package (public exceptions). Define an exception handler in the body of a subprogram (standalone or package). Figure 6–1 Exceptions and User-Defined Errors Procedure fire_emp(empid NUMBER) IS invalid_empid EXCEPTION; PRAGMA EXCEPTION_INIT(invalid_empid, –20101); BEGIN DELETE FROM emp WHERE empno = empid; EXCEPTION WHEN invlid_empid THEN INSERT INTO emp_audit VALUES (empid, ’Fired before probation ended’); END; Table EMP Error number returned to calling environment TRIGGER emp_probation BEFORE DELETE ON emp FOR EACH ROW BEGIN IF (sysdate–:old.hiredate)<30 THEN raise_application_error(20101, ’Employee’||old.ename||’ on probation’) END IF; END; Unhandled Exceptions In database PL/SQL units, an unhandled user-error condition or internal error condition that is not trapped by an appropriate exception handler causes the implicit rollback of the program unit. If the program unit includes a COMMIT statement before the point at which the unhandled exception is observed, then the implicit rollback of the program unit can only be completed back to the previous COMMIT. Additionally, unhandled exceptions in database-stored PL/SQL units propagate back to client-side applications that invoke the containing program unit. In such an application, only the application program unit invocation is rolled back (not the entire application program unit), because it is submitted to the database as a SQL statement. If unhandled exceptions in database PL/SQL units are propagated back to database applications, modify the database PL/SQL code to handle the exceptions. Your application can also trap for unhandled exceptions when invoking database program units and handle such errors appropriately. 6-24 Oracle Database Advanced Application Developer's Guide Handling Runtime PL/SQL Errors Handling Errors in Distributed Queries You can use a trigger or a stored subprogram to create a distributed query. This distributed query is decomposed by the local Oracle Database instance into a corresponding number of remote queries, which are sent to the remote nodes for execution. The remote nodes run the queries and send the results back to the local node. The local node then performs any necessary post-processing and returns the results to the user or application. If a portion of a distributed statement fails, possibly from a constraint violation, then Oracle Database returns ORA-02055. Subsequent statements, or subprogram invocations, return ORA-02067 until a rollback or a rollback to savepoint is entered. Design your application to check for any returned error messages that indicates that a portion of the distributed update has failed. If you detect a failure, rollback the entire transaction (or rollback to a savepoint) before allowing the application to proceed. Handling Errors in Remote Subprograms When a subprogram is run locally or at a remote location, these types of exceptions can occur: ■ PL/SQL user-defined exceptions, which must be declared using the keyword EXCEPTION ■ PL/SQL predefined exceptions, such as NO_DATA_FOUND ■ SQL errors, such as ORA-00900 ■ Application exceptions, which are generated using the RAISE_APPLICATION_ERROR procedure. When using local subprograms, all of these messages can be trapped by writing an exception handler, such as: EXCEPTION WHEN ZERO_DIVIDE THEN /* Handle the exception */ The WHEN clause requires an exception name. If the exception that is raised does not have a name, such as those generated with RAISE_APPLICATION_ERROR, then one can be assigned using PRAGMA_EXCEPTION_INIT. For example: DECLARE ... Null_salary EXCEPTION; PRAGMA EXCEPTION_INIT(Null_salary, -20101); BEGIN ... RAISE_APPLICATION_ERROR(-20101, 'salary is missing'); ... EXCEPTION WHEN Null_salary THEN ... When invoking a remote subprogram, exceptions are also handled by creating a local exception handler. The remote subprogram must return an error number to the local invoking subprogram, which then handles the exception, as shown in the previous example. Because PL/SQL user-defined exceptions always return ORA-06510 to the local subprogram, these exceptions cannot be handled. All other remote exceptions can be handled in the same manner as local exceptions. Coding PL/SQL Subprograms and Packages 6-25 Debugging Stored Subprograms Debugging Stored Subprograms Compiling a stored subprogram involves fixing any syntax errors in the code. You might need to do additional debugging to ensure that the subprogram works correctly, performs well, and recovers from errors. Such debugging might involve: ■ ■ Adding extra output statements to verify execution progress and check data values at certain points within the subprogram. Running a separate debugger to analyze execution in greater detail. Topics: ■ PL/Scope ■ PL/SQL Hierarchical Profiler ■ Oracle JDeveloper ■ DBMS_OUTPUT Package ■ Privileges for Debugging PL/SQL and Java Stored Subprograms ■ Writing Low-Level Debugging Code ■ DBMS_DEBUG_JDWP Package ■ DBMS_DEBUG Package PL/Scope PL/Scope is a compiler-driven tool that collects and organizes data about user-defined identifiers from PL/SQL source code. Because PL/Scope is a compiler-driven tool, you use it through interactive development environments (such as SQL Developer and JDeveloper), rather than directly. PL/Scope enables the development of powerful and effective PL/Scope source code browsers that increase PL/SQL developer productivity by minimizing time spent browsing and understanding source code. For more information about PL/Scope, see Chapter 7, "Using PL/Scope." PL/SQL Hierarchical Profiler The PL/SQL hierarchical profiler reports the dynamic execution profile of your PL/SQL program, organized by subprogram calls. It accounts for SQL and PL/SQL execution times separately. Each subprogram-level summary in the dynamic execution profile includes information such as number of calls to the subprogram, time spent in the subprogram itself, time spent in the subprogram's subtree (that is, in its descendent subprograms), and detailed parent-children information. You can browse the generated HTML reports in any browser. The browser's navigational capabilities, combined with well chosen links, provide a powerful way to analyze performance of large applications, improve application performance, and lower development costs. For a detailed description of PL/SQL hierarchical profiler, see Chapter 8, "Using the PL/SQL Hierarchical Profiler." 6-26 Oracle Database Advanced Application Developer's Guide Debugging Stored Subprograms Oracle JDeveloper Recent releases of Oracle JDeveloper have extensive features for debugging PL/SQL, Java, and multi-language programs. You can get Oracle JDeveloper as part of various Oracle product suites. Often, a more recent release is available as a download at: http://www.oracle.com/technetwork/developer-tools/jdev/downloads/index.html DBMS_OUTPUT Package You can also debug stored subprograms and triggers using the Oracle package DBMS_ OUTPUT. Put PUT and PUT_LINE statements in your code to output the value of variables and expressions to your terminal. Privileges for Debugging PL/SQL and Java Stored Subprograms Starting with Oracle Database 10g, a new privilege model applies to debugging PL/SQL and Java code running within the database. This model applies whether you are using Oracle JDeveloper, Oracle Developer, or any of the various third-party PL/SQL or Java development environments, and it affects both the DBMS_DEBUG and DBMS_DEBUG_JDWP APIs. For a session to connect to a debugger, the effective user at the time of the connect operation must have the DEBUG CONNECT SESSION system privilege. This effective user might be the owner of a DR subprogram involved in making the connect call. When a debugger becomes connected to a session, the session login user and the enabled session-level roles are fixed as the privilege environment for that debugging connection. Any DEBUG or EXECUTE privileges needed for debugging must be granted to that combination of user and roles. ■ ■ To be able to display and change Java public variables or variables declared in a PL/SQL package specification, the debugging connection must be granted either EXECUTE or DEBUG privilege on the relevant code. To be able to either display and change private variables or breakpoint and run code lines step by step, the debugging connection must be granted DEBUG privilege on the relevant code The DEBUG privilege allows a debugging session to do anything that the subprogram being debugged could have done if that action had been included in its code. Caution: In addition to these privilege requirements, the ability to stop on individual code lines and debugger access to variables are allowed only in code compiled with debug information generated. Use the PL/SQL compilation parameter PLSQL_DEBUG and the DEBUG keyword on statements such as ALTER PACKAGE to control whether the PL/SQL compiler includes debug information in its results. If not, variables are not accessible, and neither stepping nor breakpoints stop on code lines. The PL/SQL compiler never generates debug information for code hidden with the PL/SQL wrap utility. Oracle Database PL/SQL Language Reference, for information about the wrap utility See Also: The DEBUG ANY PROCEDURE system privilege is equivalent to the DEBUG privilege granted on all objects in the database. Objects owned by SYS are included if the value of the O7_ DICTIONARY_ACCESSIBILITY parameter is TRUE. Coding PL/SQL Subprograms and Packages 6-27 Invoking Stored Subprograms A debug role mechanism is available to carry privileges needed for debugging that are not normally enabled in the session. See the documentation on the DBMS_DEBUG and DBMS_DEBUG_JDWP packages for details on how to specify a debug role and any necessary related password. The JAVADEBUGPRIV role carries the DEBUG CONNECT SESSION and DEBUG ANY PROCEDURE privileges. Grant it only with the care those privileges warrant. Granting DEBUG ANY PROCEDURE privilege, or granting DEBUG privilege on any object owned by SYS, means granting complete rights to the database. Caution: Writing Low-Level Debugging Code If you are writing code for part of a debugger, you might need to use packages such as DBMS_DEBUG_JDWP or DBMS_DEBUG. DBMS_DEBUG_JDWP Package The DBMS_DEBUG_JDWP package, provided starting with Oracle Database 9g Release 2, provides a framework for multi-language debugging that is expected to supersede the DBMS_DEBUG package over time. It is especially useful for programs that combine PL/SQL and Java. DBMS_DEBUG Package The DBMS_DEBUG package, provided starting with Oracle8i, implements server-side debuggers and provides a way to debug server-side PL/SQL units. Several of the debuggers available, such as Oracle Procedure Builder and various third-party vendor solutions, use this API. See Also: ■ ■ ■ ■ ■ ■ Oracle Procedure Builder Developer's Guide Oracle Database PL/SQL Packages and Types Reference for more information about the DBMS_DEBUG package and associated privileges Oracle Database PL/SQL Packages and Types Reference for more information about the DBMS_OUTPUT package and associated privileges The Oracle JDeveloper documentation for information about using package DBMS_DEBUG_JDWP Oracle Database SQL Language Reference for more details on privileges http://www.oracle.com/technetwork/database/features/plsql /index.html Invoking Stored Subprograms Stored PL/SQL subprograms can be invoked from many different environments. For example: ■ Interactively, using an Oracle Database tool 6-28 Oracle Database Advanced Application Developer's Guide Invoking Stored Subprograms ■ From the body of another subprogram ■ From within an application (such as a SQL*Forms or a precompiler) ■ From the body of a trigger Stored PL/SQL functions (but not procedures) can also be invoked from within SQL statements. For details, see "Invoking Stored PL/SQL Functions from SQL Statements" on page 6-35. Topics: Privileges Required to Invoke a Subprogram ■ ■ Invoking a Subprogram Interactively from Oracle Tools ■ Invoking a Subprogram from Another Subprogram ■ Invoking a Subprogram from a 3GL Application ■Oracle Database PL/SQL Language Reference for information about invoking PL/SQL subprograms, including passing parameters. See Also: ■ Oracle Database PL/SQL Language Reference for information about coding the body of a trigger Privileges Required to Invoke a Subprogram You do not need privileges to invoke: ■ Standalone subprograms that you own ■ Subprograms in packages that you own ■ Public standalone subprograms ■ Subprograms in public packages To invoke a standalone or package subprogram owned by another user: ■ ■ ■ You must have the EXECUTE privilege for the standalone subprogram or for the package containing the subprogram, or you must have the EXECUTE ANY PROCEDURE system privilege. When running a remote subprogram, you must be granted the EXECUTE privilege or EXECUTE ANY PROCEDURE system privilege directly, not through a role. You must include the name of the owner in the invocation. For example: EXECUTE jdoe.Fire_emp (1043); EXECUTE jdoe.Hire_fire.Fire_emp (1043); ■ ■ If the subprogram is a definer's-rights (DR) subprogram, then it runs with the privileges of the owner. The owner must have all the necessary object privileges for any referenced objects. If the subprogram is an invoker's-rights (IR) subprogram, then it runs with your privileges. You must have all the necessary object privileges for any referenced objects; that is, all objects accessed by the subprogram through external references that are resolved in your schema. You can hold these privileges either directly or through a role. Roles are enabled unless an IR subprogram is invoked directly or indirectly by a DR subprogram. Coding PL/SQL Subprograms and Packages 6-29 Invoking Stored Subprograms Invoking a Subprogram Interactively from Oracle Tools You can invoke a subprogram interactively from an Oracle Database tool, such as SQL*Plus. Example 6–15 uses SQL*Plus to create a procedure and then invokes it in two different ways. Example 6–15 Invoking a Subprogram Interactively with SQL*Plus CREATE OR REPLACE PROCEDURE salary_raise ( employee EMPLOYEES.EMPLOYEE_ID%TYPE, increase EMPLOYEES.SALARY%TYPE ) IS BEGIN UPDATE EMPLOYEES SET SALARY = SALARY + increase WHERE EMPLOYEE_ID = employee; END; / Invoke procedure from within PL/SQL block: BEGIN salary_raise(205, 200); END; / Result: PL/SQL procedure successfully completed. Invoke procedure with EXECUTE statement: EXECUTE salary_raise(205, 200); Result: PL/SQL procedure successfully completed. Some interactive tools allow you to create session variables, which you can use for the duration of the session. Using SQL*Plus, Example 6–16 creates, uses, and prints a session variable. Example 6–16 Creating and Using a Session Variable with SQL*Plus -- Create function for later use: CREATE OR REPLACE FUNCTION get_job_id ( emp_id EMPLOYEES.EMPLOYEE_ID%TYPE ) RETURN EMPLOYEES.JOB_ID%TYPE IS job_id EMPLOYEES.JOB_ID%TYPE; BEGIN SELECT JOB_ID INTO job_id FROM EMPLOYEES WHERE EMPLOYEE_ID = emp_id; RETURN job_id; END; / -- Create session variable: 6-30 Oracle Database Advanced Application Developer's Guide Invoking Stored Subprograms VARIABLE job VARCHAR2(10); -- Run function and store returned value in session variable: EXECUTE :job := get_job_id(204); PL/SQL procedure successfully completed. SQL*Plus command: PRINT job; Result: JOB -------------------------------PR_REP See Also: ■ ■ SQL*Plus User's Guide and Reference for information about the EXECUTE command Your tools documentation for information about performing similar operations using your development tool Invoking a Subprogram from Another Subprogram A subprogram or a trigger can invoke another stored subprogram. In Example 6–17, the procedure print_mgr_name invokes the procedure print_emp_name. Recursive subprogram invocations are allowed (that is, a subprogram can invoke itself). Example 6–17 Invoking a Subprogram from Within Another Subprogram -- Create procedure that takes employee's ID and prints employee's name: CREATE OR REPLACE PROCEDURE print_emp_name ( emp_id EMPLOYEES.EMPLOYEE_ID%TYPE ) IS fname EMPLOYEES.FIRST_NAME%TYPE; lname EMPLOYEES.LAST_NAME%TYPE; BEGIN SELECT FIRST_NAME, LAST_NAME INTO fname, lname FROM EMPLOYEES WHERE EMPLOYEE_ID = emp_id; DBMS_OUTPUT.PUT_LINE ( 'Employee #' || emp_id || ': ); END; / ' || fname || ' ' || lname -- Create procedure that takes employee's ID and prints manager's name: CREATE OR REPLACE PROCEDURE print_mgr_name ( emp_id EMPLOYEES.EMPLOYEE_ID%TYPE ) IS Coding PL/SQL Subprograms and Packages 6-31 Invoking Remote Subprograms mgr_id EMPLOYEES.MANAGER_ID%TYPE; BEGIN SELECT MANAGER_ID INTO mgr_id FROM EMPLOYEES WHERE EMPLOYEE_ID = emp_id; DBMS_OUTPUT.PUT_LINE ( 'Manager of employee #' || emp_id || ' is: ); ' print_emp_name(mgr_id); END; / Invoke procedures: BEGIN print_emp_name(200); print_mgr_name(200); END; / Result: Employee #200: Jennifer Whalen Manager of employee #200 is: Employee #101: Neena Kochhar Invoking a Subprogram from a 3GL Application A 3GL database application, such as a precompiler or an OCI application, can invoke a subprogram from within its own code. Assume that the procedure Fire_emp1 was created as follows: CREATE OR REPLACE PROCEDURE fire_emp1 (Emp_id NUMBER) AS BEGIN DELETE FROM Emp_tab WHERE Empno = Emp_id; END; To run a subprogram within the code of a precompiler application, you must use the EXEC call interface. For example, this statement invokes the Fire_emp procedure in the code of a precompiler application: EXEC SQL EXECUTE BEGIN Fire_emp1(:Empnum); END; END-EXEC; See Also: Oracle Call Interface Programmer's Guide for information about invoking PL/SQL subprograms from within 3GL applications Invoking Remote Subprograms Remote subprograms (standalone and package) can be invoked from within a subprogram, OCI application, or precompiler by specifying the remote subprogram name, a database link, and the parameters for the remote subprogram. 6-32 Oracle Database Advanced Application Developer's Guide Invoking Remote Subprograms For example, this SQL*Plus statement invokes the procedure fire_emp1, which is located in the database and referenced by the local database link named boston_ server: EXECUTE fire_emp1@boston_server(1043); You must specify values for all remote subprogram parameters, even if there are defaults. You cannot access remote package variables and constants. Caution: ■ ■ Remote subprogram invocations use runtime binding. The user account to which you connect depends on the database link. (Stored subprograms use compile-time binding.) If a local subprogram invokes a remote subprogram, and a time stamp mismatch is found during execution of the local subprogram, then the remote subprogram is not run, and the local subprogram is invalidated. Topics: ■ Synonyms for Remote Subprograms ■ Committing Transactions See Also: "Handling Errors in Remote Subprograms" on page 6-25 for information about exception handling when invoking remote subprograms Synonyms for Remote Subprograms You can create a synonym for a remote subprogram name and database link, and then use the synonym to invoke the subprogram. For example: CREATE SYNONYM synonym1 for fire_emp1@boston_server; EXECUTE synonym1(1043); / The synonym enables you to invoke the remote subprogram from an Oracle Database tool application, such as a SQL*Forms application, as well from within a subprogram, OCI application, or precompiler. Synonyms provide both data independence and location transparency. Synonyms permit applications to function without modification regardless of which user owns the object and regardless of which database holds the object. However, synonyms are not a substitute for privileges on database objects. Appropriate privileges must be granted to a user before the user can use the synonym. Because subprograms defined within a package are not individual objects (the package is the object), synonyms cannot be created for individual subprograms within a package. If you do not want to use a synonym, you can create a local subprogram to invoke the remote subprogram. For example: CREATE OR REPLACE PROCEDURE local_procedure (arg IN NUMBER) AS BEGIN Coding PL/SQL Subprograms and Packages 6-33 Invoking Remote Subprograms fire_emp1@boston_server(arg); END; / DECLARE arg NUMBER; BEGIN local_procedure(arg); END; / See Also: ■ ■ Oracle Database Concepts for general information about synonyms Oracle Database SQL Language Reference for information about the CREATE SYNONYM statement Committing Transactions All invocations to remotely stored subprograms are assumed to perform updates; therefore, this type of referencing always requires two-phase commit of that transaction (even if the remote subprogram is read-only). Furthermore, if a transaction that includes a remote subprogram invocation is rolled back, then the work done by the remote subprogram is also rolled back. A subprogram invoked remotely can usually run a COMMIT, ROLLBACK, or SAVEPOINT statement, the same as a local subprogram. However, there are some differences in action: ■ ■ ■ If the transaction was originated by a database that is not an Oracle database, as might be the case in XA applications, these operations are not allowed in the remote subprogram. After doing one of these operations, the remote subprogram cannot start any distributed transactions of its own. If the remote subprogram does not commit or roll back its work, the commit is done implicitly when the database link is closed. In the meantime, further invocations to the remote subprogram are not allowed because it is still considered to be performing a transaction. A distributed transaction modifies data on two or more databases. A distributed transaction is possible using a subprogram that includes two or more remote updates that access data on different databases. Statements in the construct are sent to the remote databases, and the execution of the construct succeeds or fails as a unit. If part of a distributed update fails and part succeeds, then a rollback (of the entire transaction or to a savepoint) is required to proceed. Consider this when creating subprograms that perform distributed updates. 6-34 Oracle Database Advanced Application Developer's Guide Invoking Stored PL/SQL Functions from SQL Statements Invoking Stored PL/SQL Functions from SQL Statements Caution: Because SQL is a declarative language, rather than an imperative (or procedural) one, you cannot know how many times a function invoked from a SQL statement will run—even if the function is written in PL/SQL, an imperative language. If your application requires that a function be executed a certain number of times, do not invoke that function from a SQL statement. Use a cursor instead. For example, if your application requires that a function be called for each selected row, then open a cursor, select rows from the cursor, and call the function for each row. This guarantees that the number of calls to the function is the number of rows fetched from the cursor. To be invoked from a SQL statement, a stored PL/SQL function must be declared either at schema level or in a package specification. These SQL statements can invoke stored PL/SQL functions: ■ INSERT ■ UPDATE ■ DELETE ■ SELECT ■ CALL (CALL can also invoke a stored PL/SQL procedure.) To invoke a PL/SQL subprogram from SQL, you must either own or have EXECUTE privileges on the subprogram. To select from a view defined with a PL/SQL function, you must have SELECT privileges on the view. No separate EXECUTE privileges are necessary to select from the view. For general information about invoking subprograms, including passing parameters, see Oracle Database PL/SQL Language Reference. Topics: Why Invoke Stored PL/SQL Subprograms from SQL Statements? ■ ■ Where PL/SQL Functions Can Appear in SQL Statements ■ When PL/SQL Functions Can Appear in SQL Expressions ■ Controlling Side Effects Why Invoke Stored PL/SQL Subprograms from SQL Statements? Invoking PL/SQL subprograms in SQL statements can: ■ Increase user productivity by extending SQL Expressiveness of the SQL statement increases where activities are too complex, too awkward, or unavailable with SQL. ■ Increase query efficiency Coding PL/SQL Subprograms and Packages 6-35 Invoking Stored PL/SQL Functions from SQL Statements Functions used in the WHERE clause of a query can filter data using criteria that must otherwise be evaluated by the application. ■ ■ Manipulate character strings to represent special data types (for example, latitude, longitude, or temperature). Provide parallel query execution If the query is parallelized, then SQL statements in your PL/SQL subprogram might also be run in parallel (using the parallel query option). Where PL/SQL Functions Can Appear in SQL Statements A PL/SQL function can appear in a SQL statement wherever a SQL function or an expression can appear in a SQL statement. For example: ■ Select list of the SELECT statement ■ Condition of the WHERE or HAVING clause ■ CONNECT BY, START WITH, ORDER BY, or GROUP BY clause ■ VALUES clause of the INSERT statement ■ SET clause of the UPDATE statement A PL/SQL table function (which returns a collection of rows) can appear in a SELECT statement instead of: ■ Column name in the SELECT list ■ Table name in the FROM clause A PL/SQL function cannot appear in these contexts, which require unchanging definitions: ■ CHECK constraint clause of a CREATE or ALTER TABLE statement ■ Default value specification for a column When PL/SQL Functions Can Appear in SQL Expressions To be invoked from a SQL expression, a PL/SQL function must satisfy these requirements: ■ ■ ■ It must be a row function, not a column (group) function; that is, its argument cannot be an entire column. Its formal parameters must be IN parameters, not OUT or IN OUT parameters. Its formal parameters and its return value (if any) must have Oracle built-in data types (such as CHAR, DATE, or NUMBER), not PL/SQL data types (such as BOOLEAN, RECORD, or TABLE). There is an exception to this rule: A formal parameter can have a PL/SQL data type if the corresponding actual parameter is implicitly converted to the data type of the formal parameter (as in Example 6–19). The function in Example 6–18 satisfies the preceding requirements. Example 6–18 PL/SQL Function in SQL Expression (Follows Rules) DROP TABLE payroll; -- in case it exists CREATE TABLE payroll ( srate NUMBER, orate NUMBER, 6-36 Oracle Database Advanced Application Developer's Guide Invoking Stored PL/SQL Functions from SQL Statements acctno NUMBER ); CREATE OR REPLACE FUNCTION gross_pay ( emp_id IN NUMBER, st_hrs IN NUMBER := 40, ot_hrs IN NUMBER := 0 ) RETURN NUMBER IS st_rate NUMBER; ot_rate NUMBER; BEGIN SELECT srate, orate INTO st_rate, ot_rate FROM payroll WHERE acctno = emp_id; RETURN st_hrs * st_rate + ot_hrs * ot_rate; END gross_pay; / In Example 6–19, the SQL statement CALL invokes the PL/SQL function f1, whose formal parameter and return value have PL/SQL data type PLS_INTEGER. The CALL statement succeeds because the actual parameter, 2, is implicitly converted to the data type PLS_INTEGER. If the actual parameter had a value outside the range of PLS_ INTEGER, the CALL statement would fail. Example 6–19 PL/SQL Function in SQL Expression (Exception to Rule) CREATE OR REPLACE FUNCTION f1 ( b IN PLS_INTEGER ) RETURN PLS_INTEGER IS BEGIN RETURN CASE WHEN b > 0 THEN 1 WHEN b <= 0 THEN -1 ELSE NULL END; END f1; / VARIABLE x NUMBER; CALL f1(b=>2) INTO :x; PRINT x; Result: X ---------1 Controlling Side Effects The purity of a stored subprogram refers to the side effects of that subprogram on database tables or package variables. Side effects can prevent the parallelization of a query, yield order-dependent (and therefore, indeterminate) results, or require that package state be maintained across user sessions. Various side effects are not allowed when a function is invoked from a SQL query or DML statement. Coding PL/SQL Subprograms and Packages 6-37 Invoking Stored PL/SQL Functions from SQL Statements Before Oracle Database 8g Release 1, Oracle Database leveraged the PL/SQL compiler to enforce restrictions during the compilation of a stored subprogram or a SQL statement. As of Oracle Database 8g Release 1, the compile-time restrictions were relaxed, and a smaller set of restrictions are enforced during execution. This change provides uniform support for stored subprograms written in PL/SQL, Java, and C, and it allows programmers the most flexibility possible. Topics: ■ Restrictions ■ Declaring a Function ■ Parallel Query and Parallel DML ■ PRAGMA RESTRICT_REFERENCES for Backward Compatibility Restrictions When a new SQL statement is run, checks are made to see if it is logically embedded within the execution of a running SQL statement. This occurs if the statement is run from a trigger or from a subprogram that was in turn invoked from the running SQL statement. In these cases, further checks determine if the new SQL statement is safe in the specific context. These restrictions are enforced on subprograms: ■ ■ ■ A subprogram invoked from a query (SELECT statement) or DML statement cannot end the current transaction, create or rollback to a savepoint, or ALTER the system or session. A subprogram invoked from a query or parallelized DML statement cannot run a DML statement or otherwise modify the database. A subprogram invoked from a DML statement cannot read or modify the particular table being modified by that DML statement. These restrictions apply regardless of what mechanism is used to run the SQL statement inside the subprogram or trigger. For example: ■ ■ ■ They apply to a SQL statement invoked from PL/SQL, whether embedded directly in a subprogram or trigger body, run using the native dynamic mechanism (EXECUTE IMMEDIATE), or run using the DBMS_SQL package. They apply to statements embedded in Java with SQLJ syntax or run using JDBC. They apply to statements run with OCI using the callback context from within an "external" C function. You can avoid these restrictions if the execution of the new SQL statement is not logically embedded in the context of the running statement. PL/SQL autonomous transactions provide one escape (see "Autonomous Transactions" on page 2-30 ). Another escape is available using OCI from an external C function, if you create a new connection rather than using the handle available from the OCIExtProcContext argument. Declaring a Function You can use the keywords DETERMINISTIC and PARALLEL_ENABLE in the syntax for declaring a function. These are optimization hints that inform the query optimizer and other software components about: ■ Functions that need not be invoked redundantly 6-38 Oracle Database Advanced Application Developer's Guide Invoking Stored PL/SQL Functions from SQL Statements ■ Functions permitted within a parallelized query or parallelized DML statement Only functions that are DETERMINISTIC are allowed in function-based indexes and in certain snapshots and materialized views. A deterministic function depends solely on the values passed into it as arguments and does not reference or modify the contents of package variables or the database or have other side-effects. Such a function produces the same result value for any combination of argument values passed into it. You place the DETERMINISTIC keyword after the return value type in a declaration of the function. For example: CREATE OR REPLACE FUNCTION f1 ( p1 NUMBER ) RETURN NUMBER DETERMINISTIC IS BEGIN RETURN p1 * 2; END; / You might place this keyword in these places: ■ On a function defined in a CREATE FUNCTION statement ■ In a function declaration in a CREATE PACKAGE statement ■ On a method declaration in a CREATE TYPE statement Do not repeat the keyword on the function or method body in a CREATE PACKAGE BODY or CREATE TYPE BODY statement. Certain performance optimizations occur on invocations of functions that are marked DETERMINISTIC without any other action being required. These features require that any function used with them be declared DETERMINISTIC: ■ ■ Any user-defined function used in a function-based index. Any function used in a materialized view, if that view is to qualify for Fast Refresh or is marked ENABLE QUERY REWRITE. The preceding functions features attempt to use previously calculated results rather than invoking the function when it is possible to do so. It is good programming practice to make functions that fall into these categories DETERMINISTIC: ■ Functions used in a WHERE, ORDER BY, or GROUP BY clause ■ Functions that MAP or ORDER methods of a SQL type ■ Functions that help determine whether or where a row appears in a result set Keep these points in mind when you create DETERMINISTIC functions: ■ ■ The database cannot recognize if the action of the function is indeed deterministic. If the DETERMINISTIC keyword is applied to a function whose action is not truly deterministic, then the result of queries involving that function is unpredictable. If you change the semantics of a DETERMINISTIC function and recompile it, then existing function-based indexes and materialized views report results for the prior version of the function. Thus, if you change the semantics of a function, you must manually rebuild any dependent function-based indexes and materialized views. Coding PL/SQL Subprograms and Packages 6-39 Invoking Stored PL/SQL Functions from SQL Statements Oracle Database PL/SQL Language Reference for CREATE FUNCTION restrictions See Also: Parallel Query and Parallel DML Oracle Database's parallel execution feature divides the work of running a SQL statement across multiple processes. Functions invoked from a SQL statement that is run in parallel might have a separate copy run in each of these processes, with each copy invoked for only the subset of rows that are handled by that process. Each process has its own copy of package variables. When parallel execution begins, these are initialized based on the information in the package specification and body as if a user is logging into the system; the values in package variables are not copied from the original login session. And changes made to package variables are not automatically propagated between the various sessions or back to the original session. Java STATIC class attributes are similarly initialized and modified independently in each process. Because a function can use package (or Java STATIC) variables to accumulate some value across the various rows it encounters, Oracle Database cannot assume that it is safe to parallelize the execution of all user-defined functions. For SELECT statements in Oracle Database versions before 8.1.5, the parallel query optimization allowed functions noted as both RNPS and WNPS in a PRAGMA RESTRICT_ REFERENCES declaration to run in parallel. Functions defined with CREATE FUNCTION statements had their code implicitly examined to determine if they were pure enough; parallelized execution might occur even though a pragma cannot be specified on these functions. See Also: "PRAGMA RESTRICT_REFERENCES for Backward Compatibility" on page 6-41 For DML statements in Oracle Database versions before 8.1.5, the parallelization optimization looked to see if a function was noted as having all four of RNDS, WNDS, RNPS and WNPS specified in a PRAGMA RESTRICT_REFERENCES declaration; those functions that were marked as neither reading nor writing to either the database or package variables could run in parallel. Again, those functions defined with a CREATE FUNCTION statement had their code implicitly examined to determine if they were actually pure enough; parallelized execution might occur even though a pragma cannot be specified on these functions. Oracle Database versions 8.1.5 and later continue to parallelize those functions that earlier versions recognize as parallelizable. The PARALLEL_ENABLE keyword is the preferred way to mark your code as safe for parallel execution. This keyword is syntactically similar to DETERMINISTIC as described in "Declaring a Function" on page 6-38; it is placed after the return value type in a declaration of the function, as in: CREATE OR REPLACE FUNCTION f1 ( p1 NUMBER ) RETURN NUMBER PARALLEL_ENABLE IS BEGIN RETURN p1 * 2; END; / A PL/SQL function defined with CREATE FUNCTION might still be run in parallel without any explicit declaration that it is safe to do so, if the system can determine that it neither reads nor writes package variables nor invokes any function that might do so. A Java method or C function is never seen by the system as safe to run in parallel, 6-40 Oracle Database Advanced Application Developer's Guide Invoking Stored PL/SQL Functions from SQL Statements unless the programmer explicitly indicates PARALLEL_ENABLE on the call specification, or provides a PRAGMA RESTRICT_REFERENCES indicating that the function is sufficiently pure. An additional runtime restriction is imposed on functions run in parallel as part of a parallelized DML statement. Such a function is not permitted to in turn run a DML statement; it is subject to the same restrictions that are enforced on functions that are run inside a query (SELECT) statement. See Also: Restrictions on page 6-38 PRAGMA RESTRICT_REFERENCES for Backward Compatibility In Oracle Database versions before 8.1.5 (Oracle8i), programmers used PRAGMA RESTRICT_REFERENCES to assert the purity level of a subprogram. In subsequent versions, use the hints PARALLEL_ENABLE and DETERMINISTIC, instead, to communicate subprogram purity to Oracle Database. You can remove PRAGMA RESTRICT_REFERENCES from your code. However, this pragma remains available for backward compatibility in these situations: ■ When it is impossible or impractical to edit existing code to completely remove PRAGMA RESTRICT_REFERENCES. For example, if subprogram S1 depends on subprogram S2, and you do not remove the pragma from S1, then you might need the pragma in S2 to compile S1. ■ When replacing PRAGMA RESTRICT_REFERENCES in existing code with hints PARALLEL_ENABLE and DETERMINISTIC would negatively affect the action of new, dependent code. (Use PRAGMA RESTRICT_REFERENCES to preserve the action of the existing code.) An existing PL/SQL application can thus continue using the pragma even on new functionality, to ease integration with the existing code. Do not use the pragma in a new application. If you use PRAGMA RESTRICT_REFERENCES, place it in a package specification, not in a package body. It must follow the declaration of a subprogram, but it need not follow immediately. Only one pragma can reference a given subprogram declaration. To code the PRAGMA RESTRICT_REFERENCES, use this syntax: PRAGMA RESTRICT_REFERENCES ( Function_name, WNDS [, WNPS] [, RNDS] [, RNPS] [, TRUST] ); Where: Option Description WNDS The subprogram writes no database state (does not modify database tables). RNDS The subprogram reads no database state (does not query database tables). WNPS The subprogram writes no package state (does not change the values of package variables). RNPS The subprogram reads no package state (does not reference the values of package variables) TRUST The other restrictions listed in the pragma are not enforced; they are simply assumed to be true. This allows easy invocation from functions that have RESTRICT_ REFERENCES declarations to those that do not. Coding PL/SQL Subprograms and Packages 6-41 Invoking Stored PL/SQL Functions from SQL Statements You can pass the arguments in any order. If any SQL statement inside the subprogram body violates a rule, then you get an error when the statement is parsed. In Example 6–20, the function compound_ neither reads nor writes database or package state; therefore, you can assert the maximum purity level. Always assert the highest purity level that a subprogram allows, so that the PL/SQL compiler never rejects the subprogram unnecessarily. Example 6–20 PRAGMA RESTRICT_REFERENCES DROP TABLE accounts; -- in case it exists CREATE TABLE accounts ( acctno INTEGER, balance NUMBER ); INSERT INTO accounts (acctno, balance) VALUES (12345, 1000.00); CREATE OR REPLACE PACKAGE finance AS FUNCTION compound_ ( years IN NUMBER, amount IN NUMBER, rate IN NUMBER ) RETURN NUMBER; PRAGMA RESTRICT_REFERENCES (compound_, WNDS, WNPS, RNDS, RNPS); END finance; / CREATE PACKAGE BODY finance AS FUNCTION compound_ ( years IN NUMBER, amount IN NUMBER, rate IN NUMBER ) RETURN NUMBER IS BEGIN RETURN amount * POWER((rate / 100) + 1, years); END compound_; -- No pragma in package body END finance; / DECLARE interest NUMBER; BEGIN SELECT finance.compound_(5, 1000, 6) INTO interest FROM accounts WHERE acctno = 12345; END; / Topics: ■ Using the Keyword TRUST ■ Differences between Static and Dynamic SQL Statements ■ Overloading Package Functions Using the Keyword TRUST When PRAGMA RESTRICT REFERENCES includes the keyword TRUST, the restrictions listed in the pragma are assumed to be true, and not enforced. 6-42 Oracle Database Advanced Application Developer's Guide Invoking Stored PL/SQL Functions from SQL Statements When you invoke a subprogram that is in a section of code that does not use pragmas (such as a Java method), from a section of PL/SQL code that does use pragmas, specify PRAGMA RESTRICT REFERENCES with TRUST for either the invoked subprogram or the invoking subprogram. In both Example 6–21 and Example 6–22, the PL/SQL function f invokes the Java procedure java_sleep. In Example 6–21, this is possible because java_sleep is declared to be WNDS with TRUST. In Example 6–22, it is possible because f is declared to be WNDS with TRUST, which allows it to invoke any subprogram. Example 6–21 PRAGMA RESTRICT REFERENCES with TRUST on Invokee CREATE OR REPLACE PACKAGE p IS PROCEDURE java_sleep (milli_seconds IN NUMBER) AS LANGUAGE JAVA NAME 'java.lang.Thread.sleep(long)'; PRAGMA RESTRICT_REFERENCES(java_sleep,WNDS,TRUST); FUNCTION f (n NUMBER) RETURN NUMBER; END p; / CREATE OR REPLACE PACKAGE BODY p IS FUNCTION f ( n NUMBER ) RETURN NUMBER IS BEGIN java_sleep(n); RETURN n; END f; END p; / Example 6–22 PRAGMA RESTRICT REFERENCES with TRUST on Invoker CREATE OR REPLACE PACKAGE p IS PROCEDURE java_sleep (milli_seconds IN NUMBER) AS LANGUAGE JAVA NAME 'java.lang.Thread.sleep(long)'; FUNCTION f (n NUMBER) RETURN NUMBER; PRAGMA RESTRICT_REFERENCES(f,WNDS,TRUST); END p; / CREATE OR REPLACE PACKAGE BODY p IS FUNCTION f ( n NUMBER ) RETURN NUMBER IS BEGIN java_sleep(n); RETURN n; END f; END p; / Differences between Static and Dynamic SQL Statements Static INSERT, UPDATE, and DELETE statements do not violate RNDS if these statements do not explicitly read any database states, such as columns of a table. However, dynamic INSERT, UPDATE, and DELETE statements always violate RNDS, regardless of whether the statements explicitly read database states. Coding PL/SQL Subprograms and Packages 6-43 Returning Large Amounts of Data from a Function This INSERT statement violates RNDS if it is executed dynamically, but it does not violate RNDS if it is executed statically. INSERT INTO my_table values(3, 'BOB'); This UPDATE statement always violates RNDS statically and dynamically, because it explicitly reads the column name of my_table. UPDATE my_table SET id=777 WHERE name='BOB'; Overloading Package Functions If a subprogram is overloaded, PRAGMA RESTRICT_ REFERENCES applies only to the most recently declared version. In Example 6–23, the pragma applies to the second declaration of valid. Example 6–23 Overloaded Package Function with PRAGMA RESTRICT_REFERENCES CREATE OR REPLACE PACKAGE tests AS FUNCTION valid (x NUMBER) RETURN CHAR; FUNCTION valid (x DATE) RETURN CHAR; PRAGMA RESTRICT_REFERENCES (valid, WNDS); END; / Returning Large Amounts of Data from a Function In a data warehousing environment, you might use PL/SQL functions to transform large amounts of data. Perhaps the data is passed through a series of transformations, each performed by a different function. PL/SQL table functions let you perform such transformations without significant memory overhead or the need to store the data in tables between each transformation stage. These functions can accept and return multiple rows, can return rows as they are ready rather than all at once, and can be parallelized. Oracle Database PL/SQL Language Reference for more information about performing multiple transformations with pipelined table functions See Also: Coding Your Own Aggregate Functions To analyze a set of rows and compute a result value, you can code your own aggregate function that works the same as a SQL aggregate function like SUM: ■ ■ ■ ■ Define an ADT that defines these member functions: ■ ODCIAggregateInitialize ■ ODCIAggregateIterate ■ ODCIAggregateMerge ■ ODCIAggregateTerminate Code the member functions. In particular, ODCIAggregateIterate accumulates the result as it is invoked for each row that is processed. Store any intermediate results using the attributes of the ADT. Create the aggregate function, and associate it with the ADT. Call the aggregate function from SQL queries, DML statements, or other places that you might use the SQL aggregate functions. You can include typical options such as DISTINCT and ALL in the invocation of the aggregate function. 6-44 Oracle Database Advanced Application Developer's Guide Coding Your Own Aggregate Functions See Also: Oracle Database Data Cartridge Developer's Guide for more information about user-defined aggregate functions Coding PL/SQL Subprograms and Packages 6-45 Coding Your Own Aggregate Functions 6-46 Oracle Database Advanced Application Developer's Guide 7 Using PL/Scope 7 PL/Scope is a compiler-driven tool that collects data about identifiers in PL/SQL source code at program-unit compilation time and makes it available in static data dictionary views. The collected data includes information about identifier types, usages (declaration, definition, reference, call, assignment) and the location of each usage in the source code. PL/Scope enables the development of powerful and effective PL/Scope source code browsers that increase PL/SQL developer productivity by minimizing time spent browsing and understanding source code. PL/Scope is intended for application developers, and is usually used in the environment of a development database. PL/Scope cannot collect data for a PL/SQL unit whose source code is wrapped. For information about wrapping PL/SQL source code, see Oracle Database PL/SQL Language Reference. Note: Topics: ■ Specifying Identifier Collection ■ PL/Scope Identifier Data for STANDARD and DBMS_STANDARD ■ How Much Space is PL/Scope Data Using? ■ Viewing PL/Scope Data ■ Identifier Types that PL/Scope Collects ■ Usages that PL/Scope Reports ■ Sample PL/Scope Session Specifying Identifier Collection By default, PL/Scope does not collect data for identifiers in the PL/SQL source program. To have PL/Scope collect data for all identifiers in the PL/SQL source program, including identifiers in package bodies, set the PL/SQL compilation parameter PLSCOPE_SETTINGS to 'IDENTIFIERS:ALL'. Collecting all identifiers might generate large amounts of data and slow compile time. Note: Using PL/Scope 7-1 PL/Scope Identifier Data for STANDARD and DBMS_STANDARD PL/Scope stores the data that it collects in the SYSAUX tablespace. If the SYSAUX tablespace is unavailable, and you compile a program unit with PLSCOPE_ SETTINGS='IDENTIFIERS:ALL', PL/Scope does not collect data for the compiled object. The compiler does not issue a warning, but it saves a warning in USER_ERRORS. See Also: ■ ■ Oracle Database Reference for information about PLSCOPE_SETTINGS Oracle Database PL/SQL Language Reference for information about PL/SQL compilation parameters PL/Scope Identifier Data for STANDARD and DBMS_STANDARD The packages STANDARD and DBMS_STANDARD declare and define base types, such as VARCHAR2 and NUMBER, and subprograms such as RAISE_APPLICATION_ERROR. If your database has PL/Scope identifier data for these packages, PL/Scope can track your usage of the identifiers that these packages create. Do You Need STANDARD and DBMS_STANDARD Identifier Data? You can use PL/Scope without STANDARD and DBMS_STANDARD identifier data. You need this data only if you must know where your code uses the base types or subprograms that these packages create—for example, to know where your code uses the base type BINARY_INTEGER, so that you can substitute PLS_INTEGER. Does Your Database Have STANDARD and DBMS_STANDARD Identifier Data? A newly created Oracle Database 11g Release 1 (11.1.0.7), or a database that was upgraded to 11.1.0.7 from Oracle Database 10g Release 2, has PL/Scope identifier data for the packages STANDARD and DBMS_STANDARD. A database that was upgraded to 11.1.0.7 from 11.1.0.6 does not have this data. To see if your database has this data, use the query in Example 7–1. Example 7–1 shows what the query returns when the database has PL/Scope identifier data for STANDARD and DBMS_STANDARD. Example 7–1 Is STANDARD and DBMS_STANDARD PL/Scope Identifier Data Available? Query: SELECT UNIQUE OBJECT_NAME FROM ALL_IDENTIFIERS WHERE OBJECT_NAME IN ('STANDARD', 'DBMS_STANDARD') AND OWNER='SYS' ORDER BY OBJECT_NAME; Result: OBJECT_NAME -----------------------------DBMS_STANDARD STANDARD 2 rows selected. If the query in Example 7–1 selects no rows, then the database does not have PL/Scope identifier data for the packages STANDARD and DBMS_STANDARD. To collect this data, a DBA must recompile the packages STANDARD and DBMS_STANDARD, as explained in "Recompiling STANDARD and DBMS_STANDARD" on page 7-3. 7-2 Oracle Database Advanced Application Developer's Guide PL/Scope Identifier Data for STANDARD and DBMS_STANDARD Recompiling STANDARD and DBMS_STANDARD A DBA can use this procedure to recompile the packages STANDARD and DBMS_ STANDARD: This procedure invalidates and revalidates (by recompiling) every PL/SQL object in the database. Note: 1. Connect to the database, shut it down, and then start it in UPGRADE mode: CONNECT / AS SYSDBA; SHUTDOWN IMMEDIATE; STARTUP PFILE=parameter_initialization_file UPGRADE; 2. Have PL/Scope collect data for all identifiers in the packages STANDARD and DBMS_ STANDARD: ALTER SESSION SET PLSCOPE_SETTINGS='IDENTIFIERS:ALL'; 3. Invalidate and recompile the database: @?/rdbms/admin/utlirp.sql Now all PL/SQL objects in the database are invalid except STANDARD and DBMS_ STANDARD, which were recompiled with PLSCOPE_SETTINGS='IDENTIFIERS:ALL'. 4. (Optional) Invalidate any other PL/SQL objects to be recompiled with PLSCOPE_ SETTINGS='IDENTIFIERS:ALL', using a script similar to this. Customize the query on lines 5 through 9 to invalidate only those objects for which you need PL/Scope identifier data. Collecting all identifiers for all objects, as this script does, might generate large amounts of data and slow compile time: DECLARE TYPE ObjIDArray IS TABLE OF NUMBER INDEX BY BINARY_INTEGER; ObjIDs ObjIDArray; BEGIN SELECT object_id BULK COLLECT INTO ObjIDs FROM ALL_OBJECTS WHERE object_type IN (SELECT DISTINCT TYPE FROM ALL_PLSQL_OBJECT_SETTINGS); FOR i IN 1..SQL%ROWCOUNT LOOP BEGIN DBMS_UTILITY.INVALIDATE(ObjIDs(i), 'PLSCOPE_SETTINGS=IDENTIFIERS:ALL REUSE SETTINGS'); NULL; END; END LOOP; END; / Notes: ■ ■ In the preceding script: Do not substitute ObjIDs.LAST for SQL%ROWCOUNT, because ObjIDs attributes are dependent on a package that is locked by the anonymous block. If your database is large, do not substitute a cursor FOR LOOP for the BULK COLLECT statement, or you will run out of resources. Using PL/Scope 7-3 How Much Space is PL/Scope Data Using? 5. Shut down the database, and then start it in NORMAL mode: SHUTDOWN IMMEDIATE; STARTUP PFILE=parameter_initialization_file; 6. For any remaining invalid PL/SQL objects, do either of these: ■ Allow them to be recompiled automatically, as they are referenced. (This can be slow if there are complex dependencies.) ■ Run the script utlrp.sql to recompile the invalid PL/SQL objects, as explained in "Running utlrp.sql to Recompile Invalid PL/SQL Objects" on page 7-4. Running utlrp.sql to Recompile Invalid PL/SQL Objects If the database was restarted in NORMAL mode (step 5 on page 7-4), then a DBA, or a user who has been granted the DBA role, can use this procedure: 1. Connect to the database as SYS: CONNECT / AS SYS; 2. Run the script utlrp.sql: @?/rdbms/admin/utlrp.sql If the script gives you any instructions, follow them, and then run the script again. If the script terminates abnormally without giving any instructions, run it again. How Much Space is PL/Scope Data Using? PL/Scope stores its data in the SYSAUX tablespace. If you are logged on as SYSDBA, you can use the query in Example 7–2 to display the amount of space that PL/Scope data is using. Example 7–2 How Much Space is PL/Scope Data Using? Query: SELECT SPACE_USAGE_KBYTES FROM V$SYSAUX_OCCUPANTS WHERE OCCUPANT_NAME='PL/SCOPE'; Result: SPACE_USAGE_KBYTES -----------------1600 1 row selected. For information about managing the SYSAUX tablespace, see Oracle Database Administrator's Guide. Viewing PL/Scope Data To view the data that PL/Scope has collected, you can use either: ■ Static Data Dictionary Views 7-4 Oracle Database Advanced Application Developer's Guide Viewing PL/Scope Data ■ Demo Tool ■ SQL Developer Static Data Dictionary Views The static data dictionary views *_IDENTIFIERS display information about PL/Scope identifiers, including their types and usages. For general information about these views, see Oracle Database Reference. Topics: Unique Keys ■ ■ Context ■ Signature Unique Keys Each row of a *_IDENTIFIERS view represents a unique usage of an identifier in the PL/SQL unit. In each of these views, these are equivalent unique keys within a compilation unit: ■ LINE, COL, and USAGE ■ USAGE_ID For the usages in the *_IDENTIFIERS views, see "Usages that PL/Scope Reports" on page 7-9. An identifier that is passed to a subprogram in IN OUT mode has two rows in *_IDENTIFIERS: a REFERENCE usage (corresponding to IN) and an ASSIGNMENT usage (corresponding to OUT). Note: Context Context is useful for discovering relationships between usages. Except for top-level schema object declarations and definitions, every usage of an identifier happens within the context of another usage. For example: ■ ■ A local variable declaration happens within the context of a top-level procedure declaration. If an identifier is declared as a variable, such as x VARCHAR2(10), the USAGE_ CONTEXT_ID of the VARCHAR2 type reference contains the USAGE_ID of the x declaration, allowing you to associate the variable declaration with its type. In other words, USAGE_CONTEXT_ID is a reflexive foreign key to USAGE_ID, as Example 7–3 shows. Example 7–3 USAGE_CONTEXT_ID and USAGE_ID ALTER SESSION SET PLSCOPE_SETTINGS = 'IDENTIFIERS:ALL'; CREATE OR REPLACE PROCEDURE a (p1 IN BOOLEAN) IS v PLS_INTEGER; BEGIN v := 42; DBMS_OUTPUT.PUT_LINE(v); RAISE_APPLICATION_ERROR (-20000, 'Bad'); Using PL/Scope 7-5 Viewing PL/Scope Data EXCEPTION WHEN Program_Error THEN NULL; END a; / CREATE OR REPLACE PROCEDURE b (p2 OUT PLS_INTEGER, p3 IN OUT VARCHAR2) IS n NUMBER; q BOOLEAN := TRUE; BEGIN FOR j IN 1..5 LOOP a(q); a(TRUE); a(TRUE); IF j > 2 THEN GOTO z; END IF; END LOOP; < > DECLARE d CONSTANT CHAR(1) := 'X'; BEGIN SELECT COUNT(*) INTO n FROM Dual WHERE Dummy = d; END z; END b; / WITH v AS ( SELECT Line, Col, INITCAP(NAME) Name, LOWER(TYPE) Type, LOWER(USAGE) Usage, USAGE_ID, USAGE_CONTEXT_ID FROM USER_IDENTIFIERS WHERE Object_Name = 'B' AND Object_Type = 'PROCEDURE' ) SELECT RPAD(LPAD(' ', 2*(Level-1)) || Name, 20, '.')||' '|| RPAD(Type, 20)|| RPAD(Usage, 20) IDENTIFIER_USAGE_CONTEXTS FROM v START WITH USAGE_CONTEXT_ID = 0 CONNECT BY PRIOR USAGE_ID = USAGE_CONTEXT_ID ORDER SIBLINGS BY Line, Col / Result: IDENTIFIER_USAGE_CONTEXTS ------------------------------------------------------------B................... procedure declaration B................. procedure definition P2.............. formal out declaration Pls_Integer... subtype reference P3.............. formal in out declaration Varchar2...... character datatype reference N............... variable declaration Number........ number datatype reference Q............... variable declaration Q............. variable assignment Boolean....... boolean datatype reference J............... iterator declaration A............. procedure call 7-6 Oracle Database Advanced Application Developer's Guide Identifier Types that PL/Scope Collects Q........... A............. A............. J............. Z............. Z............... D............. D........... Char........ N............. D............. variable procedure procedure iterator label label constant constant subtype variable constant reference call call reference reference declaration declaration assignment reference assignment reference 24 rows selected. Signature The signature of an identifier is unique, within and across program units. That is, the signature distinguishes the identifier from other identifiers with the same name, whether they are defined in the same program unit or different program units. For the program unit in Example 7–4, which has two identifiers named p, the static data dictionary view USER_IDENTIFIERS has several rows in which NAME is p, but in these rows, SIGNATURE varies. The rows associated with the outer procedure p have one signature, and the rows associated with the inner procedure p have another signature. If program unit q calls procedure p, the USER_IDENTIFIERS view for q has a row in which NAME is p and SIGNATURE is the signature of the outer procedure p. Example 7–4 Program Unit with Two Identifiers Named p CREATE OR REPLACE PROCEDURE p IS PROCEDURE p IS BEGIN DBMS_OUTPUT.PUT_LINE('Inner p'); END p; BEGIN DBMS_OUTPUT.PUT_LINE('Outer p'); p(); END p; / Demo Tool $ORACLE_HOME/plsql/demo/plscopedemo.sql is an HTML-based demo implemented as a PL/SQL Web Application using the PL/SQL Web Toolkit. For more information about PL/SQL Web Applications, see "Implementing PL/SQL Web Applications" on page 9-2. SQL Developer PL/Scope is a feature of SQL Developer. For information about using PL/Scope from SQL Developer, see the SQL Developer online documentation. Identifier Types that PL/Scope Collects Table 7–1 shows the identifier types that PL/Scope collects, in alphabetical order. The identifier types in Table 7–1 appear in the TYPE column of the *_IDENTIFIER static data dictionary views, which are described in Oracle Database Reference. Using PL/Scope 7-7 Identifier Types that PL/Scope Collects Identifiers declared in compilation units that were not compiled with PLSCOPE_SETTINGS='IDENTIFIERS:ALL' do not appear in *_IDENTIFIER static data dictionary views. Note: Table 7–1 Identifier Types that PL/Scope Collects TYPE Column Value Comment ASSOCIATIVE ARRAY CONSTANT CURSOR BFILE DATATYPEBLOB DATATYPEBOOLEAN DATATYPECHARACTER DATATYPECLOB DATATYPEDATE DATATYPEINTERVAL DATATYPENUMBER DATATYPETIME DATATYPETIMESTAMP DATATYPE Each DATATYPE is a base type declared in package STANDARD. EXCEPTION FORMAL INFORMAL IN OUTFORMAL OUT FUNCTION INDEX TABLE ITERATOR An iterator is the index of a FOR loop. LABEL A label declaration also acts as a context. LIBRARY NESTED TABLE OBJECT OPAQUE Examples of internal opaque types are ANYDATA and XMLType. PACKAGE PROCEDURE RECORD REFCURSOR SUBTYPE SYNONYM PL/Scope does not resolve the base object name of a synonym. To find the base object name of a synonym, query *_SYNONYMS. TRIGGER UROWID VARRAY VARIABLE Can be object attribute, local variable, package variable, or record field. 7-8 Oracle Database Advanced Application Developer's Guide Usages that PL/Scope Reports Usages that PL/Scope Reports Table 7–2 shows the usages that PL/Scope reports, in alphabetical order. The identifier types in Table 7–2 appear in the USAGE column of the *_IDENTIFIER static data dictionary views, which are described in Oracle Database Reference. Table 7–2 Usages that PL/Scope Reports USAGE Column Value ASSIGNMENT Description An assignment can be made only to an identifier that can have a value, such as a VARIABLE. Examples of assignments are: ■ Using an identifier to the left of an assignment operator ■ Using an identifier in the INTO clause of a FETCH statement ■ Passing an identifier to a subprogram by reference (OUT mode) ■ Using an identifier as the bind variable in the USING clause of an EXECUTE IMMEDIATE statement in either OUT or IN OUT mode An identifier that is passed to a subprogram in IN OUT mode has both a REFERENCE usage (corresponding to IN) and an ASSIGNMENT usage (corresponding to OUT). CALL In the context of PL/Scope, a CALL is an operation that pushes a call onto the call stack; that is: ■ A call to a FUNCTION or PROCEDURE ■ Running or fetching a cursor identifier (a logical call to SQL) A GOTO statement or raise of an exception is not a CALL, because neither pushes a call onto the call stack. DECLARATION A DECLARATION tells the compiler that an identifier exists, and each identifier has exactly one DECLARATION. Each DECLARATION can have an associated data type. For a loop index declaration, LINE and COL (in *_IDENTIFIERS views) are the line and column of the FOR clause that implicitly declares the loop index. For a label declaration, LINE and COL are the line and column on which the label appears (and is implicitly declared) within the delimiters << and >>. DEFINITION A DEFINITION tells the compiler how to implement or use a previously declared identifier. Each of these types of identifiers has a DEFINITION: ■ EXCEPTION (can have multiple definitions) ■ FUNCTION ■ OBJECT ■ PACKAGE ■ PROCEDURE ■ TRIGGER For a top-level identifier only, the DEFINITION and DECLARATION are in the same place. Using PL/Scope 7-9 Sample PL/Scope Session Table 7–2 (Cont.) Usages that PL/Scope Reports USAGE Column Value REFERENCE Description A REFERENCE uses an identifier without changing its value. Examples of references are: ■ ■ ■ Raising an exception identifier Using a type identifier in the declaration of a variable or formal parameter Using a variable identifier whose type contains fields to access a field. For example, in myrecordvar.myfield := 1, a reference is made to myrecordvar, and an assignment is made to myfield. ■ Using a cursor for any purpose except FETCH ■ Passing an identifier to a subprogram by value (IN mode) ■ Using an identifier as the bind variable in the USING clause of an EXECUTE IMMEDIATE statement in either IN or IN OUT mode An identifier that is passed to a subprogram in IN OUT mode has both a REFERENCE usage (corresponding to IN) and an ASSIGNMENT usage (corresponding to OUT). Sample PL/Scope Session In this sample session, assume that you are logged in as HR. 1. Set the session parameter: ALTER SESSION SET PLSCOPE_SETTINGS='IDENTIFIERS:ALL'; 2. Create this package: CREATE OR REPLACE PACKAGE PACK1 IS TYPE r1 is RECORD (rf1 VARCHAR2(10)); FUNCTION F1(fp1 NUMBER) RETURN NUMBER; PROCEDURE P1(pp1 VARCHAR2); END PACK1; / CREATE OR REPLACE PACKAGE BODY PACK1 IS FUNCTION F1(fp1 NUMBER) RETURN NUMBER IS a NUMBER := 10; BEGIN RETURN a; END F1; PROCEDURE P1(pp1 VARCHAR2) IS pr1 r1; BEGIN pr1.rf1 := pp1; END; END PACK1; / 3. Verify that PL/Scope collected all identifiers for the package body: SELECT PLSCOPE_SETTINGS FROM USER_PLSQL_OBJECT_SETTINGS WHERE NAME='PACK1' AND TYPE='PACKAGE BODY' Result: PLSCOPE_SETTINGS 7-10 Oracle Database Advanced Application Developer's Guide Sample PL/Scope Session -----------------------------------------------------------------------IDENTIFIERS:ALL 4. Display unique identifiers in HR by querying for all DECLARATION usages. For example, to see all unique identifiers with name like %1, use these SQL*Plus formatting commands and this query: COLUMN NAME FORMAT A6 COLUMN SIGNATURE FORMAT A32 COLUMN TYPE FORMAT A9 SELECT NAME, SIGNATURE, TYPE FROM USER_IDENTIFIERS WHERE NAME LIKE '%1' AND USAGE='DECLARATION' ORDER BY OBJECT_TYPE, USAGE_ID; Result is similar to: NAME -----PACK1 R1 RF1 F1 FP1 P1 PP1 FP1 PP1 PR1 SIGNATURE -------------------------------41820FA4D5EF6BE707895178D0C5C4EF EEBB6849DEE31BC77BF186EBAE5D4E2D 41D70040337349634A7F547BC83517C7 4559CF050A5F5C3E5F5FFDD0D9D55EFA CAC3474C112DBEC67AB926978D9A16C1 B7C0576BA4D00C33A65CC0C64CADAB89 6B74CF95A5B7377A735925DFAA280266 98EB63B8A4AFEB5EF94D50A20165D6CC AD89FE0EAE9CE5D6D48AA4684E0D57DF 1B5117F30E8DAE0261A02CAA5E33883F TYPE --------PACKAGE RECORD VARIABLE FUNCTION FORMAL IN PROCEDURE FORMAL IN FORMAL IN FORMAL IN VARIABLE 10 rows selected. The *_IDENTIFIERS static data dictionary views display only basic type names; for example, the TYPE of a local variable or record field is VARIABLE. To determine the exact type of a VARIABLE, you must use its USAGE_CONTEXT_ID. 5. Find all local variables: COLUMN VARIABLE_NAME FORMAT A13 COLUMN CONTEXT_NAME FORMAT A12 SELECT a.NAME variable_name, b.NAME context_name, a.SIGNATURE FROM USER_IDENTIFIERS a, USER_IDENTIFIERS b WHERE a.USAGE_CONTEXT_ID = b.USAGE_ID AND a.TYPE = 'VARIABLE' AND a.USAGE = 'DECLARATION' AND a.OBJECT_NAME = 'PACK1' AND a.OBJECT_NAME = b.OBJECT_NAME AND a.OBJECT_TYPE = b.OBJECT_TYPE AND (b.TYPE = 'FUNCTION' or b.TYPE = 'PROCEDURE') ORDER BY a.OBJECT_TYPE, a.USAGE_ID; Result is similar to: VARIABLE_NAME ------------A PR1 CONTEXT_NAME -----------F1 P1 SIGNATURE -------------------------------1691C6B3C951FCAA2CBEEB47F85CF128 1B5117F30E8DAE0261A02CAA5E33883F Using PL/Scope 7-11 Sample PL/Scope Session 2 rows selected. 6. Find all usages performed on the local variable A: COLUMN COLUMN COLUMN COLUMN USAGE FORMAT A11 USAGE_ID FORMAT 999 OBJECT_NAME FORMAT A11 OBJECT_TYPE FORMAT A12 SELECT USAGE, USAGE_ID, OBJECT_NAME, OBJECT_TYPE FROM USER_IDENTIFIERS WHERE SIGNATURE='1691C6B3C951FCAA2CBEEB47F85CF128' ORDER BY OBJECT_TYPE, USAGE_ID; -- signature of A Result: USAGE USAGE_ID OBJECT_NAME OBJECT_TYPE ----------- -------- ----------- -----------DECLARATION 6 PACK1 PACKAGE BODY ASSIGNMENT 8 PACK1 PACKAGE BODY REFERENCE 9 PACK1 PACKAGE BODY 3 rows selected. The usages performed on the local identifier A are the identifier declaration (USAGE_ID 6), an assignment (USAGE_ID 8), and a reference (USAGE_ID 9). 7. From the declaration of the local identifier A, find its type: COLUMN NAME FORMAT A6 COLUMN TYPE FORMAT A15 SELECT a.NAME, a.TYPE FROM USER_IDENTIFIERS a, USER_IDENTIFIERS b WHERE a.USAGE = 'REFERENCE' AND a.USAGE_CONTEXT_ID = b.USAGE_ID AND b.USAGE = 'DECLARATION' AND b.SIGNATURE = '4559CF050A5F5C3E5F5FFDD0D9D55EFA' AND a.OBJECT_TYPE = b.OBJECT_TYPE AND a.OBJECT_NAME = b.OBJECT_NAME; -- signature of F1 Result: NAME TYPE ------ --------------NUMBER NUMBER DATATYPE 1 row selected. This query produces the output shown only if your database has PL/Scope identifier data for the packages STANDARD and DBMS_ STANDARD. For more information, see "PL/Scope Identifier Data for STANDARD and DBMS_STANDARD" on page 7-2. Note: 8. Find out where the assignment to local identifier A occurred: SELECT LINE, COL, OBJECT_NAME, OBJECT_TYPE FROM USER_IDENTIFIERS WHERE SIGNATURE='1691C6B3C951FCAA2CBEEB47F85CF128' 7-12 Oracle Database Advanced Application Developer's Guide -- signature of A Sample PL/Scope Session AND USAGE='ASSIGNMENT'; Result: LINE COL OBJECT_NAME OBJECT_TYPE ---------- ---------- ----------- -----------3 5 PACK1 PACKAGE BODY 1 row selected. Using PL/Scope 7-13 Sample PL/Scope Session 7-14 Oracle Database Advanced Application Developer's Guide 8 Using the PL/SQL Hierarchical Profiler 8 You can use the PL/SQL hierarchical profiler to identify bottlenecks and performance-tuning opportunities in PL/SQL applications. The profiler reports the dynamic execution profile of a PL/SQL program organized by function calls, and accounts for SQL and PL/SQL execution times separately. No special source or compile-time preparation is required; any PL/SQL program can be profiled. This chapter describes the PL/SQL hierarchical profiler and explains how to use it to collect and analyze profile data for a PL/SQL program. Topics: Overview of PL/SQL Hierarchical Profiler ■ ■ Collecting Profile Data ■ Understanding Raw Profiler Output ■ Analyzing Profile Data ■ plshprof Utility Overview of PL/SQL Hierarchical Profiler Nonhierarchical (flat) profilers record the time that a program spends within each subprogram—the function time or self time of each subprogram. Function time is helpful, but often inadequate. For example, it is helpful to know that a program spends 40% of its time in the subprogram INSERT_ORDER, but it is more helpful to know which subprograms call INSERT_ORDER often and the total time the program spends under INSERT_ORDER (including its descendant subprograms). Hierarchical profilers provide such information. The PL/SQL hierarchical profiler: ■ Reports the dynamic execution profile of your PL/SQL program, organized by subprogram calls ■ Accounts for SQL and PL/SQL execution times separately ■ Requires no special source or compile-time preparation ■ ■ Stores results in database tables (hierarchical profiler tables) for custom report generation by integrated development environment (IDE) tools (such as SQL Developer and third-party tools) Provides subprogram-level execution summary information, such as: Using the PL/SQL Hierarchical Profiler 8-1 Collecting Profile Data ■ Number of calls to the subprogram ■ Time spent in the subprogram itself (function time or self time) ■ ■ Time spent in the subprogram itself and in its descendent subprograms (subtree time) Detailed parent-children information, for example: – All callers of a given subprogram (parents) – All subprograms that a given subprogram called (children) – How much time was spent in subprogram x when called from y – How many calls to subprogram x were from y The PL/SQL hierarchical profiler is implemented by the DBMS_HPROF package and has two components: ■ Data collection The data collection component is an intrinsic part of the PL/SQL Virtual Machine. The DBMS_HPROF package provides APIs to turn hierarchical profiling on and off and write the raw profiler output to a file. ■ Analyzer The analyzer component processes the raw profiler output and stores the results in hierarchical profiler tables. To generate simple HTML reports directly from raw profiler output, without using the Analyzer, you can use the plshprof command-line utility. Note: Collecting Profile Data To collect profile data from your PL/SQL program for the PL/SQL hierarchical profiler, follow these steps: 1. Ensure that you have these privileges: ■ ■ EXECUTE privilege on the DBMS_HPROF package WRITE privilege on the directory that you specify when you call DBMS_ HPROF.START_PROFILING 2. Use the DBMS_HPROF.START_PROFILING PL/SQL API to start hierarchical profiler data collection in a session. 3. Run your PL/SQL program long enough to get adequate code coverage. To get the most accurate measurements of elapsed time, avoid unrelated activity on the system on which your PL/SQL program is running. 4. Use the DBMS_HPROF.STOP_PROFILING PL/SQL API to stop hierarchical profiler data collection. For more information about DBMS_HPROF.START_PROFILING and DBMS_HPROF.STOP_ PROFILING, see Oracle Database PL/SQL Packages and Types Reference. Consider this PL/SQL procedure, test: CREATE OR REPLACE PROCEDURE test IS n NUMBER; 8-2 Oracle Database Advanced Application Developer's Guide Understanding Raw Profiler Output PROCEDURE foo IS BEGIN SELECT COUNT(*) INTO n FROM EMPLOYEES; END foo; BEGIN -- test FOR i IN 1..3 LOOP foo; END LOOP; END test; / The SQL script in Example 8–1 profiles the execution of the PL/SQL procedure test. Example 8–1 Profiling a PL/SQL Procedure BEGIN /* Start profiling. Write raw profiler output to file test.trc in a directory that is mapped to directory object PLSHPROF_DIR (see note after example). */ DBMS_HPROF.START_PROFILING('PLSHPROF_DIR', 'test.trc'); END; / -- Run procedure to be profiled BEGIN test; END; / BEGIN -- Stop profiling DBMS_HPROF.STOP_PROFILING; END; / A directory object is an alias for a file system path name. For example, if you are connected to the database AS SYSDBA, this CREATE DIRECTORY statement creates the directory object PLSHPROF_DIR and maps it to the file system directory /private/plshprof/results: Note: CREATE DIRECTORY PLSHPROF_DIR as '/private/plshprof/results'; To run the SQL script in Example 8–1, you must have READ and WRITE privileges on both PLSHPROF_DIR and the directory to which it is mapped. if you are connected to the database AS SYSDBA, this GRANT statement grants READ and WRITE privileges on PLSHPROF_DIR to HR: GRANT READ, WRITE ON DIRECTORY PLSHPROF_DIR TO HR; For more information about using directory objects, see Oracle Database SecureFiles and Large Objects Developer's Guide. Understanding Raw Profiler Output Raw profiler output is intended to be processed by the analyzer component of the PL/SQL hierarchical profiler. However, even without such processing, it provides a simple function-level trace of the program. This topic explains how to understand raw profiler output. Using the PL/SQL Hierarchical Profiler 8-3 Understanding Raw Profiler Output The raw profiler format shown in this chapter is intended only to illustrate conceptual features of raw profiler output. Format specifics are subject to change at each Oracle Database release. Note: The SQL script in Example 8–1 wrote this raw profiler output to the file test.trc: P#V P#! P#C P#X P#C P#X P#C P#X P#C P#X P#C P#X P#R P#X P#R P#X P#C P#X P#C P#X P#R P#X P#R P#X P#C P#X P#C P#X P#R P#X P#R P#X P#R P#X P#R P#X P#R P#C P#X P#C P#X P#C P#R P#R P#R P#! PLSHPROF Internal Version 1.0 PL/SQL Timer Started PLSQL."".""."__plsql_vm" 2 PLSQL."".""."__anonymous_block" 50 PLSQL."HR"."TEST"::7."TEST"#980980e97e42f8ec #1 3 PLSQL."HR"."TEST"::7."TEST.FOO"#980980e97e42f8ec #4 35 SQL."HR"."TEST"::7."__static_sql_exec_line6" #6 206 26 2 PLSQL."HR"."TEST"::7."TEST.FOO"#980980e97e42f8ec #4 4 SQL."HR"."TEST"::7."__static_sql_exec_line6" #6 80 3 0 PLSQL."HR"."TEST"::7."TEST.FOO"#980980e97e42f8ec #4 3 SQL."HR"."TEST"::7."__static_sql_exec_line6" #6 69 3 1 1 3 PLSQL."".""."__plsql_vm" 3 PLSQL."".""."__anonymous_block" 44 PLSQL."SYS"."DBMS_HPROF"::11."STOP_PROFILING"#980980e97e42f8ec #53 PL/SQL Timer Stopped Table 8–1 Raw Profiler Output File Indicators Indicator Meaning P#V PLSHPROF banner with version number P#C Call to a subprogram (call event) 8-4 Oracle Database Advanced Application Developer's Guide Understanding Raw Profiler Output Table 8–1 (Cont.) Raw Profiler Output File Indicators Indicator Meaning P#R Return from a subprogram (return event) P#X Elapsed time between preceding and following events P#! Comment Call events (P#C) and return events (P#R) are always properly nested (like matched parentheses). If an unhandled exception causes a called subprogram to exit, the profiler still reports a matching return event. Each call event (P#C) entry in the raw profiler output includes this information: ■ Namespace to which the called subprogram belongs See "Namespaces of Tracked Subprograms" on page 8-6. ■ Name of the PL/SQL module in which the called subprogram is defined ■ Type of the PL/SQL module in which the called subprogram is defined ■ Name of the called subprogram This name might be one of the "Special Function Names" on page 8-6. ■ Hexadecimal value that represents an MD5 hash of the signature of the called subprogram The DBMS_HPROF.analyze PL/SQL API (described in "Analyzing Profile Data" on page 8-6) stores the hash value in a hierarchical profiler table, which allows both you and DBMS_HPROF.analyze to distinguish between overloaded subprograms (subprograms with the same name). ■ Line number at which the called subprogram is defined in the PL/SQL module PL/SQL hierarchical profiler does not measure time spent at individual lines within modules, but you can use line numbers to identify the source locations of subprograms in the module (as IDE/Tools do) and to distinguish between overloaded subprograms. For example, consider this entry in the preceding example of raw profiler output: P#C PLSQL."HR"."TEST"::7."TEST.FOO"#980980e97e42f8ec #4 The components of the preceding entry have these meanings: Component Meaning PLSQL PLSQL is the namespace to which the called subprogram belongs. "HR"."TEST" HR.TEST is the name of the PL/SQL module in which the called subprogram is defined. 7 7 is the internal enumerator for the module type of HR.TEST. Examples of module types are procedure, package, and package body. "TEST.FOO" TEST.FOO is the name of the called subprogram. #980980e97e42f8ec #980980e97e42f8ec is a hexadecimal value that represents an MD5 hash of the signature of TEST.FOO. #4 4 is the line number in the PL/SQL module HR.TEST at which TEST.FOO is defined. Using the PL/SQL Hierarchical Profiler 8-5 Analyzing Profile Data When a subprogram is inlined, it is not reported in the profiler output. For information about subprogram inlining, see Oracle Database PL/SQL Language Reference. Note: When a call to a DETERMINISTIC function is "optimized away," it is not reported in the profiler output. For information about DETERMINISTIC functions, see Oracle Database PL/SQL Language Reference. Namespaces of Tracked Subprograms The subprograms that the PL/SQL hierarchical profiler tracks are classified into the namespaces PLSQL and SQL, as follows: ■ ■ Namespace PLSQL includes: – PL/SQL subprogram calls – PL/SQL triggers – PL/SQL anonymous blocks – Remote subprogram calls – Package initialization blocks Namespace SQL includes SQL statements executed from PL/SQL, such as queries, data manipulation language (DML) statements, data definition language (DDL) statements, and native dynamic SQL statements Special Function Names PL/SQL hierarchical profiler tracks certain operations as if they were functions with the names and namespaces shown in Table 8–2. Table 8–2 Function Names of Operations that the PL/SQL Hierarchical Profiler Tracks Tracked Operation Function Name Namespace Call to PL/SQL Virtual Machine __plsql_vm PL/SQL PL/SQL anonymous block __anonymous_block PL/SQL Package initialization block __pkg_init PL/SQL Static SQL statement at line line# __static_sql_exec_lineline# SQL Dynamic SQL statement at line line# __dyn_sql_exec_lineline# SQL SQL FETCH statement at line line# __sql_fetch_lineline# SQL Analyzing Profile Data The analyzer component of the PL/SQL hierarchical profiler, DBMS_HPROF.analyze, processes the raw profiler output and stores the results in the hierarchical database tables described in Table 8–3. Table 8–3 PL/SQL Hierarchical Profiler Database Tables Table Description DBMSHP_RUNS Top-level information for this run of DBMS_HPROF.analyze. For column descriptions, see Table 8–4 on page 8-8. 8-6 Oracle Database Advanced Application Developer's Guide Analyzing Profile Data Table 8–3 (Cont.) PL/SQL Hierarchical Profiler Database Tables Table Description DBMSHP_FUNCTION_INFO Information for each subprogram profiled in this run of DBMS_HPROF.analyze. For column descriptions, see Table 8–5 on page 8-9. DBMSHP_PARENT_CHILD_INFO Parent-child information for each subprogram profiled in this run of DBMS_HPROF.analyze. For column descriptions, see Table 8–6 on page 8-8. Topics: ■ Creating Hierarchical Profiler Tables ■ Understanding Hierarchical Profiler Tables To generate simple HTML reports directly from raw profiler output, without using the Analyzer, you can use the plshprof command-line utility. For details, see "plshprof Utility" on page 8-13. Note: Creating Hierarchical Profiler Tables To create the hierarchical profiler tables in Table 8–3 and the other data structures required for persistently storing profile data, follow these steps: 1. Run the script dbmshptab.sql (located in the directory rdbms/admin). This script creates both the hierarchical profiler tables in Table 8–3 and the other data structures required for persistently storing profile data. Running the script dbmshptab.sql drops any previously created hierarchical profiler tables. Note: 2. 3. Ensure that you have these privileges: ■ EXECUTE privilege on the DBMS_HPROF package ■ READ privilege on the directory that DBMS_HPROF.analyze specifies Use the PL/SQL API DBMS_HPROF.analyze to analyze a single raw profiler output file and store the results in hierarchical profiler tables. (For an example of a raw profiler output file, see test.trc in "Understanding Raw Profiler Output" on page 8-3.) For more information about DBMS_HPROF.analyze, see Oracle Database PL/SQL Packages and Types Reference. 4. Use the hierarchical profiler tables to generate custom reports. The anonymous block in Example 8–2: ■ Invokes the function DBMS_HPROF.analyze function, which: – Analyzes the profile data in the raw profiler output file test.trc (from "Understanding Raw Profiler Output" on page 8-3), which is in the directory that is mapped to the directory object PLSHPROF_DIR, and stores the data in the hierarchical profiler tables in Table 8–3 on page 8-6. Using the PL/SQL Hierarchical Profiler 8-7 Analyzing Profile Data – ■ Returns a unique identifier that you can use to query the hierarchical profiler tables in Table 8–3 on page 8-6. (By querying these hierarchical profiler tables, you can produce customized reports.) Stores the unique identifier in the variable runid, which it prints. Example 8–2 Invoking DBMS_HPROF.analyze DECLARE runid NUMBER; BEGIN runid := DBMS_HPROF.analyze(LOCATION=>'PLSHPROF_DIR', FILENAME=>'test.trc'); DBMS_OUTPUT.PUT_LINE('runid = ' || runid); END; / Understanding Hierarchical Profiler Tables These topics explain how to use the hierarchical profiler tables in Table 8–3: ■ Hierarchical Profiler Database Table Columns ■ Distinguishing Between Overloaded Subprograms ■ Hierarchical Profiler Tables for Sample PL/SQL Procedure ■ Examples of Calls to DBMS_HPROF.analyze with Options Hierarchical Profiler Database Table Columns Table 8–4 describes the columns of the hierarchical profiler table DBMSHP_RUNS, which contains one row of top-level information for each run of DBMS_HPROF.analyze. The primary key for the hierarchical profiler table DBMSHP_RUNS is RUNID. Table 8–4 DBMSHP_RUNS Table Columns Column Name Column Data Type Column Contents RUNID NUMBER PRIMARY KEY Unique identifier for this run of DBMS_ HPROF.analyze, generated from DBMSHP_RUNNUMBER sequence. RUN_TIMESTAMP TIMESTAMP Time stamp for this run of DBMS_ HPROF.analyze. RUN_COMMENT VARCHAR2(2047) Comment that you provided for this run of DBMS_HPROF.analyze. TOTAL_ELAPSED_TIME INTEGER Total elapsed time for this run of DBMS_HPROF.analyze. Table 8–5 describes the columns of the hierarchical profiler table DBMSHP_FUNCTION_ INFO, which contains one row of information for each subprogram profiled in this run of DBMS_HPROF.analyze. If a subprogram is overloaded, Table 8–5 has a row for each variation of that subprogram. Each variation has its own LINE# and HASH (see "Distinguishing Between Overloaded Subprograms" on page 8-10). The primary key for the hierarchical profiler table DBMSHP_FUNCTION_INFO is RUNID, SYMBOLID. 8-8 Oracle Database Advanced Application Developer's Guide Analyzing Profile Data Table 8–5 DBMSHP_FUNCTION_INFO Table Columns Column Name Column Data Type Column Contents RUNID NUMBER References RUNID column of DBMSHP_ RUNS table. For a description of that column, see Table 8–4. SYMBOLID NUMBER Symbol identifier for subprogram (unique for this run of DBMS_ HPROF.analyze). OWNER VARCHAR2(32) Owner of module in which each subprogram is defined (for example, SYS or HR). MODULE VARCHAR2(2047) Module in which subprogram is defined (for example, DBMS_LOB, UTL_HTTP, or MY_PACKAGE). TYPE VARCHAR2(32) Type of module in which subprogram is defined (for example, PACKAGE, PACKAGE_BODY, or PROCEDURE). FUNCTION VARCHAR2(4000) Name of subprogram (not necessarily a function) (for example, INSERT_ORDER, PROCESS_ITEMS, or TEST). This name might be one of the "Special Function Names" on page 8-6. For subprogram B defined within subprogram A, this name is A.B. A recursive call to function X is denoted X@n, where n is the recursion depth. For example, X@1 is the first recursive call to X. LINE# NUMBER Line number in OWNER.MODULE at which FUNCTION is defined. HASH RAW(32) Hash code for signature of subprogram (unique for this run of DBMS_ HPROF.analyze). NAMESPACE VARCHAR2(32) Namespace of subprogram. For details, see "Namespaces of Tracked Subprograms" on page 8-6. SUBTREE_ELAPSED_TIME INTEGER Elapsed time, in microseconds, for subprogram, including time spent in descendant subprograms. FUNCTION_ELAPSED_TIME INTEGER Elapsed time, in microseconds, for subprogram, excluding time spent in descendant subprograms. CALLS INTEGER Number of calls to subprogram. Table 8–6 describes the columns of the hierarchical profiler table DBMSHP_PARENT_ CHILD_INFO, which contains one row of parent-child information for each unique parent-child subprogram combination profiled in this run of DBMS_HPROF.analyze. Using the PL/SQL Hierarchical Profiler 8-9 Analyzing Profile Data Table 8–6 DBMSHP_PARENT_CHILD_INFO Table Columns Column Name Column Data Type Column Contents RUNID NUMBER References RUNID column of DBMSHP_ FUNCTION_INFO table. For a description of that column, see Table 8–5. PARENTSYMID NUMBER Parent symbol ID. RUNID, PARENTSYMID references DBMSHP_FUNCTION_INFO(RUNID, SYMBOLID). CHILDSYMID Child symbol ID. VARCHAR2(32) RUNID, CHILDSYMID references DBMSHP_ FUNCTION_INFO(RUNID, SYMBOLID). SUBTREE_ELAPSED_TIME INTEGER Elapsed time, in microseconds, for RUNID, CHILDSYMID when called from RUNID, PARENTSYMID, including time spent in descendant subprograms. FUNCTION_ELAPSED_TIME INTEGER Elapsed time, in microseconds, for RUNID, CHILDSYMID when called from RUNID, PARENTSYMID, excluding time spent in descendant subprograms. CALLS INTEGER Number of calls to RUNID, CHILDSYMID from RUNID, PARENTSYMID. Distinguishing Between Overloaded Subprograms Overloaded subprograms are different subprograms with the same name (see Oracle Database PL/SQL Language Reference). Suppose that a program declares three subprograms named compute—the first at line 50, the second at line 76, and the third at line 100. In the DBMSHP_FUNCTION_INFO table, each of these subprograms has compute in the FUNCTION column. To distinguish between the three subprograms, use either the LINE# column (which has 50 for the first subprogram, 76 for the second, and 100 for the third) or the HASH column (which has a unique value for each subprogram). In the profile data for two different runs, the LINE# and HASH values for a function might differ. The LINE# value of a function changes if you insert or delete lines before the function definition. The HASH value changes only if the signature of the function changes; for example, if you change the parameter list. Hierarchical Profiler Tables for Sample PL/SQL Procedure The hierarchical profiler tables for the PL/SQL procedure test in "Collecting Profile Data" on page 8-2 are shown in Example 8–3 through Example 8–5. Example 8–3 DBMSHP_RUNS Table for Sample PL/SQL Procedure RUNID 1 RUN_TIMESTAMP 10-APR-06 12.01.56.766743 PM TOTAL_ELAPSED_TIME 2637 RUN_COMMENT First run of TEST Example 8–4 DBMSHP_FUNCTION_INFO Table for Sample PL/SQL Procedure RUNID 1 1 1 SYMBOLID 1 2 3 OWNER MODULE TYPE HR TEST PROCEDURE NAMESPACE PLSQL PLSQL PLSQL 8-10 Oracle Database Advanced Application Developer's Guide FUNCTION __anonymous_block __plsql_vm TEST Analyzing Profile Data 1 1 1 4 5 6 LINE# 0 0 1 3 57 5 CALLS 2 2 1 3 1 3 HR SYS HR TEST DBMS_HPROF TEST HASH 980980E97E42F8EC 980980E97E42F8EC 980980E97E42F8EC 980980E97E42F8EC 980980E97E42F8EC 980980E97E42F8EC PROCEDURE PACKAGE_BODY PROCEDURE PLSQL PLSQL SQL SUBTREE_ELAPSED_TIME 2554 2637 2212 2184 0 1998 TEST.FOO STOP_PROFILING __static_sql_exec_line5 FUNCTION_ELAPSED_TIME 342 83 28 126 0 1998 Example 8–5 DBMSHP_PARENT_CHILD_INFO Table for Sample PL/SQL Procedure RUNID 1 1 1 1 1 PARENTSYMID 2 1 3 1 4 CHILDSYMID 1 3 4 5 6 SUBTREE_ELAPSED_TIME 2554 2212 2184 0 1998 FUNCTION_ELAPSED_TIME 342 28 126 0 1998 CALLS 2 1 3 1 3 Consider the third row of the table DBMSHP_PARENT_CHILD_INFO (Example 8–5). The RUNID column shows that this row corresponds to the first run. The columns PARENTSYMID and CHILDSYMID show that the symbol IDs of the parent (caller) and child (called subprogram) are 3 and 4, respectively. The table DBMSHP_FUNCTION_INFO (Example 8–4) shows that for the first run, the symbol IDs 3 and 4 correspond to procedures TEST and TEST.FOO, respectively. Therefore, the information in this row is about calls from the procedure TEST to the procedure FOO (defined within TEST) in the module HR.TEST. This row shows that, when called from the procedure TEST, the function time for the procedure FOO is 126 microseconds, and the time spent in the FOO subtree (including descendants) is 2184 microseconds. Examples of Calls to DBMS_HPROF.analyze with Options For an example of a call to DBMS_HPROF.analyze without options, see Example 8–2 on page 8-8. Example 8–6 creates a package, creates a procedure that invokes subprograms in the package, profiles the procedure, and uses DBMS_HRPROF.analyze to analyze the raw profiler output file. The raw profiler output file is in the directory corresponding to the PLSHPROF_DIR directory object. Example 8–6 Invoking DBMS_HPROF.analyze with Options -- Create package CREATE OR REPLACE PACKAGE pkg IS PROCEDURE myproc (n IN out NUMBER); FUNCTION myfunc (v VARCHAR2) RETURN VARCHAR2; FUNCTION myfunc (n PLS_INTEGER) RETURN PLS_INTEGER; END pkg; / CREATE OR REPLACE PACKAGE BODY pkg IS PROCEDURE myproc (n IN OUT NUMBER) IS BEGIN n := n + 5; END; FUNCTION myfunc (v VARCHAR2) RETURN VARCHAR2 IS n NUMBER; Using the PL/SQL Hierarchical Profiler 8-11 Analyzing Profile Data BEGIN n := LENGTH(v); myproc(n); IF n > 20 THEN RETURN SUBSTR(v, 1, 20); ELSE RETURN v || '...'; END IF; END; FUNCTION myfunc (n PLS_INTEGER) RETURN PLS_INTEGER IS i PLS_INTEGER; PROCEDURE myproc (n IN out PLS_INTEGER) IS BEGIN n := n + 1; END; BEGIN i := n; myproc(i); RETURN i; END; END pkg; / -- Create procedure that invokes package subprograms CREATE OR REPLACE PROCEDURE test2 IS x NUMBER := 5; y VARCHAR2(32767); BEGIN pkg.myproc(x); y := pkg.myfunc('hello'); END; -- Profile test2 BEGIN DBMS_HPROF.START_PROFILING('PLSHPROF_DIR', 'test2.trc'); END; / BEGIN test2; END; / BEGIN DBMS_HPROF.STOP_PROFILING; END; / -- If not done, create hierarchical profiler tables -- (see "Creating Hierarchical Profiler Tables" on page 8-7.) -- Call DBMS_HPROF.analyze with options DECLARE runid NUMBER; BEGIN -- Analyze only subtrees rooted at trace entry "HR"."PKG"."MYPROC" runid := DBMS_HPROF.analyze('PLSHPROF_DIR', 'test2.trc', trace => '"HR"."PKG"."MYPROC"'); 8-12 Oracle Database Advanced Application Developer's Guide plshprof Utility -- Analyze up to 20 calls to subtrees rooted at trace entry -- "HR"."PKG"."MYFUNC". Because "HR"."PKG"."MYFUNC" is overloaded, -- both overloads are considered for analysis. runid := DBMS_HPROF.analyze('PLSHPROF_DIR', 'test2.trc', collect => 20, trace => '"HR"."PKG"."MYFUNC"'); -- Analyze second call to PL/SQL virtual machine runid := DBMS_HPROF.analyze('PLSHPROF_DIR', 'test2.trc', skip => 1, collect => 1, trace => '""."".""__plsql_vm"'); END; / plshprof Utility The plshprof command-line utility (located in the directory $ORACLE_HOME/bin/) generates simple HTML reports from either one or two raw profiler output files. (For an example of a raw profiler output file, see test.trc in "Collecting Profile Data" on page 8-2.) You can browse the generated HTML reports in any browser. The browser's navigational capabilities, combined with well chosen links, provide a powerful way to analyze performance of large applications, improve application performance, and lower development costs. Topics: plshprof Options ■ ■ HTML Report from a Single Raw Profiler Output File ■ HTML Difference Report from Two Raw Profiler Output Files plshprof Options The command to run the plshprof utility is: plshprof [option...] profiler_output_filename_1 profiler_output_filename_2 Each option is one of these: Option Description Default -skip count Skips first count calls. Use only with -trace symbol. 0 -collect count Collects information for count calls. Use only 1 with -trace symbol. -output filename Specifies name of output file symbol.html or tracefile1.html -summary Prints only elapsed time None -trace symbol Specifies function name of tree root Not applicable Using the PL/SQL Hierarchical Profiler 8-13 plshprof Utility Suppose that your raw profiler output file, test.trc, is in the current directory. You want to analyze and generate HTML reports, and you want the root file of the HTML report to be named report.html. Use this command (% is the prompt): % plshprof -output report test.trc HTML Report from a Single Raw Profiler Output File To generate a PL/SQL hierarchical profiler HTML report from a single raw profiler output file, use these commands: % cd target_directory % plshprof -output html_root_filename profiler_output_filename target_directory is the directory in which you want the HTML files to be created. html_root_filename is the name of the root HTML file to be created. profiler_output_filename is the name of a raw profiler output file. The preceding plshprof command generates a set of HTML files. Start browsing them from html_root_filename.html. Topics: First Page of Report ■ ■ Function-Level Reports ■ Module-Level Reports ■ Namespace-Level Reports ■ Parents and Children Report for a Function First Page of Report The first page of an HTML report from a single raw profiler output file includes summary information and hyperlinks to other pages of the report. Sample First Page PL/SQL Elapsed Time (microsecs) Analysis 2831 microsecs (elapsed time) & 12 function calls The PL/SQL Hierarchical Profiler produces a collection of reports that present information derived from the profiler output log in a variety of formats. These reports have been found to be the most generally useful as starting points for browsing: ■ ■ Function Elapsed Time (microsecs) Data sorted by Total Subtree Elapsed Time (microsecs) Function Elapsed Time (microsecs) Data sorted by Total Function Elapsed Time (microsecs) In addition, the following reports are also available: ■ ■ ■ Function Elapsed Time (microsecs) Data sorted by Function Name Function Elapsed Time (microsecs) Data sorted by Total Descendants Elapsed Time (microsecs) Function Elapsed Time (microsecs) Data sorted by Total Function Call Count 8-14 Oracle Database Advanced Application Developer's Guide plshprof Utility Function Elapsed Time (microsecs) Data sorted by Mean Subtree Elapsed Time (microsecs) ■ Function Elapsed Time (microsecs) Data sorted by Mean Function Elapsed Time (microsecs) ■ Function Elapsed Time (microsecs) Data sorted by Mean Descendants Elapsed Time (microsecs) ■ Module Elapsed Time (microsecs) Data sorted by Total Function Elapsed Time (microsecs) ■ ■ Module Elapsed Time (microsecs) Data sorted by Module Name ■ Module Elapsed Time (microsecs) Data sorted by Total Function Call Count Namespace Elapsed Time (microsecs) Data sorted by Total Function Elapsed Time (microsecs) ■ ■ Namespace Elapsed Time (microsecs) Data sorted by Namespace ■ Namespace Elapsed Time (microsecs) Data sorted by Total Function Call Count ■ Parents and Children Elapsed Time (microsecs) Data Function-Level Reports The function-level reports provide a flat view of the profile information. Each function-level report includes this information for each function: ■ Function time (time spent in the function itself, also called "self time") ■ Descendants time (time spent in the descendants of the function) Subtree time (time spent in the subtree of the function—function time plus descendants time) ■ ■ Number of calls to the function ■ Function name The function name is hyperlinked to the Parents and Children Report for the function. Each function-level report is sorted on a particular attribute; for example, function time or subtree time. This sample report is sorted in descending order of the total subtree elapsed time for the function, which is why information in the Subtree and Ind% columns is in bold type: Sample Report Function Elapsed Time (microsecs) Data sorted by Total Subtree Elapsed Time (microsecs) 2831 microsecs (elapsed time) & 12 function calls Subtree Ind% Function Descendant Ind% Calls Ind% Function Name 2831 100% 93 2738 2738 96.7% 2 16.7% __plsq_vm 96.7% 310 2428 85.8% 2 16.7% __anonymous_block 2428 85.8% 15 2413 85.2% 1 8.3% 2413 85.2% 435 1978 69.9% 3 25.0% HR.TEST.TEST.FOO (Line 3) HR.TEST.TEST (Line 1) Using the PL/SQL Hierarchical Profiler 8-15 plshprof Utility Subtree Ind% Function Descendant Ind% Calls Ind% Function Name 1978 69.9% 1978 0 0.0% 0 0 0.0% 3 25.0% HR.TEST.__static_sql_exec_ line5 (Line 5) 0 0.0% 1 8.3% SYS.DBMS_HPROF.STOP_ PROFILING (Line 53) Module-Level Reports Each module-level report includes this information for each module (for example, package or type): ■ ■ Module time (time spent in the module—sum of the function times of all functions in the module) Number of calls to functions in the module Each module-level report is sorted on a particular attribute; for example, module time or module name. This sample report is sorted by module time, which is why information in the Module, Ind%, and Cum% columns is in bold type: Sample Report Module Elapsed Time (microsecs) Data sorted by Total Function Elapsed Time (microsecs) 166878 microsecs (elapsed time) & 1099 function calls Module Ind% Cum% Calls Ind% Module Name 84932 50.9% 50.9% 6 0.5% HR.P 67749 40.6% 91.5% 216 19.7% SYS.DBMS_LOB 13340 8.0% 99.5% 660 60.1% SYS.UTL_FILE 839 0.5% 100% 214 19.5% SYS.UTL_RAW 18 0.0% 100% 2 0.2% HR.UTILS 0 0.0% 100% 1 0.1% SYS.DBMS_HPROF Namespace-Level Reports Each namespace-level report includes this information for each namespace: ■ ■ Namespace time (time spent in the namespace—sum of the function times of all functions in the namespace) Number of calls to functions in the namespace Each namespace-level report is sorted on a particular attribute; for example, namespace time or number of calls to functions in the namespace. This sample report is sorted by function time, which is why information in the Function, Ind%, and Cum% columns is in bold type: Sample Report Namespace Elapsed Time (microsecs) Data sorted by Total Function Elapsed Time (microsecs) 166878 microsecs (elapsed time) & 1099 function calls 8-16 Oracle Database Advanced Application Developer's Guide plshprof Utility Function Ind% Cum% Calls Ind% Namespace 93659 56.1% 56.1% 1095 99.6% PLSQL 73219 43.9% 100% 4 0.4% SQL Parents and Children Report for a Function For each function tracked by the profiler, the Parents and Children Report provides information about parents (functions that call it) and children (functions that it calls). For each parent, the report gives the function's execution profile (subtree time, function time, descendants time, and number of calls). For each child, the report gives the execution profile for the child when called from this function (but not when called from other functions). The execution profile for a function includes the same information for that function as a function-level report includes for each function (for details, see "Function-Level Reports" on page 8-15). This Sample Report is a fragment of a Parents and Children Report that corresponds to a function named HR.P.UPLOAD. The first row has this summary information: ■ ■ There are two calls to the function HR.P.UPLOAD. The total subtree time for the function is 166,860 microseconds—11,713 microseconds (7.0%) in the function itself and 155,147 microseconds (93.0%) in its descendants. After the row "Parents" are the execution profile rows for the two parents of HR.P.UPLOAD, which are HR.UTILS.COPY_IMAGE and HR.UTILS.COPY_FILE. The first parent execution profile row, for HR.UTILS.COPY_IMAGE, shows: ■ ■ ■ HR.UTILS.COPY_IMAGE calls HR.P.UPLOAD once, which is 50% of the number of calls to HR.P.UPLOAD. The subtree time for HR.P.UPLOAD when called from HR.UTILS.COPY_IMAGE is 106,325 microseconds, which is 63.7% of the total subtree time for HR.P.UPLOAD. The function time for HR.P.UPLOAD when called from HR.UTILS.COPY_IMAGE is 6,434 microseconds, which is 54.9% of the total function time for HR.P.UPLOAD. After the row "Children" are the execution profile rows for the children of HR.P.UPLOAD when called from HR.P.UPLOAD. The third child execution profile row, for SYS.UTL_FILE.GET_RAW, shows: ■ ■ ■ HR.P.UPLOAD calls SYS.UTL_FILE.GET_RAW 216 times. The subtree time, function time and descendants time for SYS.UTL_FILE.GET_RAW when called from HR.P.UPLOAD are 12,487 microseconds, 3,969 microseconds, and 8,518 microseconds, respectively. Of the total descendants time for HR.P.UPLOAD (155,147 microseconds), the child SYS.UTL_FILE.GET_RAW is responsible for 12,487 microsecs (8.0%). Sample Report HR.P.UPLOAD (Line 3) Subtree Ind% Function Ind% Descendant Ind% Calls Ind% Function Name 166860 100% 11713 7.0% 155147 93.0% 2 0.2% HR.P.UPLOAD (Line 3) Using the PL/SQL Hierarchical Profiler 8-17 plshprof Utility Subtree Ind% Function Ind% Descendant Ind% Calls Ind% Function Name Parents: 106325 63.7% 6434 54.9% 99891 64.4% 1 50.0% HR.UTILS.COPY_ IMAGE (Line 3) 60535 36.3% 5279 45.1% 55256 35.6% 1 50.0% HR.UTILS.COPY_ FILE (Line 8)) 71818 46.3% 71818 100% 0 N/A 2 100% HR.P.__static_sql_ exec_line38 (Line 38) 67649 43.6% 67649 100% 0 N/A 214 100% SYS.DBMS_ LOB.WRITEAPPEN D (Line 926) 12487 8.0% 3969 100% 8518 100% 216 100% SYS.UTL_FILE.GET_ RAW (Line 1089) 1401 0.9% 1401 100% 0 N/A 2 100% HR.P.__static_sql_ exec_line39 (Line 39) 839 0.5% 839 100% 0 N/A 214 100% SYS.UTL_FILE.GET_ RAW (Line 246) 740 0.5% 73 100% 667 100% 2 100% SYS.UTL_ FILE.FOPEN (Line 422) 113 0.1% 11 100% 102 100% 2 100% SYS.UTL_ FILE.FCLOSE (Line 585) 100 0.1% 100 100% 0 N/A 100% SYS.DBMS_ LOB.CREATETEMP ORARY (Line 536) Children: 2 HTML Difference Report from Two Raw Profiler Output Files To generate a PL/SQL hierarchical profiler HTML difference report from two raw profiler output files, use these commands: % cd target_directory % plshprof -output html_root_filename profiler_output_filename_1 profiler_output_filename_2 target_directory is the directory in which you want the HTML files to be created. html_root_filename is the name of the root HTML file to be created. profiler_output_filename_1 and profiler_output_filename_2 are the names of raw profiler output files. The preceding plshprof command generates a set of HTML files. Start browsing them from html_root_filename.html. Topics: Difference Report Conventions ■ ■ First Page of Difference Report ■ Function-Level Difference Reports ■ Module-Level Difference Reports ■ Namespace-Level Difference Reports 8-18 Oracle Database Advanced Application Developer's Guide plshprof Utility ■ Parents and Children Difference Report for a Function Difference Report Conventions Difference reports use these conventions: ■ ■ ■ ■ In a report title, Delta means difference, or change. A positive value indicates that the number increased (regressed) from the first run to the second run. A negative value for a difference indicates that the number decreased (improved) from the first run to the second run. The symbol # after a function name means that the function was called in only one run. First Page of Difference Report The first page of an HTML difference report from two raw profiler output files includes summary information and hyperlinks to other pages of the report. Sample First Page PL/SQL Elapsed Time (microsecs) Analysis – Summary Page This analysis finds a net regression of 2709589 microsecs (elapsed time) or 80% (3393719 versus 6103308). Here is a summary of the 7 most important individual function regressions and improvements: Regressions: 3399382 microsecs (elapsed time) Function Rel% Ind% Calls 2075627 +941% 61.1% 0 1101384 +54.6% 32.4% 5 6.5% 1 222371 Rel% Function Name HR.P.G (Line 35) +55.6% HR.P.H (Line 18) HR.P.J (Line 10) Improvements: 689793 microsecs (elapsed time) Function Rel% Ind% Calls Rel% Function Name -467051 -50.0% 67.7% -2 -50.0% HR.P.F (Line 25) 32.3% -1 HR.P.I (Line 2)# 0.0% 0 HR.P.TEST (Line 46) -222737 -5 -21.7% The PL/SQL Timing Analyzer produces a collection of reports that present information derived from the profiler's output logs in a variety of formats. The following reports have been found to be the most generally useful as starting points for browsing: ■ Function Elapsed Time (microsecs) Data for Performance Regressions ■ Function Elapsed Time (microsecs) Data for Performance Improvements In addition, the following reports are also available: ■ Function Elapsed Time (microsecs) Data sorted by Function Name Using the PL/SQL Hierarchical Profiler 8-19 plshprof Utility ■ ■ ■ Function Elapsed Time (microsecs) Data sorted by Total Subtree Elapsed Time (microsecs) Delta Function Elapsed Time (microsecs) Data sorted by Total Function Elapsed Time (microsecs) Delta Function Elapsed Time (microsecs) Data sorted by Total Descendants Elapsed Time (microsecs) Delta ■ Function Elapsed Time (microsecs) Data sorted by Total Function Call Count Delta ■ Module Elapsed Time (microsecs) Data sorted by Module Name ■ Module Elapsed Time (microsecs) Data sorted by Total Function Elapsed Time (microsecs) Delta ■ Module Elapsed Time (microsecs) Data sorted by Total Function Call Count Delta ■ Namespace Elapsed Time (microsecs) Data sorted by Namespace ■ Namespace Elapsed Time (microsecs) Data sorted by Total Function Elapsed Time (microsecs) ■ Namespace Elapsed Time (microsecs) Data sorted by Total Function Call Count ■ File Elapsed Time (microsecs) Data Comparison with Parents and Children Function-Level Difference Reports Each function-level difference report includes, for each function, the change in these values from the first run to the second run: ■ Function time (time spent in the function itself, also called "self time") ■ Descendants time (time spent in the descendants of the function) ■ Subtree time (time spent in the subtree of the function—function time plus descendants time) ■ Number of calls to the function ■ Mean function time The mean function time is the function time divided by number of calls to the function. ■ Function name The function name is hyperlinked to the Parents and Children Difference Report for the function. The report in Sample Report 1 shows the difference information for all functions that performed better in the first run than they did in the second run. Note that: ■ ■ ■ For HR.P.G, the function time increased by 2,075,627 microseconds (941%), which accounts for 61.1% of all regressions. For HR.P.H, the function time and number of calls increased by 1,101,384 microseconds (54.6%) and 5 (55.6%), respectively, but the mean function time improved by 1,346 microseconds (-0.6%). HR.P.J was called in only one run. Sample Report 1 Function Elapsed Time (microsecs) Data for Performance Regressions 8-20 Oracle Database Advanced Application Developer's Guide plshprof Utility Subtree Function Rel% Ind% Cum% Descendant Calls Rel% 4075787 2075627 +941% 61.1% 61.1% 1101384 1101384 222371 222371 2000160 0 +54.6% 32.4% 93.5% 0 5 6.5% 0 1 100% Mean Function Rel% 2075627 Function Name +941% HR.P.G (Line 35) +55.6% -1346 -0.6% HR.P.H (Line 18) HR.P.J (Line 10)# The report in Sample Report 2 shows the difference information for all functions that performed better in the second run than they did in the first run. Sample Report 2 Function Elapsed Time (microsecs) Data for Performance Improvements Subtree Function Rel% -1365827 -467051 -222737 -222737 2709589 -5 -50.0% -21.7% Ind% Cum% Descendant Calls Rel% 67.7% 67.7% -898776 -2 32.3% 100% 0 -1 2709594 0 0.0% 100% -50.0% Mean Function Rel% Function Name -32 HR.P.F (Line 25) 0.0% HR.P.I (Line 2) -5 -20.8 HR.P.TEST (Line 46)# The report in Sample Report 3 summarizes the difference information for all functions. Sample Report 3 Function Elapsed Time (microsecs) Data sorted by Total Function Call Count Delta Subtree Function Rel% Ind% Descendant Calls Rel% Mean Function Rel% 1101384 1101384 +54.6% 32.4% 0 5 +55.6% -1346 -1365827 -467051 +50.0% 67.7% -898776 -2 -50.0% -32 Function Name -0.6% HR.P.H (Line 18) -0.0% HR.P.F (Line 25) -222377 -222377 32.3% 0 -1 HR.P.I (Line 2)# 222371 222371 6.5% 0 1 HR.P.J(Line 10)# 4075787 2075627 +941% 61.1% 2000160 0 2075627 +941% HR.P.G (Line 35) 2709589 -5 -21.7% 0.0% 2709594 0 -5 -20.8% HR.P.TEST (Line 46) 0 0 0 0 SYS.DBMS_HPROF.STOP_ PROFILING (Line 53) Module-Level Difference Reports Each module-level report includes, for each module, the change in these values from the first run to the second run: ■ ■ Module time (time spent in the module—sum of the function times of all functions in the module) Number of calls to functions in the module Sample Report Module Elapsed Time (microsecs) Data sorted by Total Function Elapsed Time (microsecs) Delta Module Calls Module Name 2709589 3 HR.P 0 0 SYS.DBMS_HPROF Using the PL/SQL Hierarchical Profiler 8-21 plshprof Utility Namespace-Level Difference Reports Each namespace-level report includes, for each namespace, the change in these values from the first run to the second run: ■ ■ Namespace time (time spent in the namespace—sum of the function times of all functions in the namespace) Number of calls to functions in the namespace Sample Report Namespace Elapsed Time (microsecs) Data sorted by Namespace Function Calls Namespace 2709589 3 PLSQL Parents and Children Difference Report for a Function The Parents and Children Difference Report for a function shows changes in the execution profiles of these from the first run to the second run: ■ Parents (functions that call the function) ■ Children (functions that the function calls) Execution profiles for children include only information from when this function calls them, not for when other functions call them. The execution profile for a function includes this information: ■ Function time (time spent in the function itself, also called "self time") ■ Descendants time (time spent in the descendants of the function) ■ Subtree time (time spent in the subtree of the function—function time plus descendants time) ■ Number of calls to the function ■ Function name The sample report is a fragment of a Parents and Children Difference Report that corresponds to a function named HR.P.X. The first row, a summary of the difference between the first and second runs, shows regression: function time increased by 1,094,099 microseconds (probably because the function was called five more times). The "Parents" rows show that HR.P.G called HR.P.X nine more times in the second run than it did in the first run, while HR.P.F called it four fewer times. The "Children" rows show that HR.P.X called each child five more times in the second run than it did in the first run. Sample Report HR.P.X (Line 11) Subtree Function Descendant Calls Function Name 3322196 1094099 HR.P.X (Line 11) 2228097 5 Parents: 8-22 Oracle Database Advanced Application Developer's Guide plshprof Utility Subtree Function Descendant Calls Function Name 6037490 1993169 4044321 9 HR.P.G (Line 38) -2715294 -899070 -1816224 -4 HR.P.F (Line 28) 1125489 1125489 0 5 HR.P.J (Line 10) 1102608 1102608 0 5 HR.P.I (Line 2) Children: The Parents and Children Difference Report for a function is accompanied by a Function Comparison Report, which shows the execution profile of the function for the first and second runs and the difference between them. This example is the Function Comparison Report for the function HR.P.X: Sample Report Elapsed Time (microsecs) for HR.P.X (Line 11) (20.1% of total regression) HR.P.X (Line 11) First Trace Ind% Second Trace Ind% Function Elapsed Time (microsecs) 1999509 26.9% 3093608 24.9% 1094099 +54.7% Descendants Elapsed Time (microsecs) 4095943 55.1% 6324040 50.9% 2228097 +54.4% Subtree Elapsed Time (microsecs) 6095452 81.9% 9417648 75.7% 3322196 +54.5% Function Calls 9 25.0% 14 28.6% 5 Mean Function Elapsed Time (microsecs) 222167.7 220972.0 -1195.7 -0.5% Mean Descendants Elapsed Time (microsecs) 455104.8 451717.1 -3387.6 -0.7% Mean Subtree Elapsed Time (microsecs) 677272.4 672689.1 -4583.3 -0.7% Diff Diff% +55.6% Using the PL/SQL Hierarchical Profiler 8-23 plshprof Utility 8-24 Oracle Database Advanced Application Developer's Guide 9 Developing PL/SQL Web Applications 9 This chapter explains how to develop PL/SQL web applications, which let you make your database available on the intranet. Topics: ■ Overview of PL/SQL Web Applications ■ Implementing PL/SQL Web Applications ■ Using mod_plsql Gateway to Map Client Requests to a PL/SQL Web Application ■ Using Embedded PL/SQL Gateway ■ Generating HTML Output with PL/SQL ■ Passing Parameters to PL/SQL Web Applications ■ Performing Network Operations in PL/SQL Subprograms Overview of PL/SQL Web Applications Typically, a web application written in PL/SQL is a set of stored subprograms that interact with web browsers through HTTP. A set of interlinked, dynamically generated HTML pages forms the user interface of a web application. The program flow of a PL/SQL web application is similar to that in a CGI PERL script. Developers often use CGI scripts to produce web pages dynamically, but such scripts are often not optimal for accessing the database. Delivering web content with PL/SQL stored subprograms provides the power and flexibility of database processing. For example, you can use data manipulation language (DML) statements, dynamic SQL statements, and cursors. You also eliminate the process overhead of forking a new CGI process to handle each HTTP request. Figure 9–1 illustrates the generic process for a PL/SQL web application. Developing PL/SQL Web Applications 9-1 Implementing PL/SQL Web Applications Figure 9–1 PL/SQL Web Application Stored Procedure 4 2 Web Browser 3 PL/SQL Web Toolkit 5 1 Web Server Implementing PL/SQL Web Applications You can implement a web browser-based application entirely in PL/SQL with these Oracle Database components: ■ PL/SQL Gateway ■ PL/SQL Web Toolkit PL/SQL Gateway The PL/SQL gateway enables a web browser to invoke a PL/SQL stored subprogram through an HTTP listener. The gateway is a platform on which PL/SQL users develop and deploy PL/SQL web applications. mod_plsql mod_plsql is one implementation of the PL/SQL gateway. The module is a plug-in of Oracle HTTP Server and enables web browsers to invoke PL/SQL stored subprograms. Oracle HTTP Server is a component of both Oracle Application Server and the database. The mod_plsql plug-in enables you to use PL/SQL stored subprograms to process HTTP requests and generate responses. In this context, an HTTP request is a URL that includes parameter values to be passed to a stored subprogram. PL/SQL gateway translates the URL, invokes the stored subprogram with the parameters, and returns output (typically HTML) to the client. Some advantages of using mod_plsql over the embedded form of the PL/SQL gateway are: ■ ■ You can run it in a firewall environment in which the Oracle HTTP Server runs on a firewall-facing host while the database is hosted behind a firewall. You cannot use this configuration with the embedded gateway. The embedded gateway does not support mod_plsql features such as dynamic HTML caching, system monitoring, and logging in the Common Log Format. 9-2 Oracle Database Advanced Application Developer's Guide Implementing PL/SQL Web Applications Embedded PL/SQL Gateway You can use an embedded version of the PL/SQL gateway that runs in the XML DB HTTP Listener in the database. It provides the core features of mod_plsql in the database but does not require the Oracle HTTP Server. You configure the embedded PL/SQL gateway with the DBMS_EPG package in the PL/SQL Web Toolkit. Some advantages of using the embedded gateway over mod_plsql are as follows: ■ ■ You can invoke PL/SQL web applications such as Application Express without installing Oracle HTTP Server, thereby simplifying installation, configuration, and administration of PL/SQL based web applications. You use the same configuration approach that is used to deliver content from Oracle XML DB in response to FTP and HTTP requests. PL/SQL Web Toolkit This set of PL/SQL packages is a generic interface that enables you to use stored subprograms invoked by mod_plsql at run time. In response to a browser request, a PL/SQL subprogram updates or retrieves data from Oracle Database according to the user input. It then generates an HTTP response to the browser, typically in the form of a file download or HTML to be displayed. The PL/SQL Web Toolkit API enables stored subprograms to perform actions such as: ■ Obtain information about an HTTP request ■ Generate HTTP headers such as content-type and mime-type ■ Set browser cookies ■ Generate HTML pages Table 9–1 describes commonly used PL/SQL Web Toolkit packages. Table 9–1 Commonly Used Packages in the PL/SQL Web Toolkit Package Description of Contents HTF Function versions of the subprograms in the htp package. The function versions do not directly generate output in a web page. Instead, they pass their output as return values to the statements that invoke them. Use these functions when you must nest function calls. HTP Subprograms that generate HTML tags. For example, the procedure htp.anchor generates the HTML anchor tag, . OWA_CACHE Subprograms that enable the PL/SQL gateway cache feature to improve performance of your PL/SQL web application. You can use this package to enable expires-based and validation-based caching with the PL/SQL gateway file system. OWA_COOKIE Subprograms that send and retrieve HTTP cookies to and from a client web browser. Cookies are strings a browser uses to maintain state between HTTP calls. State can be maintained throughout a client session or longer if a cookie expiration date is included. OWA_CUSTOM The authorize function used by cookies. OWA_IMAGE Subprograms that obtain the coordinates where a user clicked an image. Use this package when you have an image map whose destination links invoke a PL/SQL gateway. Developing PL/SQL Web Applications 9-3 Using mod_plsql Gateway to Map Client Requests to a PL/SQL Web Application Table 9–1 (Cont.) Commonly Used Packages in the PL/SQL Web Toolkit Package Description of Contents OWA_OPT_LOCK Subprograms that impose database optimistic locking strategies to prevent lost updates. Lost updates can otherwise occur if a user selects, and then attempts to update, a row whose values were changed in the meantime by another user. OWA_PATTERN Subprograms that perform string matching and string manipulation with regular expressions. OWA_SEC Subprograms used by the PL/SQL gateway for authenticating requests. OWA_TEXT Subprograms used by package OWA_PATTERN for manipulating strings. You can also use them directly. OWA_UTIL These types of utility subprograms: ■ ■ ■ WPG_DOCLOAD Dynamic SQL utilities to produce pages with dynamically generated SQL code. HTML utilities to retrieve the values of CGI environment variables and perform URL redirects. Date utilities for correct date-handling. Date values are simple strings in HTML, but must be properly treated as an Oracle Database data type. Subprograms that download documents from a document repository that you define using the DAD configuration. See Also: Oracle Database PL/SQL Packages and Types Reference for syntax, descriptions, and examples for the PL/SQL Web Toolkit packages Using mod_plsql Gateway to Map Client Requests to a PL/SQL Web Application As explained in detail in the Oracle HTTP Server mod_plsql User's Guide, mod_plsql maps web client requests to PL/SQL stored subprograms over HTTP. See this documentation for instructions. See Also: ■ ■ Oracle HTTP Server mod_plsql User's Guide to learn how to configure and use mod_plsql Oracle Fusion Middleware Administrator's Guide for Oracle HTTP Server for information about the mod_plsql module Using Embedded PL/SQL Gateway The embedded gateway functions very similar to the mod_plsql gateway. Before using the embedded version of the gateway, familiarize yourself with the Oracle HTTP Server mod_plsql User's Guide. Much of the information is the same or similar. Topics: ■ How Embedded PL/SQL Gateway Processes Client Requests ■ Installing Embedded PL/SQL Gateway ■ Configuring Embedded PL/SQL Gateway ■ Invoking PL/SQL Stored Subprograms Through Embedded PL/SQL Gateway 9-4 Oracle Database Advanced Application Developer's Guide Using Embedded PL/SQL Gateway ■ Securing Application Access with Embedded PL/SQL Gateway ■ Restrictions in Embedded PL/SQL Gateway ■ Using Embedded PL/SQL Gateway: Scenario How Embedded PL/SQL Gateway Processes Client Requests Figure 9–2 illustrates the process by which the embedded gateway handles client HTTP requests. Figure 9–2 Processing Client Requests with Embedded PL/SQL Gateway Web Browser User-level caching in browser Embedded PL/SQL Gateway Oracle XDB HTTP Listener Web Browser 7 2 3 6 8 Authentication 1 4 Web Server PL/SQL Application Web Browser 5 PL/SQL Web Toolkit The explanation of the steps in Figure 9–2 is as follows: 1. The Oracle XML DB HTTP Listener receives a request from a client browser to request to invoke a PL/SQL subprogram. The subprogram can either be written directly in PL/SQL or indirectly generated when a PL/SQL Server Page is uploaded to the database and compiled. 2. The XML DB HTTP Listener routes the request to the embedded PL/SQL gateway as specified in its virtual-path mapping configuration. 3. The embedded gateway uses the HTTP request information and the gateway configuration to determine which database account to use for authentication. 4. The embedded gateway prepares the call parameters and invokes the PL/SQL subprogram in the application. 5. The PL/SQL subprogram generates an HTML page out of relational data and the PL/SQL Web Toolkit accessed from the database. Developing PL/SQL Web Applications 9-5 Using Embedded PL/SQL Gateway 6. The application sends the page to the embedded gateway. 7. The embedded gateway sends the page to the XML DB HTTP Listener. 8. The XML DB HTTP Listener sends the page to the client browser. Unlike mod_plsql, the embedded gateway processes HTTP requests with the Oracle XML DB Listener. This listener is the same server-side process as the Oracle Net Listener and supports Oracle Net Services, HTTP, and FTP. Configure general HTTP listener settings through the XML DB interface (for instructions, see Oracle XML DB Developer's Guide). Configure the HTTP listener either by using Oracle Enterprise Manager or by editing the xdbconfig.xml file. Use the DBMS_EPG package for all embedded PL/SQL gateway configuration, for example, creating or setting attributes for a DAD. Installing Embedded PL/SQL Gateway The embedded gateway requires these components: ■ XML DB HTTP Listener ■ PL/SQL Web Toolkit The embedded PL/SQL gateway is installed as part of Oracle XML DB. If you are using a preconfigured database created during an installation or by the Database Configuration Assistant (DBCA), then Oracle XML DB is installed and configured. For information about manually adding Oracle XML DB to an existing database, see Oracle XML DB Developer's Guide. The PL/SQL Web Toolkit is part of the standard installation of the database, so no supplementary installation is necessary. Configuring Embedded PL/SQL Gateway You configure mod_plsql by editing the Oracle HTTP Server configuration files. Because the embedded gateway is installed as part of the Oracle XML DB HTTP Listener, you manage the embedded gateway as a servlet through the Oracle XML DB servlet management interface. The configuration interface to the embedded gateway is the PL/SQL package DBMS_ EPG. This package modifies the underlying xdbconfig.xml configuration file that XML DB uses. The default values of the embedded gateway configuration parameters are sufficient for most users. Topics: ■ Configuring Embedded PL/SQL Gateway: Overview ■ Configuring User Authentication for Embedded PL/SQL Gateway Configuring Embedded PL/SQL Gateway: Overview As in mod_plsql, each request for a PL/SQL stored subprogram is associated with a Database Access Descriptor (DAD). A DAD is a set of configuration values used for database access. A DAD specifies information such as: ■ The database account to use for authentication ■ The subprogram to use for uploading and downloading documents In the embedded PL/SQL gateway, a DAD is represented as a servlet in the XML DB HTTP Listener configuration. Each DAD attribute maps to an XML element in the 9-6 Oracle Database Advanced Application Developer's Guide Using Embedded PL/SQL Gateway configuration file xdbconfig.xml. The value of the DAD attribute corresponds to the element content. For example, the database-username DAD attribute corresponds to the XML element; if the value of the DAD attribute is HR it corresponds to HR . DAD attribute names are case-sensitive. Use the DBMS_EPG package to perform these embedded PL/SQL gateway configurations: 1. Create a DAD with the DBMS_EPG.CREATE_DAD procedure. 2. Set DAD attributes with the DBMS_EPG.SET_DAD_ATTRIBUTE procedure. All DAD attributes are optional. If you do not specify an attribute, it has its initial value. Table 9–2 lists the embedded PL/SQL gateway attributes and the corresponding mod_ plsql DAD parameters. Enumeration values in the "Legal Values" column are case-sensitive. Table 9–2 Mapping Between mod_plsql and Embedded PL/SQL Gateway DAD Attributes mod_plsql DAD Attribute Embedded PL/SQL Gateway DAD Attribute Multiple Occurrences Legal Values PlsqlAfterProcedure after-procedure No String PlsqlAlwaysDescribeProcedure always-describe-procedure No Enumeration of On, Off PlsqlAuthenticationMode authentication-mode No Enumeration of Basic, SingleSignOn, GlobalOwa, CustomOwa, PerPackageOwa PlsqlBeforeProcedure before-procedure No String PlsqlBindBucketLengths bind-bucket-lengths Yes Unsigned integer PlsqlBindBucketWidths bind-bucket-widths Yes Unsigned integer PlsqlCGIEnvironmentList cgi-environment-list Yes String PlsqlCompatibilityMode compatibility-mode No Unsigned integer PlsqlDatabaseUsername database-username No String PlsqlDefaultPage default-page No String PlsqlDocumentPath document-path No String PlsqlDocumentProcedure document-procedure No String PlsqlDocumentTablename document-table-name No String PlsqlErrorStyle error-style No Enumeration of ApacheStyle, ModplsqlStyle, DebugStyle PlsqlExclusionList exclusion-list Yes String PlsqlFetchBufferSize fetch-buffer-size No Unsigned integer PlsqlInfoLogging info-logging No Enumeration of InfoDebug PlsqlInputFilterEnable input-filter-enable No String PlsqlMaxRequestsPerSession max-requests-per-session No Unsigned integer PlsqlNLSLanguage nls-language No String PlsqlOWADebugEnable owa-debug-enable No Enumeration of On, Off PlsqlPathAlias path-alias No String PlsqlPathAliasProcedure path-alias-procedure No String PlsqlRequestValidationFunction request-validation-function No String PlsqlSessionCookieName session-cookie-name No String Developing PL/SQL Web Applications 9-7 Using Embedded PL/SQL Gateway Table 9–2 (Cont.) Mapping Between mod_plsql and Embedded PL/SQL Gateway DAD Attributes mod_plsql DAD Attribute Embedded PL/SQL Gateway DAD Attribute Multiple Occurrences PlsqlSessionStateManagement session-state-management No Enumeration of StatelessWithResetPackageState, StatelessWithFastRestPackageState, StatelessWithPreservePackageState PlsqlTransferMode transfer-mode No Enumeration of Char, Raw PlsqlUploadAsLongRaw upload-as-long-raw No String Legal Values The default values of the DAD attributes are sufficient for most users of the embedded gateway. mod_plsql users do not need these attributes: ■ ■ PlsqlDatabasePassword PlsqlDatabaseConnectString (because the embedded gateway does not support logon to external databases) Like the DAD attributes, the global configuration parameters are optional. Table 9–3 describes the DBMS_EPG global attributes and the corresponding mod_plsql global parameters. Table 9–3 Mapping Between mod_plsql and Embedded PL/SQL Gateway Global Attributes mod_plsql DAD Attribute Embedded PL/SQL Gateway DAD Attribute Multiple Occurrences Legal Values PlsqlLogLevel log-level No Unsigned integer PlsqlMaxParameters max-parameters No Unsigned integer See Also: ■ ■ ■ Oracle Fusion Middleware Administrator's Guide for Oracle HTTP Server for detailed descriptions of the mod_plsql DAD attributes. See this documentation for default values and usage notes. Oracle Database PL/SQL Packages and Types Reference to learn about the DBMS_EPG package Oracle XML DB Developer's Guide for an account of the xdbconfig.xml file Configuring User Authentication for Embedded PL/SQL Gateway Because it uses the XML DB authentication schemes, the embedded gateway handles database authentication differently from mod_plsql. In particular, it does not store database passwords in a DAD. To serve a PL/SQL web application on the Internet but maintain the database behind a firewall, do not use the embedded PL/SQL gateway to run the application; use mod_plsql. Note: Use the DBMS_EPG package to configure database authentication. Topics: ■ Configuring Static Authentication with DBMS_EPG ■ Configuring Dynamic Authentication with DBMS_EPG 9-8 Oracle Database Advanced Application Developer's Guide Using Embedded PL/SQL Gateway ■ Configuring Anonymous Authentication with DBMS_EPG ■ Determining the Authentication Mode of a DAD ■ Creating and Configuring DADs: Examples ■ Determining the Authentication Mode for a DAD: Example ■ Determining the Authentication Mode for All DADs: Example ■ Showing DAD Authorizations that Are Not in Effect: Example ■ Examining Embedded PL/SQL Gateway Configuration Configuring Static Authentication with DBMS_EPG Static authentication is for the mod_plsql user who stores database user names and passwords in the DAD so that the browser user is not required to enter database authentication information. To configure static authentication, follow these steps: 1. Log on to the database as an XML DB administrator (that is, a user with the XDBADMIN role assigned). 2. Create the DAD. For example, this procedure creates a DAD invoked HR_DAD and maps the virtual path to /hrweb/: EXEC DBMS_EPG.CREATE_DAD('HR_DAD', '/hrweb/*'); 3. For this step, you need the ALTER ANY USER system privilege. Set the DAD attribute database-username to the database account whose privileges must be used by the DAD. For example, this procedure specifies that the DAD named HR_DAD has the privileges of the HR account: EXEC DBMS_EPG.SET_DAD_ATTRIBUTE('HR_DAD', 'database-username', 'HR'); The DAD attribute database-username is case-sensitive. 4. Assign the DAD the privileges of the database user specified in the previous step. This authorization enables end users to invoke procedures and access document tables through the embedded PL/SQL gateway with the privileges of the authorized account. For example: EXEC DBMS_EPG.AUTHORIZE_DAD('HR_DAD', 'HR'); Alternatively, you can log off as the user with XDBADMIN privileges, log on as the database user whose privileges must be used by the DAD, and then use this command to assign these privileges to the DAD: EXEC DBMS_EPG.AUTHORIZE_DAD('HR_DAD'); Multiple users can authorize the same DAD. The database-username attribute setting of the DAD determines which user's privileges to use. Note: Unlike mod_plsql, the embedded gateway connects to the database as the special user ANONYMOUS, but accesses database objects with the user privileges assigned to the DAD. The database rejects access if the browser user attempts to connect explicitly with the HTTP Authorization header. Developing PL/SQL Web Applications 9-9 Using Embedded PL/SQL Gateway The account ANONYMOUS is locked after XML DB installation. To use static authentication with the embedded PL/SQL gateway, first unlock this account. Note: Configuring Dynamic Authentication with DBMS_EPG Dynamic authentication is for the mod_plsql user who does not store database user names and passwords in the DAD. In dynamic authentication, a database user does not have to authorize the embedded gateway to use its privileges to access database objects. Instead, browser users must supply the database authentication information through the HTTP Basic Authentication scheme. The action of the embedded gateway depends on whether the database-username attribute is set for the DAD. If the attribute is not set, then the embedded gateway connects to the database as the user supplied by the browser client. If the attribute is set, then the database restricts access to the user specified in the database-username attribute. To set up dynamic authentication, follow these steps: 1. Log on to the database as a an XML DB administrator (that is, a user with the XDBADMIN role). 2. Create the DAD. For example, this procedure creates a DAD invoked DYNAMIC_DAD and maps the virtual path to /hrweb/: EXEC DBMS_EPG.CREATE_DAD('DYNAMIC_DAD', '/hrweb/*'); 3. Optionally, set the DAD attribute database-username to the database account whose privileges must be used by the DAD. The browser prompts the user to enter the username and password for this account when accessing the DAD. For example, this procedure specifies that the DAD named DYNAMIC_DAD has the privileges of the HR account: EXEC DBMS_EPG.SET_DAD_ATTRIBUTE('DYNAMIC_DAD', 'database-username', 'HR'); The attribute database-username is case-sensitive. WARNING: Passwords sent through the HTTP Basic Authentication scheme are not encrypted. Configure the embedded gateway to use the HTTPS protocol to protect the passwords sent by the browser clients. Configuring Anonymous Authentication with DBMS_EPG Anonymous authentication is for the mod_plsql user who creates a special DAD database user for database logon, but stores the application procedures and document tables in a different schema and grants access to the procedures and document tables to PUBLIC. To set up anonymous authentication, follow these steps: 1. Log on to the database as an XML DB administrator, that is, a user with the XDBADMIN role assigned. 2. Create the DAD. For example, this procedure creates a DAD invoked HR_DAD and maps the virtual path to /hrweb/: EXEC DBMS_EPG.CREATE_DAD('HR_DAD', '/hrweb/*'); 9-10 Oracle Database Advanced Application Developer's Guide Using Embedded PL/SQL Gateway 3. Set the DAD attribute database-username to ANONYMOUS. For example: EXEC DBMS_EPG.SET_DAD_ATTRIBUTE('HR_DAD', 'database-username', 'ANONYMOUS'); Both database-username and ANONYMOUS are case-sensitive. You need not authorize the embedded gateway to use ANONYMOUS privileges to access database objects, because ANONYMOUS has no system privileges and owns no database objects. Determining the Authentication Mode of a DAD If you know the name of a DAD, then the authentication mode for this DAD depends on these factors: ■ Does the DAD exist? ■ Is the database-username attribute for the DAD set? ■ Is the DAD authorized to use the privilege of the database-username user? ■ Is the database-username attribute the one that the user authorized to use the DAD? Table 9–4 shows how the answers to the preceding questions determine the authentication mode. Table 9–4 Authentication Possibilities for a DAD DAD Exists? database-username set? User authorized? Mode Yes Yes Yes Static Yes Yes No Dynamic restricted Yes No Does not matter Dynamic Yes Yes (to ANONYMOUS) Does not matter Anonymous No N/A For example, assume that you create a DAD named MY_DAD. If the database-username attribute for MY_DAD is set to HR, but the HR user does not authorize MY_DAD, then the authentication mode for MY_DAD is dynamic and restricted. A browser user who attempts to run a PL/SQL subprogram through MY_DAD is prompted to enter the HR database username and password. The DBA_EPG_DAD_AUTHORIZATION view shows which users have authorized use of a DAD. The DAD_NAME column displays the name of the DAD; the USERNAME column displays the user whose privileges are assigned to the DAD. The DAD authorized might not exist. Oracle Database Reference for more information about the DBA_EPG_DAD_AUTHORIZATION view See Also: Creating and Configuring DADs: Examples Example 9–1 does this: ■ Creates a DAD with static authentication for database user HR and assigns it the privileges of the HR account, which then authorizes it. ■ Creates a DAD with dynamic authentication that is not restricted to any user. ■ Creates a DAD with dynamic authentication that is restricted to the HR account. Example 9–1 Creating and Configuring DADs -----------------------------------------------------------------------Developing PL/SQL Web Applications 9-11 Using Embedded PL/SQL Gateway --- DAD with static authentication -----------------------------------------------------------------------CONNECT SYSTEM AS SYSDBA PASSWORD: password EXEC DBMS_EPG.CREATE_DAD('Static_Auth_DAD', '/static/*'); EXEC DBMS_EPG.SET_DAD_ATTRIBUTE('Static_Auth_DAD', 'database-username', 'HR'); GRANT EXECUTE ON DBMS_EPG TO HR; -- Authorization CONNECT HR PASSWORD: password EXEC DBMS_EPG.AUTHORIZE_DAD('Static_Auth_DAD'); ------------------------------------------------------------------------- DAD with dynamic authentication -----------------------------------------------------------------------CONNECT SYSTEM AS SYSDBA PASSWORD: password EXEC DBMS_EPG.CREATE_DAD('Dynamic_Auth_DAD', '/dynamic/*'); -------------------------------------------------------------------------- DAD with dynamic authentication restricted ------------------------------------------------------------------------EXEC DBMS_EPG.CREATE_DAD('Dynamic_Auth_DAD_Restricted', '/dynamic/*'); EXEC DBMS_EPG.SET_DAD_ATTRIBUTE ('Dynamic_Auth_DAD_Restricted', 'database-username', 'HR'); The creation and authorization of a DAD are independent; therefore you can: ■ ■ Authorize a DAD that does not exist (it can be created later) Authorize a DAD for which you are not the user (however, the authorization does not take effect until the DAD database-user attribute is changed to your username) Example 9–2 creates a DAD with static authentication for database user HR and assigns it the privileges of the HR account. Then: ■ Instead of authorizing that DAD, the database user HR authorizes a nonexistent DAD. Although the user might have done this by mistake, no error occurs, because the nonexistent DAD might be created later. ■ The database user OE authorizes the DAD (whose database-user attribute is set to HR. No error occurs, but the authorization does not take effect until the DAD database-user attribute is changed to OE. Example 9–2 Authorizing DADs to be Created or Changed Later REM Create DAD with static authentication for database user HR CONNECT SYSTEM AS SYSDBA PASSWORD: password EXEC DBMS_EPG.CREATE_DAD('Static_Auth_DAD', '/static/*'); EXEC DBMS_EPG.SET_DAD_ATTRIBUTE('Static_Auth_DAD', 'database-username', 'HR'); GRANT EXECUTE ON DBMS_EPG TO HR; 9-12 Oracle Database Advanced Application Developer's Guide Using Embedded PL/SQL Gateway REM Database user HR authorizes DAD that does not exist CONNECT HR PASSWORD: password EXEC DBMS_EPG.AUTHORIZE_DAD('Static_Auth_DAD_Typo'); REM Database user OE authorizes DAD with database-username 'HR' CONNECT OE PASSWORD: password EXEC DBMS_EPG.AUTHORIZE_DAD('Static_Auth_DAD'); Determining the Authentication Mode for a DAD: Example Example 9–3 creates a PL/SQL procedure, show_dad_auth_status, which accepts the name of a DAD and reports its authentication mode. If the specified DAD does not exist, the procedure exits with an error. Example 9–3 Determining the Authentication Mode for a DAD CREATE OR REPLACE PROCEDURE show_dad_auth_status (p_dadname VARCHAR2) IS v_daduser VARCHAR2(32); v_cnt PLS_INTEGER; BEGIN -- Determine DAD user v_daduser := DBMS_EPG.GET_DAD_ATTRIBUTE(p_dadname, 'database-username'); -- Determine whether DAD authorization exists for DAD user SELECT COUNT(*) INTO v_cnt FROM DBA_EPG_DAD_AUTHORIZATION da WHERE da.DAD_NAME = p_dadname AND da.USERNAME = v_daduser; -- If DAD authorization exists for DAD user, authentication mode is static IF (v_cnt > 0) THEN DBMS_OUTPUT.PUT_LINE ( '''' || p_dadname || ''' is set up for static authentication for user ''' || v_daduser || '''.'); RETURN; END IF; -- If no DAD authorization exists for DAD user, authentication mode is dynamic -- Determine whether dynamic authentication is restricted to particular user IF (v_daduser IS NOT NULL) THEN DBMS_OUTPUT.PUT_LINE ( '''' || p_dadname || ''' is set up for dynamic authentication for user ''' || v_daduser || ''' only.'); ELSE DBMS_OUTPUT.PUT_LINE ( '''' || p_dadname || ''' is set up for dynamic authentication for any user.'); END IF; END; / Developing PL/SQL Web Applications 9-13 Using Embedded PL/SQL Gateway Assume that you have run the script in Example 9–1 to create and configure various DADs. The output is: SET SERVEROUTPUT ON; BEGIN show_dad_auth_status('Static_Auth_DAD'); END; / 'Static_Auth_DAD' is set up for static authentication for user 'HR'. Determining the Authentication Mode for All DADs: Example The anonymous block in Example 9–4 reports the authentication modes of all registered DADs. It invokes the show_dad_auth_status procedure from Example 9–3. Example 9–4 Showing the Authentication Mode for All DADs DECLARE v_dad_names DBMS_EPG.VARCHAR2_TABLE; BEGIN DBMS_OUTPUT.PUT_LINE ('---------- Authorization Status for All DADs ----------'); DBMS_EPG.GET_DAD_LIST(v_dad_names); FOR i IN 1..v_dad_names.count LOOP show_dad_auth_status(v_dad_names(i)); END LOOP; END; / If you have run the script in Example 9–1 to create and configure various DADs, the output of Example 9–4 is: ---------- Authorization Status for All DADs ---------'Static_Auth_DAD' is set up for static auth for user 'HR'. 'Dynamic_Auth_DAD' is set up for dynamic auth for any user. 'Dynamic_Auth_DAD_Restricted' is set up for dynamic auth for user 'HR' only. Showing DAD Authorizations that Are Not in Effect: Example The anonymous block in Example 9–5 reports DAD authorizations that are not in effect. A DAD authorization is not in effect in either of these situations: ■ ■ The user who authorizes the DAD is not the user specified by the database-username attribute of the DAD The user authorizes a DAD that does not exist Example 9–5 Showing DAD Authorizations that Are Not in Effect DECLARE v_dad_names DBMS_EPG.VARCHAR2_TABLE; v_dad_user VARCHAR2(32); v_dad_found BOOLEAN; BEGIN DBMS_OUTPUT.PUT_LINE ('---------- DAD Authorizations Not in Effect ----------'); DBMS_EPG.GET_DAD_LIST(v_dad_names); FOR r IN (SELECT * FROM DBA_EPG_DAD_AUTHORIZATION) LOOP v_dad_found := FALSE; FOR i IN 1..v_dad_names.count LOOP -- Inner loop IF (r.DAD_NAME = v_dad_names(i)) THEN 9-14 Oracle Database Advanced Application Developer's Guide -- Outer loop Using Embedded PL/SQL Gateway v_dad_user := DBMS_EPG.GET_DAD_ATTRIBUTE(r.DAD_NAME, 'database-username'); -- Is database-username the user for whom DAD is authorized? IF (r.USERNAME <> v_dad_user) THEN DBMS_OUTPUT.PUT_LINE ( 'DAD authorization of ''' || r.dad_name || ''' by user ''' || r.username || '''' || ' is not in effect because DAD user is ' || '''' || v_dad_user || '''.'); END IF; v_dad_found := TRUE; EXIT; -- Inner loop END IF; END LOOP; -- Inner loop -- Does DAD exist? IF (NOT v_dad_found) THEN DBMS_OUTPUT.PUT_LINE ( 'DAD authorization of ''' || r.dad_name || ''' by user ''' || r.username || ''' is not in effect because the DAD does not exist.'); END IF; END LOOP; -- Outer loop END; / If you have run the script in Example 9–2 to create and configure various DADs, the output of Example 9–5 (reformatted to fit on the page) is: ---------- DAD Authorizations Not in Effect ---------DAD authorization of 'Static_Auth_DAD' by user 'OE' is not in effect because DAD user is 'HR'. DAD authorization of 'Static_Auth_DAD_Typo' by user 'HR' is not in effect because DAD does not exist. Examining Embedded PL/SQL Gateway Configuration When you are connected to the database as a user with system privileges, this script helps you examine the configuration of the embedded PL/SQL gateway: $ORACLE_HOME/rdbms/admin/epgstat.sql Example 9–6 shows the output of the epgstat.sql script for Example 9–1 when the ANONYMOUS account is locked. Example 9–6 epgstat.sql Script Output for Example 9–1 Command to run script: @$ORACLE_HOME/rdbms/admin/epgstat.sql Result: +--------------------------------------+ | XDB protocol ports: | | XDB is listening for the protocol | | when the protocol port is nonzero. | +--------------------------------------+ HTTP Port FTP Port --------- -------- Developing PL/SQL Web Applications 9-15 Using Embedded PL/SQL Gateway 0 0 1 row selected. +---------------------------+ | DAD virtual-path mappings | +---------------------------+ Virtual Path -------------------------------/dynamic/* /static/* DAD Name -------------------------------Dynamic_Auth_DAD_Restricted Static_Auth_DAD 2 rows selected. +----------------+ | DAD attributes | +----------------+ DAD Name -----------Dynamic_Auth _DAD_Restric ted DAD Param DAD Value --------------------- ---------------------------------------database-username HR Static_Auth_ DAD database-username HR 2 rows selected. +---------------------------------------------------+ | DAD authorization: | | To use static authentication of a user in a DAD, | | the DAD must be authorized for the user. | +---------------------------------------------------+ DAD Name User Name -------------------------------- -------------------------------Static_Auth_DAD HR OE Static_Auth_DAD_Typo HR 3 rows selected. +----------------------------+ | DAD authentication schemes | +----------------------------+ DAD Name User Name -------------------- -------------------------------Dynamic_Auth_DAD Dynamic_Auth_DAD_Res HR tricted Auth Scheme -----------------Dynamic Dynamic Restricted Static_Auth_DAD Static HR 3 rows selected. +--------------------------------------------------------+ 9-16 Oracle Database Advanced Application Developer's Guide Using Embedded PL/SQL Gateway | ANONYMOUS user status: | | To use static or anonymous authentication in any DAD, | | the ANONYMOUS account must be unlocked. | +--------------------------------------------------------+ Database User Status --------------- -------------------ANONYMOUS EXPIRED & LOCKED 1 row selected. +-------------------------------------------------------------------+ | ANONYMOUS access to XDB repository: | | To allow public access to XDB repository without authentication, | | ANONYMOUS access to the repository must be allowed. | +-------------------------------------------------------------------+ Allow repository anonymous access? ---------------------------------false 1 row selected. Invoking PL/SQL Stored Subprograms Through Embedded PL/SQL Gateway The basic steps for invoking PL/SQL subprograms through the embedded PL/SQL gateway are the same as for the mod_plsql gateway. See Oracle HTTP Server mod_plsql User's Guide for instructions. You must adapt the mod_plsql instructions slightly for use with the embedded gateway. For example, invoke the embedded gateway in a browser by entering the URL in this format: protocol://hostname[:port]/virt-path/[[!][schema.][package.]proc_name[?query_str]] The placeholder virt-path stands for the virtual path that you configured in DBMS_ EPG.CREATE_DAD. The mod_plsql documentation uses DAD_location instead of virt-path. These topics documented in Oracle HTTP Server mod_plsql User's Guide apply equally to the embedded gateway: ■ Transaction mode ■ Supported data types ■ Parameter-passing scheme ■ File upload and download support ■ Path-aliasing ■ Common Gateway Interface (CGI) environment variables Securing Application Access with Embedded PL/SQL Gateway The embedded gateway shares the same protection mechanism with mod_plsql. See Oracle HTTP Server mod_plsql User's Guide for instructions. Developing PL/SQL Web Applications 9-17 Using Embedded PL/SQL Gateway Restrictions in Embedded PL/SQL Gateway The mod_plsql restrictions documented in the first chapter of Oracle HTTP Server mod_ plsql User's Guide apply equally to the embedded gateway. In addition, the embedded version of the gateway does not support these features: ■ Dynamic HTML caching ■ System monitoring ■ Authentication modes other than Basic For information about authentication modes, see Oracle HTTP Server mod_plsql User's Guide. Using Embedded PL/SQL Gateway: Scenario This section illustrates how to write a simple application that queries the hr.employees table and delivers HTML output to a web browser through the PL/SQL gateway. It assumes that you have both XML DB and the sample schemas installed. To write and run the program follow these steps: 1. Log on to the database as a user with ALTER USER privileges and ensure that the database account ANONYMOUS is unlocked. The ANONYMOUS account, which is locked by default, is required for static authentication. If the account is locked, then use this SQL statement to unlock it: ALTER USER anonymous ACCOUNT UNLOCK; 2. Log on to the database as an XML DB administrator, that is, a user with the XDBADMIN role. To determine which users and roles were granted the XDADMIN role, query the data dictionary: SELECT * FROM DBA_ROLE_PRIVS WHERE GRANTED_ROLE = 'XDBADMIN'; 3. Create the DAD. For example, this procedure creates a DAD invoked HR_DAD and maps the virtual path to /plsql/: EXEC DBMS_EPG.CREATE_DAD('HR_DAD', '/plsql/*'); 4. Set the DAD attribute database-username to the database user whose privileges must be used by the DAD. For example, this procedure specifies that the DAD HR_ DAD accesses database objects with the privileges of user HR: EXEC DBMS_EPG.SET_DAD_ATTRIBUTE('HR_DAD', 'database-username', 'HR'); The attribute database-username is case-sensitive. 5. Grant EXECUTE privilege to the database user whose privileges must be used by the DAD (so that he or she can authorize the DAD). For example: GRANT EXECUTE ON DBMS_EPG TO HR; 6. Log off as the XML DB administrator and log on to the database as the database user whose privileges must be used by the DAD (for example, HR). 7. Authorize the embedded PL/SQL gateway to invoke procedures and access document tables through the DAD. For example: 9-18 Oracle Database Advanced Application Developer's Guide Using Embedded PL/SQL Gateway EXEC DBMS_EPG.AUTHORIZE_DAD('HR_DAD'); 8. Create a sample PL/SQL stored procedure invoked print_employees. This program creates an HTML page that includes the result set of a query of hr.employees: CREATE OR REPLACE PROCEDURE print_employees IS CURSOR emp_cursor IS SELECT last_name, first_name FROM hr.employees ORDER BY last_name; BEGIN HTP.PRINT(''); HTP.PRINT(''); HTP.PRINT(''); HTP.PRINT(' List of Employees '); HTP.PRINT(''); HTP.PRINT(''); HTP.PRINT('List of Employees
'); HTP.PRINT(''); HTP.PRINT('
'); HTP.PRINT(''); HTP.PRINT(''); END; / 9. Ensure that the Oracle Net listener can accept HTTP requests. You can determine the status of the listener on Linux and UNIX by running this command at the system prompt: lsnrctl status | grep HTTP Output (reformatted from a single line to multiple lines from page size constraints): (DESCRIPTION= (ADDRESS=(PROTOCOL=tcp)(HOST=example.com)(PORT=8080)) (Presentation=HTTP) (Session=RAW) ) If you do not see the HTTP service started, then you can add these lines to your initialization parameter file (replacing listener_name with the name of your Oracle Net local listener), then restart the database and the listener: dispatchers="(PROTOCOL=TCP)" local_listener=listener_name 10. Run the print_employees program from your web browser. For example, you can use this URL, replacing host with the name of your host computer and port with the value of the PORT parameter in the previous step: Developing PL/SQL Web Applications 9-19 Generating HTML Output with PL/SQL http://host:port/plsql/print_employees For example, if your host is test.com and your HTTP port is 8080, then enter: http://example.com:8080/plsql/print_employees The web browser returns an HTML page with a table that includes the first and last name of every employee in the hr.employees table. Generating HTML Output with PL/SQL Traditionally, PL/SQL web applications use function calls to generate each HTML tag for output. These functions are part of the PL/SQL Web Toolkit packages that come with Oracle Database. Example 9–7 shows how to generate a simple HTML page by calling the HTP functions that correspond to each HTML tag. Example 9–7 Using HTP Functions to Generate HTML Tags CREATE OR REPLACE PROCEDURE html_page IS BEGIN HTP.HTMLOPEN; HTP.HEADOPEN; HTP.TITLE('Title'); HTP.HEADCLOSE; ----- generates generates generates generates'); HTP.PRINT(' '); FOR emp_record IN emp_cursor LOOP HTP.PRINT('Last Name '); HTP.PRINT('First Name '); HTP.PRINT(''); HTP.PRINT(' ' || emp_record.last_name || ' '); HTP.PRINT('' || emp_record.first_name || ' '); END LOOP; HTP.PRINT('Hello -- generates HTP.BODYOPEN( cattributes => 'TEXT="#000000" BGCOLOR="#FFFFFF"'); -- generatesHeading in the HTML File
HTP.HEADER(1, 'Heading in the HTML File'); HTP.PARA; -- generatesHTP.PRINT('Some text in the HTML file.'); HTP.BODYCLOSE; -- generates HTP.HTMLCLOSE; -- generates END; / An alternative to making function calls that correspond to each tag is to use the HTP.PRINT function to print both text and tags. Example 9–8 illustrates this technique. Example 9–8 Using HTP.PRINT to Generate HTML Tags CREATE OR REPLACE PROCEDURE html_page2 IS BEGIN HTP.PRINT(''); HTP.PRINT('
'); HTP.PRINT(''); HTP.PRINT('Title of the HTML File '); HTP.PRINT(''); HTP.PRINT(''); HTP.PRINT('Heading in the HTML File
'); HTP.PRINT('Some text in the HTML file.'); HTP.PRINT(''); HTP.PRINT(''); END; / 9-20 Oracle Database Advanced Application Developer's Guide Passing Parameters to PL/SQL Web Applications Chapter 10, "Developing PL/SQL Server Pages (PSP)," describes an additional method for delivering using PL/SQL to generate HTML content. PL/SQL server pages enables you to build on your knowledge of HTML tags and avoid learning a new set of function calls. In an application written as a set of PL/SQL server pages, you can still use functions from the PL/SQL Web Toolkit to: ■ Simplify the processing involved in displaying tables ■ Store persistent data (cookies) ■ Work with CGI protocol internals Passing Parameters to PL/SQL Web Applications To be useful in a wide variety of situations, a web application must be interactive enough to allow user choices. To keep the attention of impatient web surfers, streamline the interaction so that users can specify these choices very simply, without excessive decision-making or data entry. The main methods of passing parameters to PL/SQL web applications are: ■ ■ Using HTML form tags. The user fills in a form on one web page, and all the data and choices are transmitted to a stored subprogram when the user clicks the Submit button on the page. Hard-coded in the URL. The user clicks on a link, and a set of predefined parameters are transmitted to a stored subprogram. Typically, you include separate links on your web page for all the choices that the user might want. Topics: ■ Passing List and Dropdown-List Parameters from an HTML Form ■ Passing Option and Check Box Parameters from an HTML Form ■ Passing Entry-Field Parameters from an HTML Form ■ Passing Hidden Parameters from an HTML Form ■ Uploading a File from an HTML Form ■ Submitting a Completed HTML Form ■ Handling Missing Input from an HTML Form ■ Maintaining State Information Between Web Pages Passing List and Dropdown-List Parameters from an HTML Form List boxes and drop-down lists are implemented with the HTML tag
Source Exif Data:
File Type : PDF File Type Extension : pdf MIME Type : application/pdf PDF Version : 1.6 Linearized : Yes Language : en XMP Toolkit : Adobe XMP Core 5.2-c001 63.139439, 2010/10/03-12:08:50 Creator Tool : FrameMaker 10.0.2 Modify Date : 2014:12:06 01:55:52-08:00 Create Date : 2014:12:06 01:50:09Z Metadata Date : 2014:12:06 01:55:52-08:00 Format : application/pdf Title : Oracle Database Advanced Application Developer’s Guide Creator : Oracle Corporation Description : Oracle Database Marked : True Producer : Acrobat Elements 9.0.0 (Windows) Document ID : uuid:a8cde759-3c04-4a55-8d75-e495c7d2d302 Instance ID : uuid:3eeb59fa-6b01-4c65-8ca6-c7113c78625c Page Mode : UseOutlines Page Count : 576 Author : Oracle Corporation Subject : Oracle DatabaseEXIF Metadata provided by EXIF.tools