Oracle® Database

JDBC Developer’s Guide and Reference, 11g Release 1 (11.1)
B31224-04

July 2008 This book describes how to use Oracle JDBC drivers to develop powerful Java database applications.

Oracle Database JDBC Developer's Guide and Reference, 11g Release 1 (11.1) B31224-04 Copyright © 1999, 2008, Oracle. All rights reserved. Primary Author: Pfaeffle Tulika Das, Venkatasubramaniam Iyer, Elizabeth Hanes Perry, Brian Wright, Thomas Brian Martin

Contributing Author:

Contributor: Kuassi Mensah, Douglas Surber, Paul Lo, Ed Shirk, Tong Zhou, Jean de Lavarene, Rajkumar Irudayaraj, Ashok Shivarudraiah, Angela Barone, Rosie Chen, Sunil Kunisetty, Joyce Yang, Mehul Bastawala, Luxi Chidambaran, Srinath Krishnaswamy, Longxing Deng, Magdi Morsi, Ron Peterson, Ekkehard Rohwedder, Catherine Wong, Scott Urman, Jerry Schwarz, Steve Ding, Soulaiman Htite, Anthony Lai, Prabha Krishna, Ellen Siegal, Susan Kraft, Sheryl Maring The Programs (which include both the software and documentation) contain proprietary information; they are provided under a license agreement containing restrictions on use and disclosure and are also protected by copyright, patent, and other intellectual and industrial property laws. Reverse engineering, disassembly, or decompilation of the Programs, except to the extent required to obtain interoperability with other independently created software or as specified by law, is prohibited. The information contained in this document is subject to change without notice. If you find any problems in the documentation, please report them to us in writing. This document is not warranted to be error-free. Except as may be expressly permitted in your license agreement for these Programs, no part of these Programs may be reproduced or transmitted in any form or by any means, electronic or mechanical, for any purpose. If the Programs are delivered to the United States Government or anyone licensing or using the Programs on behalf of the United States Government, the following notice is applicable: U.S. GOVERNMENT RIGHTS Programs, software, databases, and related documentation and technical data delivered to U.S. Government customers are "commercial computer software" or "commercial technical data" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations. As such, use, duplication, disclosure, modification, and adaptation of the Programs, including documentation and technical data, shall be subject to the licensing restrictions set forth in the applicable Oracle license agreement, and, to the extent applicable, the additional rights set forth in FAR 52.227-19, Commercial Computer Software--Restricted Rights (June 1987). Oracle USA, Inc., 500 Oracle Parkway, Redwood City, CA 94065. The Programs are not intended for use in any nuclear, aviation, mass transit, medical, or other inherently dangerous applications. It shall be the licensee's responsibility to take all appropriate fail-safe, backup, redundancy and other measures to ensure the safe use of such applications if the Programs are used for such purposes, and we disclaim liability for any damages caused by such use of the Programs. Oracle, JD Edwards, PeopleSoft, and Siebel are registered trademarks of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. The Programs may provide links to Web sites and access to content, products, and services from third parties. Oracle is not responsible for the availability of, or any content provided on, third-party Web sites. You bear all risks associated with the use of such content. If you choose to purchase any products or services from a third party, the relationship is directly between you and the third party. Oracle is not responsible for: (a) the quality of third-party products or services; or (b) fulfilling any of the terms of the agreement with the third party, including delivery of products or services and warranty obligations related to purchased products or services. Oracle is not responsible for any loss or damage of any sort that you may incur from dealing with any third party.

Contents
Preface ............................................................................................................................................................... xix
Audience..................................................................................................................................................... xix Documentation Accessibility ................................................................................................................... xix Related Documents ................................................................................................................................... xx Conventions .............................................................................................................................................. xxii

What’s New.................................................................................................................................................... xxiii
New Features for Release 1 (11.1) ......................................................................................................... Desupported Features ............................................................................................................................ Interface Changes .................................................................................................................................... xxiii xxiv xxiv

Part I 1

Overview

Introducing JDBC
Overview of Oracle JDBC Drivers ........................................................................................................ Common Features of Oracle JDBC Drivers .................................................................................... Choosing the Appropriate Driver.................................................................................................... Feature Differences Between JDBC OCI and Thin Drivers.......................................................... Environments and Support .................................................................................................................... Supported JDK and JDBC Versions................................................................................................. JNI and Java Environments .............................................................................................................. JDBC and IDEs.................................................................................................................................... Feature List ................................................................................................................................................ 1-1 1-2 1-4 1-4 1-4 1-5 1-5 1-5 1-5

2

Getting Started
Version Compatibility for Oracle JDBC Drivers................................................................................ Verification of a JDBC Client Installation........................................................................................... Check the Installed Directories and Files ....................................................................................... Check the Environment Variables ................................................................................................... Ensure that the Java Code Can Be Compiled and Run ................................................................ Determine the Version of the JDBC Driver .................................................................................... Test JDBC and the Database Connection........................................................................................ Basic Steps in JDBC ................................................................................................................................. Importing Packages ........................................................................................................................... 2-1 2-2 2-2 2-3 2-4 2-5 2-5 2-7 2-8

iii

Opening a Connection to a Database .............................................................................................. 2-8 Creating a Statement Object ............................................................................................................. 2-9 Running a Query and Retrieving a Result Set Object................................................................... 2-9 Processing the Result Set Object ................................................................................................... 2-10 Closing the Result Set and Statement Objects............................................................................. 2-10 Making Changes to the Database ................................................................................................. 2-11 Committing Changes...................................................................................................................... 2-13 Closing the Connection .................................................................................................................. 2-13 Sample: Connecting, Querying, and Processing the Results........................................................ 2-13 Stored Procedure Calls in JDBC Programs....................................................................................... 2-14 PL/SQL Stored Procedures ........................................................................................................... 2-15 Java Stored Procedures................................................................................................................... 2-15 Processing SQL Exceptions ................................................................................................................. 2-15

Part II 3

Oracle JDBC

JDBC Standards Support
Support for JDBC 2.0 Standard.............................................................................................................. Data Type Support ............................................................................................................................. Standard Feature Support................................................................................................................. Extended Feature Support ................................................................................................................ Standard versus Oracle Performance Enhancement APIs ........................................................... Support for JDBC 3.0 Standard.............................................................................................................. Transaction Savepoints...................................................................................................................... Creating a Savepoint .................................................................................................................. Rolling Back to a Savepoint ....................................................................................................... Releasing a Savepoint................................................................................................................. Checking Savepoint Support..................................................................................................... Savepoint Notes .......................................................................................................................... Retrieval of Auto-Generated Keys................................................................................................... java.sql.Statement ....................................................................................................................... Sample Code ................................................................................................................................ Limitations ................................................................................................................................... JDBC 3.0 LOB Interface Methods..................................................................................................... Result Set Holdability........................................................................................................................ Support for JDBC 4.0 Standard.............................................................................................................. 3-1 3-2 3-2 3-2 3-2 3-2 3-3 3-3 3-3 3-4 3-4 3-4 3-4 3-4 3-5 3-5 3-5 3-6 3-6

4

Oracle Extensions
Overview of Oracle Extensions ............................................................................................................. Features of the Oracle Extensions ........................................................................................................ Database Management Using JDBC................................................................................................ Support for Oracle Data Types......................................................................................................... Support for Oracle Objects................................................................................................................ Support for Schema Naming ............................................................................................................ DML Returning .................................................................................................................................. Accessing PL/SQL Index-by Tables................................................................................................ 4-1 4-2 4-2 4-2 4-3 4-4 4-4 4-5

iv

Oracle JDBC Packages............................................................................................................................. 4-5 Package oracle.sql .............................................................................................................................. 4-5 Package oracle.jdbc ......................................................................................................................... 4-10 Oracle Character Data Types Support ............................................................................................... 4-10 SQL CHAR Data Types .................................................................................................................. 4-10 SQL NCHAR Data Types............................................................................................................... 4-10 Class oracle.sql.CHAR.................................................................................................................... 4-11 Additional Oracle Type Extensions ................................................................................................... 4-13 Oracle ROWID Type....................................................................................................................... 4-13 Oracle REF CURSOR Type Category ........................................................................................... 4-14 Oracle BINARY_FLOAT and BINARY_DOUBLE Types ......................................................... 4-16 Oracle SYS.ANYTYPE and SYS.ANYDATA Types ................................................................... 4-16 The oracle.jdbc Package ................................................................................................................. 4-19 Interface oracle.jdbc.OracleConnection ................................................................................ 4-21 Interface oracle.jdbc.OracleStatement................................................................................... 4-22 Interface oracle.jdbc.OraclePreparedStatement .................................................................. 4-22 Interface oracle.jdbc.OracleCallableStatement .................................................................... 4-22 Interface oracle.jdbc.OracleResultSet .................................................................................... 4-23 Interface oracle.jdbc.OracleResultSetMetaData................................................................... 4-23 Class oracle.jdbc.OracleTypes................................................................................................ 4-23 Method getJavaSqlConnection............................................................................................... 4-25 DML Returning ..................................................................................................................................... 4-26 Oracle-Specific APIs........................................................................................................................ 4-26 Running DML Returning Statements........................................................................................... 4-27 Example of DML Returning .......................................................................................................... 4-27 Limitations of DML Returning...................................................................................................... 4-28 Accessing PL/SQL Index-by Tables ................................................................................................... 4-28 Overview .......................................................................................................................................... 4-29 Binding IN Parameters ................................................................................................................... 4-29 Receiving OUT Parameters............................................................................................................ 4-31 Type Mappings................................................................................................................................ 4-32

5

Features Specific to JDBC Thin
Overview of JDBC Thin Client ............................................................................................................. Additional Features Supported ............................................................................................................. Support for Applets ........................................................................................................................... Default Support for Native XA ........................................................................................................ JDBC in Applets ....................................................................................................................................... Connecting to the Database Through the Applet.......................................................................... Connecting to a Database on a Different Host Than the Web Server ........................................ Using the Oracle Connection Manager.................................................................................... Using Signed Applets................................................................................................................. Using Applets with Firewalls........................................................................................................... Configuring a Firewall for Applets that use the JDBC Thin Driver .................................... Writing a URL to Connect Through a Firewall ...................................................................... Packaging Applets ............................................................................................................................. Specifying an Applet in an HTML Page ......................................................................................... 5-1 5-1 5-2 5-2 5-2 5-2 5-3 5-4 5-5 5-6 5-6 5-7 5-8 5-8

v

CODE, HEIGHT, and WIDTH .................................................................................................. 5-8 CODEBASE.................................................................................................................................. 5-9 ARCHIVE..................................................................................................................................... 5-9

6

Features Specific to JDBC OCI Driver
OCI Connection Pooling......................................................................................................................... 6-1 Client Result Cache.................................................................................................................................. 6-1 Usage Guidelines in JDBC ................................................................................................................ 6-1 Validation of the Client Result Cache ............................................................................................. 6-2 Client Cache Statistics Verification........................................................................................... 6-2 Timing Measurement ................................................................................................................. 6-2 Transparent Application Failover ......................................................................................................... 6-2 OCI Native XA .......................................................................................................................................... 6-2 OCI Instant Client.................................................................................................................................... 6-3 Overview of Instant Client................................................................................................................ 6-3 Benefits of Instant Client ................................................................................................................... 6-3 JDBC OCI Instant Client Installation Process ................................................................................ 6-4 Usage of Instant Client ...................................................................................................................... 6-5 Patching Instant Client Shared Libraries ........................................................................................ 6-5 Regeneration of Data Shared Library and ZIP files ...................................................................... 6-6 Database Connection Names for OCI Instant Client .................................................................... 6-6 Environment Variables for OCI Instant Client .............................................................................. 6-8 Instant Client Light (English) ................................................................................................................ 6-9 Globalization Settings..................................................................................................................... 6-10 Operation.......................................................................................................................................... 6-10 Installation........................................................................................................................................ 6-11

7

Server-Side Internal Driver
Overview of the Server-Side Internal Driver ..................................................................................... Connecting to the Database.................................................................................................................... Exception-Handling Extensions ............................................................................................................ Session and Transaction Context........................................................................................................... Testing JDBC on the Server .................................................................................................................... Loading an Application into the Server............................................................................................... 7-1 7-1 7-3 7-4 7-4 7-5

Part III 8

Connection and Security

Data Sources and URLs
Data Sources .............................................................................................................................................. Overview of Oracle Data Source Support for JNDI ...................................................................... Features and Properties of Data Sources ........................................................................................ Creating a Data Source Instance and Connecting ......................................................................... Creating a Data Source Instance, Registering with JNDI, and Connecting............................... Supported Connection Properties ................................................................................................... Using Roles for SYS Login ................................................................................................................ Configuring Database Remote Login.............................................................................................. 8-1 8-1 8-2 8-6 8-6 8-8 8-8 8-8

vi

Bequeath Connection and SYS Logon............................................................................................. 8-9 Properties for Oracle Performance Extensions ........................................................................... 8-10 Database URLs and Database Specifiers.......................................................................................... 8-11

9

JDBC Client-Side Security Features
Support for Oracle Advanced Security ................................................................................................ 9-1 Support for Login Authentication ........................................................................................................ 9-3 Support for Strong Authentication....................................................................................................... 9-3 Support for OS Authentication ............................................................................................................. 9-4 Configuration Steps for Linux.......................................................................................................... 9-4 Configuration Steps for Windows ................................................................................................... 9-5 JDBC Code Using OS Authentication ............................................................................................. 9-6 Support for Data Encryption and Integrity......................................................................................... 9-6 JDBC OCI Driver Support for Encryption and Integrity.............................................................. 9-7 JDBC Thin Driver Support for Encryption and Integrity............................................................. 9-8 Setting Encryption and Integrity Parameters in Java ................................................................... 9-9 Support for SSL ..................................................................................................................................... 9-11 Managing Certificates and Wallets............................................................................................... 9-12 Keys and certificates containers .................................................................................................... 9-12 Support for Kerberos ............................................................................................................................ 9-13 Configuring Oracle Database to Use Kerberos ........................................................................... 9-13 Code Example.................................................................................................................................. 9-14 Support for RADIUS ............................................................................................................................ 9-18 Configuring Oracle Database to Use RADIUS ........................................................................... 9-18 Code Example.................................................................................................................................. 9-19 Secure External Password Store ......................................................................................................... 9-21

10

Proxy Authentication
About Proxy Authentication ............................................................................................................... Types of Proxy Connections ................................................................................................................ Creating Proxy Connections................................................................................................................ Closing a Proxy Session ....................................................................................................................... Caching Proxy Connections ................................................................................................................ 10-1 10-2 10-3 10-4 10-5

Part IV 11

Data Access and Manipulation

Accessing and Manipulating Oracle Data
Data Type Mappings............................................................................................................................. Table of Mappings .......................................................................................................................... Notes Regarding Mappings........................................................................................................... Data Conversion Considerations ....................................................................................................... Standard Types Versus Oracle Types .......................................................................................... Converting SQL NULL Data ......................................................................................................... Testing for NULLs .......................................................................................................................... Result Set and Statement Extensions ................................................................................................ Comparison of Oracle get and set Methods to Standard JDBC ................................................... 11-1 11-1 11-3 11-3 11-4 11-4 11-4 11-5 11-5

vii

Standard getObject Method........................................................................................................... Oracle getOracleObject Method.................................................................................................... Summary of getObject and getOracleObject Return Types ...................................................... Other getXXX Methods .................................................................................................................. Return Types of getXXX Methods ......................................................................................... Special Notes about getXXX Methods ................................................................................ Data Types For Returned Objects from getObject and getXXX ............................................. The setObject and setOracleObject Methods............................................................................. Other setXXX Methods................................................................................................................. Input Data Binding ................................................................................................................ Method setFixedCHAR for Binding CHAR Data into WHERE Clauses....................... Using Result Set Metadata Extensions............................................................................................ Using SQL CALL and CALL INTO Statements ............................................................................

11-6 11-6 11-7 11-9 11-9 11-10 11-10 11-11 11-11 11-12 11-13 11-14 11-15

12

Java Streams in JDBC
Overview of Java Streams.................................................................................................................... Streaming LONG or LONG RAW Columns .................................................................................... LONG RAW Data Conversions .................................................................................................... LONG Data Conversions ............................................................................................................... Streaming Example for LONG RAW Data.................................................................................. Avoiding Streaming for LONG or LONG RAW ........................................................................ Streaming CHAR, VARCHAR, or RAW Columns .......................................................................... Streaming LOBs and External Files ................................................................................................... Data Streaming and Multiple Columns............................................................................................ Closing a Stream.................................................................................................................................... Notes and Precautions on Streams..................................................................................................... Streaming Data Precautions .......................................................................................................... Using Streams to Avoid Limits on setBytes and setString........................................................ Streaming and Row Prefetching ................................................................................................... 12-1 12-2 12-2 12-2 12-3 12-5 12-5 12-6 12-7 12-8 12-8 12-8 12-9 12-9

13

Working with Oracle Object Types
Mapping Oracle Objects ...................................................................................................................... Using the Default STRUCT Class for Oracle Objects ................................................................... STRUCT Class Functionality ......................................................................................................... Retrieving STRUCT Objects and Attributes................................................................................ Creating STRUCT Objects and Descriptors................................................................................. Binding STRUCT Objects into Statements................................................................................... STRUCT Automatic Attribute Buffering ..................................................................................... Creating and Using Custom Object Classes for Oracle Objects .................................................. Relative Advantages of ORAData versus SQLData................................................................... Understanding Type Maps for SQLData Implementations...................................................... Creating Type Map and Defining Mappings for a SQLData Implementation ...................... Adding Entries to an Existing Type Map ............................................................................. Creating a New Type Map ................................................................................................... Materializing Object Types not Specified in the Type Map ............................................ Understanding the SQLData Interface....................................................................................... Reading and Writing Data with a SQLData Implementation ................................................ 13-1 13-2 13-2 13-3 13-5 13-6 13-6 13-6 13-7 13-8 13-8 13-9 13-10 13-10 13-10 13-12

viii

Understanding the ORAData Interface ..................................................................................... Reading and Writing Data with a ORAData Implementation ............................................... Additional Uses for ORAData..................................................................................................... The Deprecated CustomDatum Interface.................................................................................. Object-Type Inheritance .................................................................................................................... Creating Subtypes ......................................................................................................................... Implementing Customized Classes for Subtypes..................................................................... Use of ORAData for Type Inheritance Hierarchy ............................................................. Use of SQLData for Type Inheritance Hierarchy .............................................................. JPublisher Utility.................................................................................................................... Retrieving Subtype Objects.......................................................................................................... Creating Subtype Objects............................................................................................................. Sending Subtype Objects.............................................................................................................. Accessing Subtype Data Fields ................................................................................................... Inheritance Metadata Methods ................................................................................................... Using JPublisher to Create Custom Object Classes ..................................................................... JPublisher Functionality ............................................................................................................... JPublisher Type Mappings .......................................................................................................... Describing an Object Type ................................................................................................................ Functionality for Getting Object Metadata................................................................................ Steps for Retrieving Object Metadata.........................................................................................

13-14 13-16 13-18 13-19 13-19 13-20 13-20 13-21 13-23 13-25 13-26 13-28 13-28 13-29 13-30 13-30 13-30 13-31 13-33 13-33 13-34

14

Working with LOBs and BFILEs
Oracle Extensions for LOBs and BFILEs........................................................................................... Working with BLOBs, CLOBs and NCLOBs ................................................................................... Getting and Passing BLOB, CLOB, and NCLOB Locators........................................................ Retrieving BLOB, CLOB, and NCLOB Locators ................................................................. Passing BLOB, CLOB and NCLOB Locators ....................................................................... Reading and Writing BLOB, CLOB and NCLOB Data.............................................................. Creating and Populating a BLOB, CLOB or NCLOB Column ................................................. Accessing and Manipulating BLOB, CLOB, or NCLOB Data ................................................ Data Interface for LOBs ..................................................................................................................... Working With Temporary LOBs ....................................................................................................... Using Open and Close With LOBs .................................................................................................. Working with BFILEs ......................................................................................................................... Getting and Passing BFILE Locators .......................................................................................... Reading BFILE Data...................................................................................................................... Creating and Populating a BFILE Column................................................................................ Accessing and Manipulating BFILE Data.................................................................................. Oracle SecureFiles ............................................................................................................................... 14-1 14-2 14-2 14-2 14-4 14-5 14-8 14-10 14-10 14-13 14-14 14-14 14-15 14-16 14-17 14-18 14-19

15

Using Oracle Object References
Oracle Extensions for Object References.......................................................................................... Overview of Object Reference Functionality .................................................................................. Object Reference Getter and Setter Methods .............................................................................. Key REF Class Methods ................................................................................................................. 15-1 15-2 15-2 15-2

ix

Retrieving and Passing an Object Reference................................................................................... Retrieving an Object Reference from a Result Set ...................................................................... Retrieving an Object Reference from a Callable Statement ...................................................... Passing an Object Reference to a Prepared Statement............................................................... Accessing and Updating Object Values Through an Object Reference ..................................... Custom Reference Classes with JPublisher .....................................................................................

15-3 15-3 15-4 15-4 15-5 15-5

16

Working with Oracle Collections
Oracle Extensions for Collections ...................................................................................................... Choices in Materializing Collections............................................................................................ Creating Collections........................................................................................................................ Creating Multilevel Collection Types .......................................................................................... Overview of Collection Functionality............................................................................................... ARRAY Performance Extension Methods ........................................................................................ Accessing oracle.sql.ARRAY Elements as Arrays of Java Primitive Types............................ ARRAY Automatic Element Buffering ........................................................................................ ARRAY Automatic Indexing......................................................................................................... Creating and Using Arrays .................................................................................................................. Creating ARRAY Objects ............................................................................................................... Retrieving an Array and Its Elements .......................................................................................... Retrieving the Array ............................................................................................................... Data Retrieval Methods .......................................................................................................... Comparing the Data Retrieval Methods............................................................................... Retrieving Elements of a Structured Object Array According to a Type Map ............... Retrieving a Subset of Array Elements ................................................................................. Retrieving Array Elements into an oracle.sql.Datum Array ............................................. Accessing Multilevel Collection Elements ......................................................................... Passing Arrays to Statement Objects.......................................................................................... Using a Type Map to Map Array Elements .................................................................................... Custom Collection Classes with JPublisher .................................................................................. 16-1 16-1 16-2 16-3 16-3 16-3 16-4 16-4 16-4 16-5 16-5 16-6 16-6 16-6 16-7 16-8 16-8 16-9 16-10 16-11 16-12 16-13

17

Result Set
Overview of JDBC 2.0 Result Set ....................................................................................................... Result Set Functionality and Result Set Categories Supported in JDBC 2.0........................... Oracle JDBC Implementation Overview for Result Set Enhancements .................................. Creating Scrollable or Updatable Result Sets ................................................................................. Specifying Result Set Scrollability and Updatability ................................................................. Result Set Limitations and Downgrade Rules ............................................................................ Positioning and Processing in Scrollable Result Sets.................................................................... Positioning in a Scrollable Result Set ........................................................................................... Processing a Scrollable Result Set ............................................................................................... Updating Result Sets .......................................................................................................................... Performing a DELETE Operation in a Result Set ..................................................................... Performing an UPDATE Operation in a Result Set ................................................................. Performing an INSERT Operation in a Result Set.................................................................... Avoiding Update Conflicts.......................................................................................................... Fetch Size .............................................................................................................................................. 17-1 17-1 17-3 17-5 17-5 17-6 17-8 17-8 17-10 17-11 17-11 17-12 17-13 17-14 17-15

x

...................................................................................................................................................................................... Seeing External Changes ...................... JoinRowSet ................... Closing a Cached Statement ..................... WebRowSet.............................................................5 ....................................................................................................................................................6 .......................................................................... 17-15 17-16 17-16 17-17 17-17 17-18 17-18 17-19 18 JDBC RowSets Overview of JDBC RowSets.. FilteredRowSet .......................................................................................................................................................................................................... Oracle Implementation of Scroll-Sensitive Result Sets.............................................................................................................................. Reusing Statements Objects............................................................................................ Seeing Internal Changes............................................................................................................................................................ 19-4 Part V 20 Performance and Scalability Statement and Result Set Caching About Statement Caching..................................... Summary of Visibility of Internal and External Changes ........................................................................................... CachedRowSet .......................... NVARCHAR2............................................................... Refetching Rows.......................................................................................... Explicit Statement Caching.................................................................................................................................. Client Result Cache ........................................................................... Using a Pooled Statement ........Setting the Fetch Size ................................ 19-1 NCHAR.......... Seeing Database Changes Made Internally and Externally.... Visibility versus Detection of External Changes .................................................................................................................................... Server-side Cache ............................................................................................................................................. 20-1 20-2 20-2 20-3 20-3 20-4 20-5 20-5 20-7 20-8 20-8 20-9 20-9 20-10 20-10 xi ............................................................................................. Using Statement Caching ........................................................................................ Traversing RowSets ........................................................................................................................................................ Command Parameters and Command Execution.................................... Closing a Pooled Statement ............................................................................................. Implicit Statement Caching ....... Events and Event Listeners............................................................................................................... 19-3 New Methods for National Character Set Type Data in JDK 1.................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... 18-1 18-2 18-3 18-4 18-4 18-6 18-9 18-10 18-12 18-13 19 Globalization Support Providing Globalization Support ......................................... Using Implicit Statement Caching .......................................................................................................................................... JdbcRowSet ................................................................................................ Result Set Caching .................................................................................................................................................................................................................... Using Explicit Statement Caching ............... Basics of Statement Caching ..................................................... Enabling and Disabling Statement Caching. RowSet Properties ..................................... NCLOB and the defaultNChar Property in JDK 1.......................................................................................................................

............................................................................................................................. Attribute Weights and Connection Matching..................... Committing the Changes in Oracle Batching ............................................................................................. Connection Cache Manager API .......... 22-2 23 Performance Extensions Update Batching ......................... Other Properties ........................................................................................................................................ Turning Caching On ................................................................................. Setting the Connection Batch Value .............................................................................................................................................................................................................................................. Connection Property Example ............................................................................................................................................. Getting Connections ..........................................21 Implicit Connection Caching The Implicit Connection Cache ....................................... Closing a Connection................................... Processing the Batch ......................................... Adding Operations to the Batch ...................................................................................................................... Error Reporting in Oracle Update Batching................. Setting Connection Cache Name .................................................................................................................................................................................................... Connection Attribute Example ................................................................................................................................. 21-2 21-3 21-3 21-4 21-4 21-5 21-5 21-5 21-6 21-7 21-7 21-8 21-8 21-8 21-9 21-10 21-11 21-11 21-12 21-13 21-13 21-13 21-14 22 Run-Time Connection Load Balancing Overview of Run-Time Connection Load Balancing ................................................................... Checking Attributes of a Returned Connection .............................................................. Oracle Update Batching ......................................... Use Cases for TimeToLiveTimeout and AbandonedConnectionTimeout ................................................................................................................................................ Using the Connection Cache ..................................................................................................................................................................................................................................................................... Connection Attributes .......................................................................... Oracle Update Batching Characteristics and Limitations .............................................. Setting the Statement Batch Value........................................................................................................................................................................................................................................................................................................................ Update Counts in Oracle Batching .............................................................................. Implicit Connection Cache Example ....................... Setting Connection Attributes .................... Committing the Changes in the Oracle Implementation of Standard Batching................ Setting Connection Cache Properties ................................................... Limitations in the Oracle Implementation of Standard Batching............................................................................................ 22-1 Enabling Run-Time Connection Load Balancing .................................................................................................................................................... Connection Cache Callbacks ......... TIMEOUT Properties....................................................................................................................................................................................................................................................................... Connection Cache Properties ......... Standard Update Batching..................................................... 23-1 23-2 23-3 23-3 23-4 23-4 23-5 23-5 23-6 23-6 23-8 23-8 23-8 23-9 23-10 23-10 xii .................................................................................................... Overriding the Batch Value ............................................................................................................................ Opening a Connection.............................................................................................................................. Advanced Topics...................................... Checking the Batch Value. Overview of Update Batching Models.......................................................... Limit Properties ................................................................................................................................................................................

......................................................................................................... How It Works .............................. 25-1 25-2 25-10 25-12 25-13 25-15 Part VI 26 High Availability Fast Connection Failover Overview of Fast Connection Failover........... Oracle Row-Prefetching Limitations ..... Client-Side ONS Configuration ................................................................................................................................................................ Querying Fast Connection Failover Status.................................. Dequeuing Messages..... Creating Messages.................... 24-1 24-2 24-2 24-6 24-7 24-9 24-10 25 Oracle Advanced Queuing Functionality and Framework of Oracle Advanced Queuing ............................................................................................................................ Examples: Enqueuing and Dequeuing............................... DatabaseMetaData TABLE_REMARKS Reporting.................................Clearing the Batch................................................................................................. Sample Code for OCI Connection Pooling ....................................................................................................................................... Using Fast Connection Failover................................................................................ Defining an OCI Connection Pool............................................................................................................................................................................................................................................................................... Fast Connection Failover Prerequisites.................................................................................................................................................................................................................................................................................................................................................................................................................................................................... Defining Column Types ......................................................................................................................................... ONS Configuration File ......................................... Enabling Fast Connection Failover...................................................................... Enqueuing Messages .......... What the Application Sees....................................................................................... Statement Handling and Caching.................................................................................. JNDI and the OCI Connection Pool ................................................................................................ Understanding Fast Connection Failover ............................... AQ Asynchronous Event Notification ............................... Configuring ONS for Fast Connection Failover ................................................... Error Handling in the Oracle Implementation of Standard Batching........................................................... Remote ONS Subscription ............................. 23-10 23-11 23-12 23-13 23-14 23-15 23-15 23-16 23-19 24 OCI Connection Pooling OCI Driver Connection Pooling: Background.................................................................................................................................. Premature Batch Flush .......................................... Connecting to an OCI Connection Pool............................................... Additional Oracle Performance Extensions .................. Server-Side ONS Configuration Using racgons . OCI Driver Connection Pooling and Shared Servers Compared ............................................................................................. 26-1 26-2 26-2 26-2 26-2 26-4 26-4 26-5 26-6 26-7 26-7 26-7 26-7 26-8 xiii ............................................................................................................................................................................ Update Counts in the Oracle Implementation of Standard Batching ...................................................................................................................... Comparison of Fast Connection Failover and TAF................................ Intermixing Batched Statements and Nonbatched Statements ..................................................................................................................................................................................................................................

................ OCI Native XA......................................................................................................................... Using Loggers......................................................................................................................................................................................................................................................................................................... Configuring the CLASSPATH Environment Variable .................................................... Oracle XA Code Sample.................................................................................................................................................................................................................. Native-XA in Oracle JDBC Drivers......................................... Oracle XA Optimizations ................. Distributed Transaction Concepts .......................................................................................... XAException Classes and Methods. Xid Interface and Oracle Implementation .................................................................. Distributed Transaction Components and Scenarios .................................... Thin Native XA............................................................................................................................... XA Error Handling.......... Error Handling and Optimizations........................................................................... 29-4 30 Diagnosability in JDBC Logging........................................................................................................................................................ Oracle XA Packages ......... Mapping Between Oracle Errors and XA Errors .......................................................................................................................... Java TAF Callback Interface ...................................................................................................................... Switching Between Global and Local Transactions ....................................................................... 28-1 28-2 28-2 28-4 28-5 28-5 28-6 28-6 28-7 28-8 28-12 28-13 28-13 28-14 28-14 28-15 28-15 28-15 28-15 28-20 28-20 28-21 Part VIII 29 Manageability Database Management Database Startup and Shutdown ............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................. Summary of Imports for Oracle XA . Configuring Logging .................. 29-1 Database Change Notification.........................................................................................................................27 Transparent Application Failover Overview of Transparent Application Failover.................................. XA Components................................................. XADatasource Interface and Oracle Implementation................................................................ Enabling Logging......................................................................... XAConnection Interface and Oracle Implementation .................................................. 30-1 30-2 30-2 30-2 30-3 30-5 xiv ................................. Implementing a Distributed Transaction ................................................................................................................................................................................................................................................................................................... OracleXAResource Method Functionality and Input Parameters ............................................................................................... XAResource Interface and Oracle Implementation ........................................................ 27-1 27-1 27-2 27-2 Part VII 28 Transaction Management Distributed Transactions Overview of Distributed Transactions.. TAF Callbacks ....................................... Failover Type Events................ Enabling and Using JDBC Logging ...........................

.............................................. Statement Caching ................................................................................................................. and Security Issues........................................................................................ Disabling Auto-Commit Mode ......................................................................................................................... IEEE 754 Floating Point Compliance.............. SQLWarning Class ..............................An Example................................. and RECORD Types ................................................. Standard and Oracle Update Batching ......................... CursorName... Scalability............................................................................................................. Function Call Syntax............................................................................................................................................................................................................................................................................................ SQL92 to SQL Syntax Example ..................................................... Supported SQL and PL/SQL Data Types..................................................................................................................................................................... Standard Fetch Size and Oracle Row Prefetching ..... SQL92 Outer Join Escapes............................ 30-6 Performance........................... LIKE Escape Characters ........................................................................... PL/SQL TABLE............................ Oracle JDBC Notes and Limitations............................................................ B-1 B-1 B-1 B-2 B-2 B-3 B-3 B-4 xv ..................................................................................... Mapping Between Built-in SQL and Java Types ................... Transaction Isolation Levels and Access Modes ..................................................................................................................................................................................................................................................... Date Literals.............................................................................................................................................................................. Timestamp Literals ............. Outer Joins................................................................................................................................................ Time Literals ................................................................................................................................................................................................................................................................................................ Catalog Arguments to DatabaseMetaData Calls............................................................................................................................................................ Embedded SQL92 Syntax ........................................................................................................................................................................................................................................................................................................... Determining the Type of Metric to Be Generated .............................................................................................. Performance Optimization ............................................................................................................................................................. Binding Named Parameters ......................................................................................... 30-7 Diagnosability Management.................... BOOLEAN..... Scalar Functions........................................................................................................................................................................ Generating the SQLText Metric ............................................ Accessing DMS Metrics Using JMX .......................................................................................................................................................... Time and Date Literals .................................... 30-8 31 JDBC DMS Metrics Overview of JDBC DMS Metrics ................................................................................................................ 31-1 31-2 31-2 31-3 Part IX A Appendixes Reference Information Valid SQL-JDBC Data Type Mappings...... A-1 A-3 A-6 A-7 A-7 A-7 A-8 A-9 A-9 A-10 A-10 A-10 A-11 A-11 A-11 A-11 A-12 A-12 A-12 A-12 B Coding Tips JDBC and Multithreading ....

................... C-9 Native XA Messages Sorted by ORA Number ...................................... TRACE_FILE_CLIENT .. C-5 Native XA Messages ............................................................................................ TRACE_LEVEL_SERVER .............................. Oracle Net Tracing to Trap Network Events ...................................................................................................................................................................... Memory Leaks and Running Out of Cursors.................................................................................................................. Boolean Parameters in PL/SQL Stored Procedures............................... D-1 D-1 D-2 D-2 D-2 D-3 D-3 D-4 D-4 D-4 D-4 D-5 D-5 D-5 D-6 D-6 D-6 D-6 D-6 Index xvi ....................................................... Using JDBC with Firewalls ...................................................................................................................................................................................................C JDBC Error Messages General Structure of JDBC Error Messages .......................................................................................................cancel ....... Memory Consumption for CHAR Columns Defined as OUT or IN/OUT Variables ....... C-10 TTC Messages Sorted by ORA Number ................................................................................ C-9 TTC Messages ................................................................................. C-9 Native XA Messages Sorted in Alphabetic Order ........................................................................................................................................................................................... TRACE_UNIQUE_CLIENT .......................................... Basic Debugging Procedures ......................................................................................................................................................................................................................................................................................................... C-1 JDBC Messages Sorted in Alphabetic Order .......................................................................................... C-1 JDBC Messages Sorted by ORA Number ......... TRACE_FILE_SERVER .......................... TRACE_LEVEL_CLIENT .......................................................... TRACE_DIRECTORY_CLIENT ..................................................................................................... C-11 D Troubleshooting Common Problems.... TRACE_DIRECTORY_SERVER ............................................................................................................................................................................ Client-Side Tracing .................................................................................................................................................. Opening More Than 16 OCI Connections for a Process.................................................................................................................................................................................................................. Server-Side Tracing ......................... C-10 TTC Messages Sorted in Alphabetic Order ................................................... Using statement.. C-1 General JDBC Messages .................................................................................................................................................................................................................................................................. Third Party Debugging Tools ............................

xvii .

..................................................................................................................................................................... 12-3 JPublisher SQL Type Categories.............................................. 23-19 onsctl Commands . 3-5 CLOB Method Equivalents............................ 11-7 LONG and LONG RAW Data Conversions ...... A-3 Support for ANSI-92 SQL Data Types ...............jdbc Package..... 26-4 Connection Mode Transitions ................................................................................................ 9-7 OCI Driver Client Parameters for Encryption and Integrity .................0 Functionality ........................................................................................................................................................ 29-2 Database Change Notification Registration Options.............................................. A-4 Support for SQL User-Defined Types........................................................................................ A-4 Support for PL/SQL Data Types .... 4-19 PL/SQL Types and Corresponding JDBC Types.......... and Defaults ................................................................................... 3-2 BLOB Method Equivalents ............................................................................................................................. 9-8 Default Mappings Between SQL Types and Java Types.............................................................................................................................................................. 4-5 Key Interfaces and Classes of the oracle............................................................................................................................................................................ 4-29 Arguments of the setPlsqlIndexTable Method.................. 1-5 Import Statements for JDBC Driver .................................................................................................. 20-7 Methods Used to Retrieve Explicitly Cached Statements...................................... 4-33 Arguments of the getPlsqlIndexTable Method .............................................................................................. B-3 xviii ........................... 13-33 Visibility of Internal and External Changes for Oracle JDBC......................................... 29-6 Valid SQL Data Type-Java Class Mappings ............................................ 28-4 Oracle-XA Error Mapping ......................................................... 1-4 Feature List.....................................List of Tables 1–1 1–2 2–1 3–1 3–2 3–3 4–1 4–2 4–3 4–4 4–5 4–6 4–7 4–8 6–1 6–2 8–1 8–2 8–3 9–1 9–2 9–3 11–1 11–2 12–1 13–1 17–1 18–1 20–1 20–2 20–3 23–1 26–1 28–1 28–2 29–1 29–2 29–3 A–1 A–2 A–3 A–4 A–5 B–1 Feature Differences Between JDBC OCI and JDBC Thin Drivers. 9-8 Thin Driver Client Parameters for Encryption and Integrity ............................................................................................................................. 28-14 Supported Database Startup Options ...................................................................................... 20-3 Methods Used in Statement Allocation and Implicit Statement Caching .................................................................... 8-4 Supported Database Specifiers .................................................................................................................................................... 29-2 Supported Database Shutdown Options........... 4-32 Argument of the getOraclePlsqlIndexTable Method . 2-8 Key Areas of JDBC 3...... 6-3 Data Shared Library for Instant Client and Instant Client Light (English) .......................................................................................... 17-19 The JDBC and Cached Row Sets Compared.................................................................................................. 8-11 Client/Server Negotiations for Encryption or Integrity ......... 11-2 getObject and getOracleObject Return Types.................. 20-8 Valid Column Type Specifications .............................................................................................................................................................................................................................................................................................................................. 4-30 Arguments of the registerIndexTableOutParameter Method .................................................................. 8-3 Oracle Extended Data Source Properties................................................................. Supported Settings................. 6-9 Standard Data Source Properties............................................ A-5 Mapping of SQL Data Types to Java Classes that Represent SQL Data Types ....... 4-33 OCI Instant Client Shared Libraries .................. 18-9 Comparing Methods Used in Statement Caching...................................................................................................................................................... 3-6 Oracle Data Type Classes .. 4-31 Argument of the getPlsqlIndexTable Method ................ A-1 Support for SQL Data Types ....................................................................................

This book can be read by anyone with an interest in JDBC programming. some screen readers may not always read a line of text that consists solely of a bracket or brace. and Oracle is actively engaged with other market-leading technology vendors to address technical obstacles so that our documentation can be accessible to all of our customers. A list of related Oracle documents is also provided.com/accessibility/ Accessibility of Code Examples in Documentation Screen readers may not always correctly read the code examples in this document. To that end. Accessibility standards will continue to evolve over time. services. xix . structure. For more information. visit the Oracle Accessibility Program Web site at http://www. and conventions of this document. Oracle neither evaluates nor makes any representations regarding the accessibility of these Web sites. however.oracle. and contains markup to facilitate access by the disabled community.Preface This preface introduces you to the Oracle Database JDBC Developer's Guide and Reference discussing the intended audience. but assumes at least some prior knowledge of the following: ■ ■ ■ Java PL/SQL Oracle databases Documentation Accessibility Our goal is to make Oracle products. our documentation includes features that make information available to users of assistive technology. and supporting documentation accessible. The conventions for writing code require that closing braces should appear on an otherwise empty line. with good usability. to the disabled community. Accessibility of Links to External Web Sites in Documentation This documentation may contain links to Web sites of other companies or organizations that Oracle does not own or control. Audience The Oracle Database JDBC Developer's Guide and Reference is intended for developers of Java Database Connectivity (JDBC)-based applications and applets. This documentation is available in HTML format.

nested table types. JSP pages.446. It includes a general overview of JSP standards and programming considerations. Related Documents The following books are also available from the Oracle Java Platform group: ■ Oracle Database Java Developer's Guide This book introduces the basic concepts of Java and provides general information about server-side configuration and functionality. ■ Oracle Application Server Containers for J2EE Servlet Developer’s Guide This book provides information for servlet developers regarding use of servlets and the servlet container in OC4J. rather than to a particular product (such as JDBC) is in this book. such as JTA. This book also discusses Java stored procedures. or object reference types. JNDI. Outside the United States. VARRAY types. for Oracle Application Server releases.TTY Access to Oracle Support Services Oracle provides dedicated Text Telephone (TTY) access to Oracle Support Services within the United States of America 24 hours a day.458. which were formerly discussed in a standalone book. ■ Oracle Application Server Containers for J2EE Services Guide This book provides information about basic Java services supplied with OC4J. ■ Oracle Application Server Containers for J2EE Enterprise JavaBeans Developer’s Guide This book provides information about the EJB implementation and EJB container in OC4J.407. then JPublisher can generate custom Java classes to map to them. JavaBeans. ■ Oracle Application Server Containers for J2EE JSP Tag Libraries and Utilities Reference This book provides conceptual information and detailed syntax and usage information for tag libraries. For TTY support.2398. Information that pertains to the Oracle Java platform as a whole. The following documents are from the Oracle Server Technologies group: xx . The following OC4J documents. primer chapters for servlets.2479. It also documents relevant OC4J configuration files. and EJBs. and general configuration and deployment instructions. call 800. are also available from the Oracle Java Platform group: ■ Oracle Application Server Containers for J2EE User’s Guide This book provides some overview and general information for OC4J. 7 days a week. If you are developing JDBC applications that use object types. call +1. as well as discussion of Oracle value-added features and steps for getting started in the OC4J environment. and the Oracle Application Server Java Object Cache. and other Java utilities provided with OC4J. ■ Oracle Application Server Containers for J2EE Support for JavaServer Pages Developer’s Guide This book provides information for JSP developers who want to run their pages in OC4J. ■ Oracle Database JPublisher User's Guide This book describes how to use the Oracle JPublisher utility to translate object types and other user-defined types to Java classes.

including the latest specifications: http://java.jsp ■ jdbc-interest discussion group for JDBC To subscribe. send an e-mail to listserv@java.jsp ■ Web site for JDBC.com/membership/ If you already have a user name and password for OTN.com/ To download free release notes.com/javase/technologies/core.sun. registration is free and can be done at http://otn.com with the following line in the body of the message: subscribe jdbc-interest yourlastname yourfirstname xxi . then you can go directly to the documentation section of the OTN Web site at http://otn. Standard Edition (Java SE): http://java.oracle.sun.4) The following are available from the JDeveloper group: ■ ■ Oracle JDeveloper online help Oracle JDeveloper documentation on the Oracle Technology Network: http://otn.oracle.0.com/products/jdev/content.com/javase/technologies/database.com/documentation/ The following resources are available from Sun Microsystems: ■ Web site for Java Platform. installation documentation. visit the Oracle Technology Network (OTN).oracle. or other collateral. You must register online before using OTN.oracle.html Printed documentation is available for sale in the Oracle Store at: http://oraclestore.sun. white papers.■ ■ ■ ■ ■ ■ ■ ■ Oracle Database Advanced Application Developer's Guide Oracle Database PL/SQL Packages and Types Reference Oracle Database PL/SQL Language Reference Oracle Database SQL Language Reference Oracle Database Net Services Administrator's Guide Oracle Database Advanced Security Administrator's Guide Oracle Database Reference Oracle Database Error Messages The following documents from the Oracle Application Server group may also be of some interest: ■ ■ ■ ■ ■ ■ Oracle Application Server 10g Administrator’s Guide Oracle Fusion Middleware Administrator's Guide for Oracle HTTP Server Oracle Application Server 10g Performance Guide Oracle Application Server 10g Globalization Guide Oracle Application Server Web Cache Administrator’s Guide Oracle Application Server 10g Upgrading to 10g (9.

To do this add the following line to the message body as well: set jdbc-interest digest Conventions This section describes the conventions used in the text and code examples of this documentation set. Run old_release. Query the TABLE_NAME column in the USER_TABLES data dictionary view. Oracle Database Concepts Ensure that the recovery catalog and target database do not reside on the same disk. RMAN keywords. or both. SQL keywords. xxii .SQL where old_release refers to the release you installed prior to upgrading. Italic typeface indicates book titles or emphasis. packages and classes. SQL*Plus or utility commands. The password is specified in the orapwd file. privileges. and roles. The JRepUtil class implements these methods. Connect as oe user. program units. net service names. Enter sqlplus to start SQL*Plus. Italics UPPERCASE monospace (fixed-width) font Uppercase monospace typeface indicates elements supplied by the system. directory names. Such elements include computer and database names. Back up the datafiles and control files in the /disk1/oracle/dbs directory. You can specify this clause only for a NUMBER column. filenames. Set the QUERY_REWRITE_ENABLED initialization parameter to true. You can back up the database by using the BACKUP command. lowercase monospace (fixed-width) font lowercase italic monospace (fixed-width) font Lowercase italic monospace font represents You can specify the parallel_clause. as well as user-supplied database objects and structures. column names. and connect identifiers.GENERATE_STATS procedure. data types. you create an defined in the text or terms that appear in a index-organized table. Note: Some programmatic elements use a mixture of UPPERCASE and lowercase. Convention Bold Meaning Example Bold typeface indicates terms that are When you specify this clause. user names and roles. as well as system-supplied column names. department_name. Lowercase monospace typeface indicates executables. The department_id. user names. database objects and structures. and sample user-supplied elements.departments table. Enter these elements as shown. The following table describes those conventions and provides examples of their use. glossary. and parameter values. packages and methods. Use the DBMS_STATS. placeholders or variables.We recommend that you request only the daily digest of the posted e-mails. and location_id columns are in the hr. Such elements include parameters.

in-place data replacement.5 and 1. Oracle SecureFiles Java/JDBC applications get richer SecureFiles LOB data manipulation API and performance enhancements such as versioning. compression.What’s New The changes in Oracle Database 11g Release 1 (11. For more information refer "Oracle SYS. and client-side read.0 standard features ANYTYPE and ANYDATA This release of Oracle JDBC drivers provides a Java interface to access SYS. This release of Oracle JDBC drivers have been enhanced to support all the features of Oracle Advanced Security. JDBC 4.5.5 and 1.1) In this release.ANYDATA Types" Types on page 4-16. sliding inserts. encryption. integrity.1) Desupported Features Interface Changes New Features for Release 1 (11.ANYTYPE and SYS.ANYTYPE and SYS.ANYDATA Oracle types. fragment move. xxiii . The server-side JDBC drivers provide support for only JDK 1. sliding delete. This feature is covered in Chapter 9. and availability features.0 Support Oracle JDBC drivers provide support for most of the JDBC 4. Oracle JDBC drivers support the following new features: JDK 1.1) can be divided into the following categories: ■ ■ ■ New Features for Release 1 (11. "JDBC Client-Side Security Features".0 Standard" on page 3-6 for more information about the JDBC 4. Refer to "Support for JDBC 4. This feature is covered in "Oracle SecureFiles" on page 14-19.0 standard features. Oracle Advanced Security Oracle Advanced Security provides confidentiality.6.6 Support The Oracle JDBC Thin and OCI drivers have been enhanced to provide support for JDK 1. sharing.

and earlier versions of Oracle JDBC as it makes no attempt to retain compatibility with earlier versions.2. For more information refer "Result Set Caching" on page 20-9. RowSets in the server Starting from this release.1 release are different from 10. For more information refer "Overview of JDBC RowSets" on page 18-1. the oracle. Result Cache This release of Oracle JDBC drivers provide support for Result Cache feature. "Diagnosability in JDBC". Desupported Features From this release onwards.jdbc. xxiv . Database Diagnosability In this release the JDBC drivers have been enhanced by including new diagnosabilty features and improving existing diagnosabilty features. Oracle JDBC drivers will not support JDK versions earlier than 1.5. multi-tier systems can take advantage of the Database Change Notification feature to maintain a data cache as updated as possible by receiving invalidation events from the JDBC drivers. Using this functionality of the JDBC drivers.1. Database Change Notification This release of Oracle JDBC drivers provide support for the Database Change Notification feature of Oracle Database. all connection properties are defined as constants in this interface. This feature is covered in Chapter 25. This feature is covered in detail in Chapter 30. you can start up and shut down an Oracle Database instance from your JDBC application in the same way as you would from SQL*Plus. This feature is covered in detail in "Database Change Notification" on page 29-4. "Oracle Advanced Queuing". For more information refer "Accessing DMS Metrics Using JMX" on page 31-3.2.OracleConnection interface has been enhanced. Interface Changes In this release.Native Streams AQ Protocol This release of Oracle JDBC drivers provides a Java interface to Oracle Streams Advanced Queuing (AQ). which is very different from traditional caching and presummarization mechanisms. 10. RowSets are also supported in the server-side drivers. Database Startup and Shutdown Starting from this release. These features enable users to diagnose problems in the applications that use Oracle JDBC drivers and the problems in the drivers themselves. New JDBC DMS Metrics with JMX Support The Dynamic Monitoring Service (DMS) metrics generated in Oracle JDBC 11. in addition to the Thin and OCI drivers. This feature is covered in "Database Startup and Shutdown" on page 29-1. 9. For better visibility and clarity.

jdbc package instead of this package.1. Code having references to this package will not compile and run. which was deprecated in Oracle Database release 9.0.driver package. xxv . is desupported in this release.The oracle.jdbc. You can use oracle.

xxvi .

"Introducing JDBC" Chapter 2.Part I Overview The chapters in this part introduce the concept of Java Database Connectivity (JDBC) and provide an overview of the Oracle implementation of JDBC. This part provides basic information about installation and configuration of the Oracle client with reference to JDBC drivers. "Getting Started" . This part also covers the basic steps in creating and running any JDBC application. Part I contains the following chapters: ■ ■ Chapter 1.

.

1 Introducing JDBC Java Database Connectivity (JDBC) is a Java standard that provides the interface for connecting from Java to relational databases. JDBC is based on the X/Open SQL Call Level Interface (CLI).0 complies with the SQL 2003 standard. the code runs and accesses data from a single Oracle session. Oracle provides the following JDBC drivers: ■ Thin driver It is a pure Java driver used on the client-side.sql interfaces. covering the following topics: ■ ■ ■ Overview of Oracle JDBC Drivers Environments and Support Feature List Overview of Oracle JDBC Drivers In addition to supporting the standard JDBC application programming interfaces (APIs). It can be used with both applets and applications. However. ■ Server-side Thin driver It is functionally similar to the client-side Thin driver. ■ Server-side internal driver It is used for code that runs on the database server and accesses the same session. This chapter provides an overview of the Oracle implementation of JDBC. without an Oracle client installation. This allows individual providers to implement and extend the standard with their own JDBC drivers. The JDBC standard is defined by Sun Microsystems and implemented through the standard java. It can be used only with applications. Figure 1–1 illustrates the architecture of Oracle JDBC drivers and Oracle Database. ■ Oracle Call Interface (OCI) driver It is used on the client-side with an Oracle client installation. it is used for code that runs on the database server and needs to access another session either on the same server or on a remote server on any tier. That is. Oracle drivers have extensions to support Oracle-specific data types and to enhance performance. Introducing JDBC 1-1 . JDBC 4.

The server-side internal drivers support only JDK 1.6. You can access the Oracle-specific features.5 and 1. The JDBC Thin and OCI drivers support Java Development Kit (JDK) 1. 1-2 Oracle Database JDBC Developer's Guide and Reference . Type IV driver that can be used in applications and applets. All the JDBC drivers support the following standards and features: ■ ■ ■ Same syntax and APIs Same Oracle extensions Full support for multithreaded applications Oracle JDBC drivers implement the standard java.5. The JDBC Thin driver communicates with the server using SQL*Net to access Oracle Database. It is platform-independent and does not require any additional Oracle software on the client-side. JDBC Thin Driver The JDBC Thin driver is a pure Java. by using the oracle.Overview of Oracle JDBC Drivers Figure 1–1 Architecture of Oracle JDBC Drivers and Oracle Database Oracle Database JDBC Thin Driver Java Sockets Java Engine Server-Side Thin Driver JDBC Server-Side Internal Driver JDBC OCI Driver OCI C Library SOL Engine PL/SQL Engine KPRB C Library Oracle Database This section covers the following topics: ■ ■ ■ Common Features of Oracle JDBC Drivers Choosing the Appropriate Driver Feature Differences Between JDBC OCI and Thin Drivers Common Features of Oracle JDBC Drivers The server-side and client-side Oracle JDBC drivers provide the same basic functionality.sql interfaces.jdbc package. in addition to the standard features.

the issue of network round-trips is irrelevant. and other necessary files on the client computer where it is installed. "Features Specific to JDBC Thin" JDBC Server-Side Internal Driver The JDBC server-side internal driver supports any Java code that runs inside Oracle Database. "Features Specific to JDBC Thin" JDBC OCI Driver The JDBC OCI driver is a Type II driver used with Java applications. and the SQL engine all run within the same address space. core libraries. The programs access the SQL engine by using function calls. therefore. OCI is an API that enables you to create applications that use the native procedures or function calls of a third-generation language to access Oracle Database and control all phases of the SQL statement processing.Overview of Oracle JDBC Drivers The JDBC Thin driver allows a direct connection to the database by providing an implementation of SQL*Net on top of Java sockets. Oracle Net. and must access the same database. named pipes. Note: The server-side internal driver does not support the cancel and setQueryTimeout methods of the Statement class. using native methods to call C-entry points. The JDBC server-side internal driver. However. is Oracle platform-specific. such as from a Java stored procedure ■ The use of JDBC Thin driver from a client application or from inside a server does not affect the code. This driver is useful in the following scenarios: ■ Accessing a remote database server from an Oracle Database instance acting as a middle tier Accessing an Oracle Database session from inside another. The JDBC OCI driver. "Features Specific to JDBC OCI Driver" JDBC Server-Side Thin Driver The JDBC server-side Thin driver offers the same functionality as the JDBC Thin driver that runs on the client-side. This driver supports only JDK 1. It supports all installed Oracle Net adapters.5. and Internetwork Packet Exchange/Sequenced Packet Exchange (IPX/SPX). It lets the Java Virtual Machine (JVM) to communicate directly with the SQL engine. written in a combination of Java and C. See Also: Chapter 5. C-entry points. TCP/IP. and therefore. the JDBC server-side Thin driver runs inside Oracle Database and accesses a remote database or a different session on the same database. the database. the Oracle JVM. These calls communicate with the database using SQL*Net. See Also: Chapter 5. The JDBC OCI driver uses the OCI libraries. Introducing JDBC 1-3 . including interprocess communication (IPC). The driver supports the TCP/IP protocol and requires a TNS listener on the TCP/IP sockets on the database server. See Also: Chapter 6. converts JDBC invocations to calls to OCI. It requires an Oracle client installation and. such as in a Java stored procedure.

use the JDBC Thin driver. then you must use the JDBC Thin driver. Most JDBC OCI driver features are not available in the JDBC Thin driver because they are inherited from OCI. For code that runs in the database server and needs to access a remote database or another session within the same database instance. use the JDBC server-side Thin driver. If you are writing a client application for an Oracle client environment and need OCI-driver-specific features.Environments and Support The JDBC server-side internal driver is fully consistent with the client-side drivers and supports the same features and extensions. such as support for non-TCP/IP networks. then use the JDBC Thin driver. ■ Environments and Support This section provides a brief discussion of the following topics: 1-4 Oracle Database JDBC Developer's Guide and Reference . If your code runs inside the database server and needs to access data locally within the session. ■ ■ ■ ■ ■ ■ Feature Differences Between JDBC OCI and Thin Drivers Table 1–1 lists the features that are specific either to the JDBC OCI or JDBC Thin driver in Oracle Database 11g Release 1 (11.1). then use the JDBC Thin driver. "Server-Side Internal Driver" Choosing the Appropriate Driver Consider the following when choosing a JDBC driver for your application or applet: ■ In general. unless you need OCI-specific features. then use the JDBC OCI driver. If you are writing an applet. You can connect to Oracle Database from either an application or an applet using the JDBC Thin driver. Table 1–1 Feature Differences Between JDBC OCI and JDBC Thin Drivers JDBC Thin Driver Default support for Native XA JDBC OCI Driver OCI connection pooling Transparent Application Failover (TAF) OCI Client Result Cache Note: ■ The OCI optimized fetch and client-side object cache features are internal to the JDBC OCI driver and are not applicable to the JDBC Thin driver. If you want to use Lightweight Directory Access Protocol (LDAP) over Secure Sockets Layer (SSL). See Also: Chapter 7. If you want maximum portability and performance. such as support for non-TCP/IP networks. then use the JDBC server-side internal driver to access that server.

integrated set of products to build.6 8.6 8.0 SQL3 Types (BLOB.2 JDK 1.0. CLOB.2.5.1. All versions of JDK earlier than 1.0.6 8.1).2 7. JDBC OCI driver.1. The Oracle JDeveloper environment contains integrated support for JDBC.6 8. just minor revisions) defineColumnType Row Prefetch Oracle Batching Java Native Interface JDK 1.0. Table 1–2 Feature JDK 1. JDBC and IDEs The Oracle JDeveloper Suite provides developers with a single.0.Feature List ■ ■ ■ Supported JDK and JDBC Versions JNI and Java Environments JDBC and IDEs Supported JDK and JDBC Versions In Oracle Database 11g Release 1 (11.1.22 (No new features. in particular. respectively.0 JDBC 1.6 8.5 8.0.5 are no longer supported.1 8.6 8.1.6 8.2 8.1.0. You can use the JDBC OCI driver with JVMs other than that of Sun Microsystems.0.5 Feature List Server-Side Internal JDBC OCI 7.6 8.2 JDBC 2. and deploy component-based database applications for the Internet.0. including the JDBC Thin driver and the native OCI driver. all the JDBC drivers are compatible with JDK 1. The JDBC Thin and OCI drivers also support JDK 1.6 Introducing JDBC 1-5 .5 and 1.2. Feature List Table 1–2 lists the features and the versions in which they were first supported for each of the three Oracle JDBC drivers: server-side internal driver. Support for JDK 1.6 is provided through the ojdbc5.6.0.1.0.jar and ojdbc6. REF) 9. and JDBC Thin driver.2.2 8.1.2 7.0. with Microsoft and IBM JVMs.jar files.2. debug.6 8. See Also: "Version Compatibility for Oracle JDBC Drivers" on page 2-1 JNI and Java Environments The JDBC OCI driver uses the standard Java Native Interface (JNI) to call OCI C libraries.6 8.6 8.5 JDBC Thin 7. Array.0. The database component of Oracle JDeveloper uses the JDBC drivers to manage the connection between the application running on the client and the server.1 JDBC 1. Struct.6 8.

6 NA 9.1.1.0.0 10.1.1.1 9.2.0 8.1.0.0 10.1.0 Set/Get Stored Procedures Parameters by Name NA 10.6 8.1 9.0 10.1 9.2.0.0 10.1.1.0.1 8.1.7 9.1.0 10.3 9.1.0 10.1 9.0 XA Server-side Thin driver JDBC 2.0 9.0 9.0.2.0 Savepoints New Statement Caching API ConnectionCacheImpl connection cache Implicit Connection Cache Fast Connection Failover Connection Wrapping DMS Service Names in URLs JDBC 3.1.1 9.0.0 Multiple Open Result Sets JDBC 3. REF JDBC 3.2.1.1.0 9.7 9.0 NA 1-6 Oracle Database JDBC Developer's Guide and Reference .0 10.0.2.0 Parameter Metadata JDBC 3.0 9.1.6 NA 8.1 9.0.0 RowSets Implicit Statement Caching Explicit Statement Caching Temporary LOBs Object Type Inheritance Multilevel Collections oracle.0 9.2.2.4 JDBC 3.0 11.1.7 8.3 9.3 JDK 1.0 Updatable Result Sets JDBC 2.0 10.2.) Feature List Feature Native LOB Index-by Tables JDBC 2.0 NA 9.7 8.0 10.1.2.0 NA NA NA 8.1.0 10.6 NA 9.2.2.1.0 10.6 8.6 8.0 Scrollable Result Sets JDBC 2.0 JDBC Thin 9.1.7 8.1.1.2.0.2.1.0 Standard Batching JDBC 2.1 9.2.0 10.0.6 8.6 8.6 8.1.6 8.0 9.6 8.2.1.1 9.2.6 8.0 9.1.6 8.1 11.1.0.1.7 10.1.0.1.1 9.6 8.1.0.0.1 10.1.0 Updatable BLOB.1.0 NA 9.0 9.0 11.2.0.2.0 9.6 Server-Side Internal JDBC OCI 8.1.0.1 9.0 8.0.1.0 9.2.Feature List Table 1–2 (Cont. CLOB.1 9.1.0 8.7 9.0 9.0.1.6 8.0.0.1.0 10.0 10.1 8.0 Connection Pooling JDBC 2.7 10.1.1.1.1 9.1.1 9.0 9.jdbc Interfaces Native XA OCI Connection Pooling OCI Client Result Cache Server Result Cache TAF NLS Support JDK 1.1.1.0 10.1 9.0 10.0 10.0 10.1 10.1 9.1.0.6 8.0 Connection Pooling Properties JDBC 3.0.1.2.0 8.2.2.

0 10.1.1 JDBC Thin 10.2.0 10.0 Database startup and shutdown Java interface to Streams AQ 11.0 10.) Feature List Feature JDBC 3.0 10.0 10.0 Auto Generated Keys JDBC 3.1.0 10.1.2.2.0 10.2.2 11.2.0 Statement Pooling Set Statement Parameters by Name End-to-End Tracing Web RowSet Proxy Authentication JDBC 3.0 10.1 11.0 10.1 10.2 11.0 10.2.0 11.2.2.1 NA 10.2.1.1.2.1 11.2.0 10.0 9.0 Local/Global Transaction Switching Run-time Connection Load Balancing Extended setXXX and getXXX for LOBs XA Connection Cache DML Returning JSR 114 RowSets SSL Encryption SSL Authentication Radius Authentication JDK 1.2.5 JDK 1.2.1 11.2.0 10.0 10.0 NA Server-Side Internal 10.1 Note: ■ In the table.0 10.1 11.0 10.2.0 10. The ConnectionCacheImpl connection cache feature is deprecated since Oracle Database 10g and Implicit Connection Cache replaces this.2 NA 10.2.0 Holdable Cursors JDBC 3.0 JDBC OCI 10.1.2.0 9.1.2.0 9.1. NA means that the feature is not applicable for the corresponding Oracle JDBC driver.0 10.2.1.0 10.Feature List Table 1–2 (Cont.0 10.0 10.0 9.1.1.2.2.0 10.0 10.2. ■ Introducing JDBC 1-7 .0 10.6 JDBC 4.0 9.2.0 10.1 11.0 10.0 10.

Feature List 1-8 Oracle Database JDBC Developer's Guide and Reference .

database versions. For example. Forward Compatibility Existing and supported JDBC drivers are certified to work with Oracle Database 11g Release 1 (11.x and 7.com/technology/tech/java/sqlj _jdbc/htdocs/jdbc_faq.2.x. 10. they are not certified to work with older.1. Querying. 9.x or earlier versions.1).4. You can find a complete.oracle.0. up-to-date list of supported databases at http://www.x. This chapter contains the following sections: ■ ■ ■ ■ ■ ■ Version Compatibility for Oracle JDBC Drivers Verification of a JDBC Client Installation Basic Steps in JDBC Sample: Connecting. the JDBC Thin drivers in Oracle Database 11g Release 1 (11.x. unsupported database releases.htm. and Processing the Results Stored Procedure Calls in JDBC Programs Processing SQL Exceptions Version Compatibility for Oracle JDBC Drivers This section discusses the general JDBC version compatibility issues.x Oracle Database releases.2 Getting Started This chapter discusses the compatibility of Oracle Java Database Connectivity (JDBC) driver versions.1. However. It also describes the basics of testing a client installation and configuration and running a simple application.2. ■ Getting Started 2-1 .0. and Java Development Kit (JDK) versions.1) are certified to work with the 10. Note: ■ In Oracle Database 11g Release 1 (11. and 9.1). Backward Compatibility The JDBC drivers are certified to work with the currently supported versions of Oracle Database. Oracle JDBC drivers no longer support JDK 1. such as 8.x.

among other things. then you must also install the Oracle client software. including examples of how to use SQL92 and Oracle SQL syntax.jar. and Oracle performance extensions. which is the Oracle JDBC application programming interface (API) documentation.jar 2-2 Oracle Database JDBC Developer's Guide and Reference . ojdbc5_g.jar. This section describes the steps for verifying an Oracle client installation of the JDBC drivers.txt file are created. ■ lib The lib directory contains the following required Java classes: – orai18n.jar and orai18n-mapping.tar. Check the Installed Directories and Files Installing the Oracle Java products creates. additional Oracle type extensions. demo. Note: The JDBC Thin driver requires a TCP/IP listener to be running on the computer where the database is installed. then no further installation on the client computer is necessary. This includes Oracle Net and the OCI libraries. ■ doc This directory contains the javadoc. user-defined types. the following directories: ■ ■ ORACLE_HOME/jdbc ORACLE_HOME /jlib Check whether or not the following directories and files have been created and populated in the ORACLE_HOME/jdbc directory: ■ demo This directory contains a compressed file. the samples directory and the Samples-Readme. When you uncompress this compressed file. and ojdbc6_g. you must do all of the following: ■ ■ ■ ■ ■ Check the Installed Directories and Files Check the Environment Variables Ensure that the Java Code Can Be Compiled and Run Determine the Version of the JDBC Driver Test JDBC and the Database Connection Installation of an Oracle JDBC driver is platform-specific. Follow the installation instructions for the driver you want to install in your platform-specific documentation. ojdbc6.zip file. assuming that you have already installed the driver of your choice.jar Contain classes for globalization and multibyte character sets support – ojdbc5. If you have installed the JDBC Oracle Call Interface (OCI) driver.Verification of a JDBC Client Installation Verification of a JDBC Client Installation To verify a JDBC client installation. The samples directory contains sample programs.zip or demo. PL/SQL blocks.jar. streams. If you have installed the JDBC Thin driver.

This means that the Java run-time loads the driver when needed and you need not include Class. These are required only if you are using JTA features for distributed transaction management or JNDI features for naming services.Verification of a JDBC Client Installation Contain the JDBC driver classes for use with JDK 1. However. the ojdbc14. and Microsoft Windows platforms. which may not have been included in other documentation on the product.jar ORACLE_HOME/jlib/orai18n. Include the following in the CLASSPATH environment variable: ORACLE_HOME/jdbc/lib/ojdbc5.jar Note: If you use the JTA features and the JNDI features. then you must specify jta.5 and JDK 1. it is recommended that you use the versions supplied by Oracle.jar files are no longer shipped.jar These files contain classes for the Java Transaction API (JTA) and the Java Naming and Directory Interface (JNDI). Check the Environment Variables This section describes the environment variables that must be set for the JDBC OCI driver and the JDBC Thin driver.jdbc. But if you are using J2SE 5. which are shipped with Oracle Database 11g. which have been tested with the Oracle drivers. Linux.jar and jndi.1).5 has been removed.jar and ojdbc6.txt This file contains late-breaking and release-specific information about the drivers. You must set the CLASSPATH environment variable for your installed JDBC OCI or Thin driver.jdbc.jar in your CLASSPATH environment variable. If you are using JSE 6 and later. focusing on the Sun Solaris.OracleDriver() in your code.jar and jndi.6 Note: ■ In Oracle Database 11g Release 1 (11.jar files. Check whether or not the following directories have been created and populated in the ORACLE_HOME /jlib directory: ■ jta. Instead. Note: These files can also be obtained from the Sun Microsystems Web site. then you need to load the JDBC driver explicitly. ■ ■ Readme. you can use the ojdbc5.OracleDriver") or new oracle.jar and classes12. support for a version of JDK earlier than version 1. Also. then there is no need to explicitly load the JDBC driver.forName("oracle. Getting Started 2-3 .

See Also: Oracle Database Java Developer's Guide Ensure that the Java Code Can Be Compiled and Run To further ensure that Java is set up properly on your client system. then you do not have to set any other environment variables. set the PATH environment variable as follows: ORACLE_HOME\bin This directory contains the ocijdbc11. "Features Specific to JDBC OCI Driver" JDBC Thin Driver If you are installing the JDBC Thin driver. Now. However. All of the JDBC OCI demonstration programs can be run in the Instant Client mode by including the JDBC OCI Instant Client data shared library on the library path environment variable. The following is an example of how the permission can be granted for the user SCOTT: CREATE ROLE jdbcthin. '*'. to use the JDBC server-side Thin driver. set the LD_LIBRARY_PATH environment variable as follows: ORACLE_HOME/lib This directory contains the libocijdbc11. type the following 2-4 Oracle Database JDBC Developer's Guide and Reference . then you must also set the following value for the library path environment variable: ■ On Sun Solaris or Linux.net. To use the JDBC server-side Thin driver.SocketPermission'. CALL dbms_java. go to the samples directory under the ORACLE_HOME/jdbc/demo directory.grant_permission('JDBCTHIN'.Verification of a JDBC Client Installation JDBC OCI Driver If you are installing the JDBC OCI driver. 'java. a check is performed for a SocketPermission object. See Also: Chapter 6. The asterisk (*) is a pattern.so shared object library. Because Oracle Database enforces the Java security model. then you must also add ORACLE_HOME/lib32 to the LD_LIBRARY_PATH environment variable. GRANT jdbcthin TO SCOTT. you need to set permission. Note that JDBCTHIN in the grant_permission call must be in uppercase.dll dynamic link library. ■ On Microsoft Windows. 'connect'). Setting Permission for the Server-Side Thin Driver The JDBC server-side Thin driver opens a socket for its connection to the database. Note: If you are running a 32-bit Java Virtual Machine (JVM) against a 64-bit client or database. You can restrict the user by granting permission to connect to only specific computers or ports. the connecting user must be granted the appropriate permission.

The program connects to the database.getConnection(). queries for the string "Hello World".java is a simple program. : javac java Each of the preceding commands should display a list of options and parameters and then exit.OracleDataSource. One of the programs.sql. Go to the samples directory.java program. Determine the Version of the JDBC Driver You can determine the version of the JDBC driver that you installed.jar Test JDBC and the Database Connection The samples directory contains sample programs for a particular Oracle JDBC driver.jdbc. class JDBCVersion { public static void main (String args[]) throws SQLException { OracleDataSource ods = new OracleDataSource(). } } You can also determine the version of the JDBC driver by executing the following commands: ■ ■ java -jar ojdbc5.jar java -jar ojdbc6. and the name of the database to which you want to connect. Ideally. Although JdbcCheckup. import oracle. verify that you can compile and run a simple test program.java.jdbc. // gets driver info: System. is designed to test JDBC and the database connection.println("JDBC driver version is " + meta.out. and prints it to the screen. such as jdbc/demo/samples/generic/SelectExample. Connection conn = ods. password. // Create Oracle DatabaseMetaData object DatabaseMetaData meta = conn. one after the other. JdbcCheckup. to see if the Java compiler and the Java interpreter run without error.pool. If the results of the query print without error. by calling the getDriverVersion method of the OracleDatabaseMetaData class.setURL("jdbc:oracle:thin:scott/tiger@host:port:service").*.getDriverVersion()). ods.getMetaData(). including JDBC classes Getting Started 2-5 .Verification of a JDBC Client Installation commands on the command line. import oracle.*. The program queries for the user name. The following sample code shows how to determine the driver version: import java. and compile and run the JdbcCheckup. it demonstrates several important functions by performing the following: ■ Imports the necessary Java classes. then your Java and JDBC installations are correct.

println("Please enter information to test connection to the database").setURL("jdbc:oracle:oci:@" + database).out.. String database. * Just run it and provide the connect information. System. IOException { // Prompt the user for connect information System.indexOf('/'). // Do the SQL "Hello World" thing 2-6 Oracle Database JDBC Developer's Guide and Reference . oracle. // Open an OracleDataSource and get a connection OracleDataSource ods = new OracleDataSource().java program. It will select * "Hello World" from the database. database = readEntry("database(a TNSNAME entry): ").substring(0. System..println("Connecting.").setUser(user).").io to be able to read from the command line import java. if (slash_index != -1) { password = user. ods.createStatement().println("connected.*. class JdbcCheckup { public static void main(String args[]) throws SQLException.jdbc. Connection conn = ods.. // Create a statement Statement stmt = conn.out. which uses the JDBC OCI driver.substring(slash_index + 1)."). ods..out.getConnection().*.out. ods.Verification of a JDBC Client Installation ■ ■ ■ ■ Creates a DataSource instance Connects to the database Runs a simple query Prints the query results to your screen The JdbcCheckup.io. String user. String password. System.OracleDataSource. int slash_index = user.setPassword(password).out.sql. } else password = readEntry("password: "). // We import java. user = readEntry("user: "). System.*.print("Connecting to the database. is as follows: /* * This sample can be used to check the JDBC installation. oracle. slash_index). */ // You import import import need to import the java.sql and JDBC packages to use JDBC java.pool. user = user.jdbc.flush().

int c = System. while (rset. c = System. in the form of a tutorial.out. 5. conn.close().close(). The tutorial guides you through the steps to create code that connects to and queries a database from the client. When using Oracle JDBC drivers.out. System. Importing Packages Opening a Connection to a Database Creating a Statement Object Running a Query and Retrieving a Result Set Object Processing the Result Set Object Closing the Result Set and Statement Objects Making Changes to the Database Committing Changes Closing the Connection Getting Started 2-7 .in. you can start creating your JDBC applications. 6. where and how to add the information. } // Utility function to read a line from standard input static String readEntry(String prompt) { try { StringBuffer buffer = new StringBuffer(). stmt. You must write code to perform the following tasks: 1.append((char)c). System. This section describes. 9. the statement and the connection rset. while (c != '\n' && c != -1) { buffer.out.").println(rset.close(). 8.print(prompt). you must include certain driver-specific information in your programs. 4.Basic Steps in JDBC ResultSet rset = stmt.out. 7. 3.println("Your JDBC installation is correct.in.trim(). } } } Basic Steps in JDBC After verifying the JDBC client installation. // close the result set. System.next()) System.read(). 2.read().toString(). } return buffer.getString(1)). } catch(IOException e) { return "".executeQuery("select 'Hello World' from dual").flush().

math.setURL(url). PortNumber.*. The properties of the retrieved connection are derived from the OracleDataSource instance. This is optional. and driver type are ignored.*. Note: It is better to import only the classes your application needs. then all other properties. import java. ServerName. If you set the URL connection property. You can omit this package if you are not going to use these classes in your application. Import statement import java. ServiceName. including TNSEntryName. String url = "jdbc:oracle:thin:@//myhost:1521/orcl". import oracle.*. The Oracle packages listed as optional provide access to the extended functionality provided by Oracle JDBC drivers. user name.pool. but this is not the recommended way of importing classes and interfaces. and Password The following code sets the URL. you must create an OracleDataSource instance. import oracle. The following example connects user scott with password tiger to a database with service orcl through port 1521 of the host myhost.*.*. but are not required for the example presented in this section. Opening a Connection to a Database First.Basic Steps in JDBC Note: You must supply Oracle driver-specific information for the first three tasks. which allow your program to use the JDBC application programming interface (API) to access a database. DatabaseName. 2-8 Oracle Database JDBC Developer's Guide and Reference . as you would for any Java application. Oracle extensions to JDBC. Then. include the import statements shown in Table 2–1 at the beginning of your program.jdbc. This guide uses the asterisk (*) for simplicity. and password for a data source: OracleDataSource ods = new OracleDataSource().getConnection method. ods.sql. The BigDecimal and BigInteger classes. For the other tasks. using the JDBC Thin driver: OracleDataSource ods = new OracleDataSource(). This is optional. rather than using the wildcard asterisk (*). Importing Packages Regardless of which Oracle JDBC driver you use. Oracle type extensions.sql. Specifying a Database URL. User Name. open a connection to the database using the OracleDataSource. ods. Network Protocol. import oracle. OracleDataSource. ods.jdbc. Table 2–1 Import Statements for JDBC Driver Provides Standard JDBC packages.setPassword(password). you can use standard JDBC Java code.setUser(user).

then you must specify the port number. See Also: Chapter 8. where the Connection object conn was created. String url = "jdbc:oracle:oci:scott/tiger@myTNSEntry"). if you want to connect to the database on the host myhost that has a TCP/IP listener on port 1521 and the service identifier is orcl. ods.setURL(url). the URL includes the user name and password and is the only input parameter. For example. This method takes a SQL statement as input and returns a JDBC ResultSet object. here is an example of how to create the Statement object: Statement stmt = conn. If you want to connect using the Thin driver. the next step is to create a Statement object.getConnection().setPassword("tiger"). "Data Sources and URLs" Creating a Statement Object Once you connect to the database and. Connection conn = ods. using the JDBC Oracle Call Interface (OCI) driver. create a Connection object.setUser("scott"). To continue the example from the previous section. Getting Started 2-9 . Connection conn = ods.createStatement(). then provide the following code: String URL = "jdbc:oracle:thin:scott/tiger@//myhost:1521/orcl"). Note: The user name and password specified in the arguments override any user name and password specified in the URL.getConnection(). The createStatement method of the JDBC Connection object returns an object of the JDBC Statement type. ods. Running a Query and Retrieving a Result Set Object To query the database.setURL(URL).Basic Steps in JDBC ods. use the executeQuery method of the Statement object. Specifying a Database URL that Includes User Name and Password The following example connects user scott with password tiger to a database host whose Transparent Network Substrate (TNS) entry is myTNSEntry. in the process.setURL(url).getConnection(). In this case. Connection conn = ods. ods. ods.

2-10 Oracle Database JDBC Developer's Guide and Reference .executeQuery ("SELECT ename FROM emp"). the executeUpdate method should be used. ■ To continue the example. If the SQL is known to be a DDL statement or a DML statement returning an update count. use the next() method of the ResultSet object to iterate through the results. This method steps through the result set row by row.println (rset. where XXX corresponds to a Java data type. For example. the next step is to run a query that returns a ResultSet object with the contents of the ename column of a table of employees named EMP: ResultSet rset = stmt. the following code will iterate through the ResultSet object. rset. the execute method should be used.next()) System. once you create the Statement object stmt. then the cursor is not released. You could also run out of cursors in the database. detecting the end of the result set when it is reached. then the executeQuery method throws a SQLException exception. If the type of the SQL statement is not known. the executeQuery method should be used. if your ResultSet object is rset and your Statement object is stmt. This applies to all ResultSet and Statement objects you create when using Oracle JDBC drivers. If you do not explicitly close the ResultSet and Statement objects. the executeQuery method does not throw a SQLException exception even if the SQL string being executed does not return a ResultSet object.getString(1)). from the previous section and will retrieve and print each employee name: while (rset. In case of an Oracle JDBC driver. Closing both the result set and the statement releases the corresponding cursor in the database. use the appropriate getXXX methods of the ResultSet object. The employee names are materialized as Java String values. For example. To pull data out of the result set as you iterate through it.Basic Steps in JDBC Note: ■ The method used to execute a Statement object depends on the type of SQL statement being executed.out. If the Statement object represents a SQL query returning a ResultSet object.close(). Processing the Result Set Object Once you run your query. The next() method returns false when it reaches the end of the result set. The cleanup routines are performed by the close method of the ResultSet and Statement classes. If you close only the result set. then close the result set and statement with the following lines of code: rset. In case of a standard JDBC driver. if the SQL string being executed does not return a ResultSet object. serious memory leaks could occur. Closing the Result Set and Statement Objects You must explicitly close the ResultSet and Statement objects after you finish using them. The drivers do not have finalizer methods.

close(). // The second ? is for ENAME // Do the insertion pstmt. } finally{ if(pstmt!=null) // Close the statement pstmt.setString (2.setString (2. // Add LESLIE as employee number 1500 pstmt. Making Changes to the Database DML Operations To perform DML (Data Manipulation Language) operations. // The second ? is for ENAME // Do the insertion pstmt. you can create either a Statement object or a PreparedStatement object. you should put close statements in a finally clause. Note: Typically.Basic Steps in JDBC stmt.close(). When you close a Statement object that a given Connection object creates. try{ pstmt = conn.execute (). // Prepare to insert new names in the EMP table PreparedStatement pstmt = null. 1500). ENAME) values (?. "LESLIE"). } Getting Started 2-11 . // The first ? is for EMPNO pstmt. The prepareStatement method of the JDBC Connection object lets you define a statement that takes variable bind parameters and returns a JDBC PreparedStatement object with your statement definition. // The first ? is for EMPNO pstmt. // Add MARSHA as employee number 507 pstmt. "MARSHA"). such as INSERT or UPDATE operations. 507). ?)"). the connection itself remains open.setInt (1. See Also: "The setObject and setOracleObject Methods" on page 11-11 and "Other setXXX Methods" on page 11-11 The following example shows how to use a prepared statement to run INSERT operations that add two rows to the EMP table.execute (). PreparedStatement objects enable you to run a statement with varying sets of input parameters.setInt (1. Use the setXXX methods on the PreparedStatement object to bind data to the prepared statement to be sent to the database.prepareStatement ("insert into EMP (EMPNO.

try{ query="create table EMP " + "(EMPNO int. ?)"). ENAME) values (?. Statement stmt=null.executeUpdate(query). "MARSHA").prepareStatement("truncate table EMP").setString (2.prepareStatement("truncate table EMP").execute ().createStatement(). tstmt. then.close().executeUpdate(). } finally{ //close the Statement object stmt. The following example shows how to create a table in the database using a Statement object. // The second ? is for ENAME // Do the insertion pstmt. // Add LESLIE as employee number 1500 pstmt. "LESLIE"). tstmt = conn.close(). try{ pstmt = conn. The following example shows how to prepare your DDL statements before any reexecution: // PreparedStatement pstmt = null. stmt = conn. tstmt = conn. 507). " + "ENAME varchar(50))". // The second ? is for ENAME // Do the insertion pstmt. tstmt. stmt. PreparedStatement tstmt = null. } finally{ if(pstmt!=null) // Close the statement pstmt.prepareStatement ("insert into EMP (EMPNO. 1500). // The first ? is for EMPNO pstmt.setInt (1. } If your code involves reexecuting a DDL operation.execute (). before reexecuting the statement.executeUpdate(). // Add MARSHA as employee number 507 pstmt. you can create either a Statement object or a PreparedStatement object. tstmt. //create table EMP with columns EMPNO and ENAME String query.setString (2.Basic Steps in JDBC DDL Operations To perform data definition language (DDL) operations.close().setInt (1. you must prepare it again. // The first ? is for EMPNO pstmt. } 2-12 Oracle Database JDBC Developer's Guide and Reference .

then an implicit COMMIT operation is run. If the auto-commit mode is disabled. and Processing the Results The steps in the preceding sections are illustrated in the following example. ■ Closing the Connection You must close the connection to the database after you have performed all the required operations and no longer require the connection. Querying. returning and processing the ResultSet object.close(). which uses the Oracle JDBC Thin driver to create a data source.commit(). then this implicit COMMIT will commit any pending DML operations that had not yet been explicitly committed or rolled back. and processes the result set. Any data definition language (DDL) operation always causes an implicit COMMIT. runs a query.sql. creates a Statement object. A COMMIT or ROLLBACK operation affects all DML statements run since the last COMMIT or ROLLBACK. then you must manually commit or roll back changes with the appropriate method call on the Connection object: conn. However. you should put close statements in a finally clause. you can disable auto-commit mode with the following method call on the Connection object: conn. connects to the database.ResultSet. as follows: conn. data manipulation language (DML) operations are committed automatically as soon as they are run.rollback(). Getting Started 2-13 . Note that the code for creating the Statement object.Connection. If you disable the auto-commit mode. Sample: Connecting. Note: Typically. and Processing the Results Committing Changes By default. import java. This is known as the auto-commit mode. You can close the connection by using the close method of the Connection object. Querying.Sample: Connecting. Note: ■ If the auto-commit mode is disabled and you close the connection without explicitly committing or rolling back your last changes. or: conn.setAutoCommit(false). and closing the statement and connection uses the standard JDBC API. import java.sql. running the query. See Also: "Disabling Auto-Commit Mode" on page B-1.

if(stmt!=null) stmt.sql.Stored Procedure Calls in JDBC Programs import java.setPassword("tiger").Statement.pool. } } } If you want to adapt the code for the OCI driver.setURL("jdbc:oracle:thin:@//myhost:1521/orcl").setURL("jdbc:oracle:oci:@MyHostString"). import oracle.out. // Print the name out while (rset. Connection conn = null.close(). if(conn!=null) conn. conn = ods. ods.close(). Stored Procedure Calls in JDBC Programs This section describes how Oracle JDBC drivers support the following kinds of stored procedures: ■ ■ PL/SQL Stored Procedures Java Stored Procedures 2-14 Oracle Database JDBC Developer's Guide and Reference . ods.getConnection().getString (1)). rset = stmt.OracleDataSource. try { // Query the employee names stmt = conn.createStatement (). ods.ORA file.jdbc. } //Close the result set. ResultSet rset = null. where.next ()) System. MyHostString is an entry in the TNSNAMES.println (rset.setURL method with the following: ods.setUser("scott"). Statement stmt = null. // Create DataSource and connect to the local database ods = new OracleDataSource(). class JdbcTest { public static void main (String args []) throws SQLException { OracleDataSource ods = null. then replace the call to the OracleDataSource.close(). and the connection finally{ if(rset!=null) rset.executeQuery ("SELECT ename FROM emp"). statement.

setString(2. end. // stored func As an example of using the Oracle syntax." ) . you have written call specifications to publish them to the Oracle data dictionary. cs.setUser("scott"). CallableStatement cs = conn.Types. here is a PL/SQL code snippet that creates a stored function. They support PL/SQL block syntax and most of SQL92 escape syntax. Getting Started 2-15 ."). Processing SQL Exceptions To handle error conditions.prepareCall ( "{call proc (?.?). Additional run-time information can also be appended.sql. presuming they have been properly published. Oracle JDBC drivers throw SQL exceptions.prepareCall ( "{? = call func (?. The function invocation in your JDBC program should look like the following: OracleDataSource ods = new OracleDataSource().executeUpdate(). // stored func // PL/SQL block syntax CallableStatement cs3 = conn.prepareCall ( "begin ? := func(?." ) . end.?)}" ) .Processing SQL Exceptions PL/SQL Stored Procedures Oracle JDBC drivers support the processing of PL/SQL stored procedures and anonymous blocks.prepareCall ("begin ? := foo(?).setPassword("tiger").prepareCall ( "begin proc (?. cs. Java Stored Procedures You can use JDBC to call Java stored procedures through the SQL and PL/SQL engines. cs. String result = cs.getString(1).setURL("jdbc:oracle:oci:@<hoststring>"). end.?)}" ) . end. The syntax for calling Java stored procedures is the same as the syntax for calling PL/SQL stored procedures.SQLException class or its subclass. Connection conn = ods. That is. // stored proc CallableStatement cs2 = conn.getConnection(). Applications can call Java stored procedures using the Native Java Interface for direct invocation of static Java methods. Errors can originate either in the JDBC driver or in the database itself.registerOutParameter(1.CHAR). "aa"). The PL/SQL function gets a character sequence and concatenates a suffix to it: create or replace function foo (val1 char) return char as begin return val1 || 'suffix'.?). producing instances of the java. // stored proc CallableStatement cs4 = conn. Resulting messages describe the error and identify the method that threw the error. ods. ods. ods. The following PL/SQL calls would work with any Oracle JDBC driver: // SQL92 syntax CallableStatement cs1 = conn.

SQLException. retrieving the SQL state. } To illustrate how the JDBC drivers handle errors. try { <some code> } catch(SQLException e) { e. assume the following code uses an incorrect column index: // Iterate through the result and print the employee names // of the code try { 2-16 Oracle Database JDBC Developer's Guide and Reference . Basic exception handling can include retrieving the error message. The following code fragment illustrates how you can catch SQL exceptions and print the stack trace. This method prints the stack trace of the throwable object to the standard error stream.getMessage()).println("exception: " + e. The SQLException class includes functionality to retrieve all of this information. You can also specify a java. a set of subclasses of the SQLException exception is introduced to identify the different categories of errors. However.Processing SQL Exceptions JDBC 3. "JDBC Error Messages" Oracle Database Error Messages Retrieving Error Information You can retrieve basic error information with the following methods of the SQLException class: ■ ■ ■ getMessage getErrorCode getSQLState The following example prints output from a getMessage method call: catch(SQLException e) { System. } This would print the output. See Also: ■ ■ Appendix C. in JDBC 4.out. Therefore. such as the following.io. when available. there are large categories of errors and it is useful to distinguish them.PrintWriter object for output.printStackTrace (). for an error originating in the JDBC driver: exception: Invalid column type Note: Error message text is available in alternative languages and character sets supported by Oracle. and printing the stack trace.0. retrieving the error code.io. To know more about this feature.0 Standard on page 3-6. Printing the Stack Trace The SQLException class provides the printStackTrace() method for printing a stack trace. see Support for JDBC 4.PrintStream object or java.0 defines only a single exception.

running the program would produce the following error text: java.println (rset.driver.jdbc.jdbc.sql.next ()) System.throwSqlException(DatabaseError.OracleResultSetImpl.driver.jdbc.java:1556) at Employee.driver.getString (5)).java:146) at oracle.SQLException: Invalid column index at oracle.printStackTrace ().getDate(OracleResultSetImpl.java:41) Getting Started 2-17 . } // incorrect column index Assuming the column index is incorrect.DatabaseError.throwSqlException(DatabaseError.java:208) at oracle.DatabaseError.java:112) at oracle.main(Employee. } catch(SQLException e) { e.Processing SQL Exceptions while (rset.throwSqlException(DatabaseError.jdbc.out.driver.DatabaseError.

Processing SQL Exceptions 2-18 Oracle Database JDBC Developer's Guide and Reference .

"Features Specific to JDBC Thin" Chapter 6. Part II contains the following chapters: ■ ■ ■ ■ ■ Chapter 3. It also includes chapters that cover features specific to JDBC Thin driver. "Oracle Extensions" Chapter 5.Part II Oracle JDBC This part includes chapters that discuss the different Java Database Connectivity (JDBC) versions that Oracle Database 11g supports. "Features Specific to JDBC OCI Driver" Chapter 7. JDBC Oracle Call Interface (OCI) driver. and the server-side internal driver. "Server-Side Internal Driver" . "JDBC Standards Support" Chapter 4.

.

The package oracle. such as features of the JDBC 2. These features are provided through the oracle. This is handled through the standard java.jdbc and oracle.jdbc2 has been removed.0 standards.5 and 1. This chapter discusses the JDBC standards support in Oracle JDBC drivers.x and later. under JDK 1.0 Standard Support for JDBC 2. including data sources.5 are no longer supported. This is handled through standard objects.6.0 Standard Support for JDBC 3.sql package. JDBC Standards Support 3-1 . It contains the following sections: ■ ■ ■ Support for JDBC 2. ■ ■ This section covers the following topics: ■ ■ ■ ■ Data Type Support Standard Feature Support Extended Feature Support Standard versus Oracle Performance Enhancement APIs Note: Versions of JDK earlier than 1. also known as the standard extension application programming interface (API).0 Standard Standard JDBC 2.2. Oracle JDBC drivers have been enhanced to provide support for the JDBC 4. such as result set enhancements and update batching.0 features are supported by JDK 1. arrays. such as Connection. connection pooling.sql packages. There are three areas to consider: ■ Support for data types. ResultSet. In Oracle Database 11g Release 1 (11. These packages support Java Development Kit (JDK) releases 1. and distributed transactions.2 and later versions. such as objects. and PreparedStatement.0 optional package. and large objects (LOBs). Support for standard features. Support for extended features.1).3 JDBC Standards Support The Oracle Java Database Connectivity (JDBC) drivers support different versions of the JDBC standard features.0 Standard Support for JDBC 4.

sql package and classes that implement its interfaces are included in the Java Archive (JAR) files packaged with Oracle Database.0 LOB Interface Methods" on page 3-5. such as scrollable result sets. are supported in a JDK 1.jdbc. global transactions LOB modification Named SQL parameters See "JDBC 3.OracleCallableStatement" on page 4-22 and "Interface oracle. JDBC 2. you have the option of using the standard model or the Oracle model.0 Functionality Comments and References See "Transaction Savepoints" on page 3-3 for information. Table 3–1 lists the JDBC 3.0 functionality through implementation of interfaces in the standard java.5 and JDK 1.sql package. Standard versus Oracle Performance Enhancement APIs The following performance enhancements are available under JDBC 2.0 optional package.0 features are supported by JDK 1. are supported through methods specified by standard JDBC 2. See Chapter 20.Support for JDBC 3.0.jar.5 environment.jdbc. which includes standard JDBC 2. Extended Feature Support Features of the JDBC 2.0 features. These interfaces are implemented as appropriate by classes in the oracle.0 interfaces. Standard Feature Support In a JDK 1.OraclePreparedStatement" on page 4-22. 3-2 Oracle Database JDBC Developer's Guide and Reference . try to mix usage of the standard model and Oracle model within a single application for either of these features. See "Interface oracle. however.0 Standard Standard JDBC 3. Table 3–1 Feature Transaction savepoints Statement caching Key Areas of JDBC 3. Do not. Oracle recommends that you use the JDBC standard model whenever possible. Switching between local and See "Switching Between Global and Local Transactions" on page 28-4.0 features supported by Oracle Database 11g Release 1 (11. and update batching. Reuse of prepared statements by connection pools.6.sql and oracle. which had previously been available only as Oracle extensions: ■ ■ Update batching Fetch size or row prefetching In each case. and distributed transactions.x or later environment.0 Standard Data Type Support Oracle JDBC fully supports JDK 1.jdbc packages. including data sources.1) and gives references to a detailed discussion of each feature. "Statement and Result Set Caching". The standard javax.2. using the JDBC classes in ojdbc5.4 and later versions. updatable result sets. See Also: ■ ■ "Update Batching" on page 23-1 "Fetch Size" on page 17-15 Support for JDBC 3. connection pooling.

Creating a Savepoint You create a savepoint using the Connection. A savepoint is either named or unnamed.setSavepoint method.Support for JDBC 3. Rolling Back to a Savepoint You roll back to a savepoint using the Connection. You retrieve a name using the getSavepointName method. You specify the name of a savepoint by supplying a string to the setSavepoint method. but code operating within the transaction can preserve partial states. which offer finer demarcation within transactions.sql. JDBC Standards Support 3-3 . then the savepoint is assigned an integer ID. Note: Savepoints are supported for local transactions only. "JDBC RowSets" See "Retrieval of Auto-Generated Keys" on page 3-4 See "Result Set Holdability" on page 3-6 The following JDBC 3.0 Standard Table 3–1 (Cont.0 LOB Interface Methods Result Set Holdability Transaction Savepoints The JDBC 3. If you do not specify a name.rollback(Savepoint svpt) method. which returns a java.0 Functionality Feature RowSets Retrieving auto-generated keys Result set holdability Comments and References See Chapter 18.Savepoint instance. Note: Attempting to retrieve a name from an unnamed savepoint or attempting to retrieve an ID from a named savepoint throws a SQLException exception. If you try to roll back to a savepoint that has been released. then a SQLException exception is thrown.) Key Areas of JDBC 3. Savepoints relax the atomicity property of transactions. A transaction with a savepoint is atomic in the sense that it appears to be a single unit outside the context of the transaction.0 specification supports savepoints. Applications can set a savepoint within a transaction and then roll back all work done after the savepoint. Specifying a savepoint within a global transaction causes a SQLException exception to be thrown. You retrieve an ID using the getSavepointId method.0 features supported by Oracle JDBC drivers are covered in this section: ■ ■ ■ ■ Transaction Savepoints Retrieval of Auto-Generated Keys JDBC 3.

■ ■ Retrieval of Auto-Generated Keys Many database systems automatically generate a unique key field when a row is inserted. then Oracle JDBC drivers cannot identify which columns need to be retrieved. When a column name or column index array is used. Oracle Database provides the same functionality with the help of sequences and triggers. Other data manipulation language (DML) statements are processed. In JDBC 3.OracleDatabaseMetaData. However. When a transaction is committed or rolled back. you must consider the following: ■ After a savepoint has been released. 3-4 Oracle Database JDBC Developer's Guide and Reference . When the integer flag is used to indicate that auto-generated keys are to be returned. when the Statement. this feature is supported only when INSERT statements are processed.Support for JDBC 3.sql. the ROWID pseudo column is returned as key.releaseSavepoint(Savepoint svpt) method.0 Standard Releasing a Savepoint You remove a savepoint using the Connection. java. However.sql. Rolling a transaction back to a savepoint automatically releases and makes invalid any savepoints created after the savepoint in question. attempting to reference it in a rollback operation will cause a SQLException exception to be thrown.supportsSavepoints method. JDBC 3. false otherwise. which returns true if savepoints are available. but without retrieving auto-generated keys.Statement These interfaces provide methods that support retrieval of auto-generated keys.RETURN_GENERATED_KEYS integer flag is used. the following interfaces are enhanced to support the retrieval of auto-generated keys feature: ■ ■ ■ java.0 introduces the retrieval of auto-generated keys feature that enables you to retrieve such generated values. all savepoints created in that transaction are automatically released and become invalid. The ROWID can be then fetched from the ResultSet object and can be used to retrieve other columns.jdbc.DatabaseMetaData java. Oracle JDBC drivers cannot identify these columns.sql. Checking Savepoint Support You query if savepoints are supported by your database by calling the oracle.0.Connection java.sql. Note: The Oracle server-side internal driver does not support the retrieval of auto-generated keys feature.Statement If key columns are not explicitly indicated. Savepoint Notes When using savepoints. Oracle JDBC drivers can identify which columns contain auto-generated keys that you want to retrieve.

int offset. s). int len) setBinaryStream(long pos) truncate(long len) Oracle Proprietary Method putBytes(long pos. is created to generate values for the ORDER_ID column starting from 1000 and incrementing by 1 each time the sequence is processed to generate the next value. byte [] bytes. they are subjected to the following limitations: ■ ■ You cannot combine auto-generated keys with batch update. byte[] bytes) setBytes(long pos. DESCRIPTION) VALUES (SEQ01.0 Standard Method setBytes(long pos.0 standard methods.prepareStatement("INSERT INTO ORDERS (ORDER_ID. '\u5185'. ISBN. SEQ01.0 LOB Interface Methods Table 3–2 and Table 3–3 show the conversions between Oracle proprietary methods and JDBC 3. You need to access the ResultSet object returned from getGeneratedKeys method by position only and no bind variable names should be used as columns in the ResultSet object.executeUpdate(). ?)".getGeneratedKeys(). pstmt.. CUSTOMER_ID NUMBER. 966431502. byte [] bytes) putBytes(long pos. Limitations Auto-generated keys are implemented using the DML returning clause.. * * CREATE TABLE ORDERS (ORDER_ID NUMBER. byte[] bytes. pstmt.NEXTVAL.Support for JDBC 3. Table 3–2 BLOB Method Equivalents JDBC 3. int length) getBinaryOutputStream(long pos) trim (long len) JDBC Standards Support 3-5 .0 Standard Sample Code The following code illustrates retrieval of auto-generated keys: /** SQL statements for creating an ORDERS table and a sequence for generating the * ORDER_ID. cols). ResultSet rset = pstmt. In the preceding example. CUSTOMER_ID.. // Create a PreparedStatement for inserting a row into the ORDERS table. ISBN NUMBER. "DESCRIPTION"}. 'b'}. * DESCRIPTION NCHAR(5)) * * CREATE SEQUENCE SEQ01 INCREMENT BY 1 START WITH 1000 */ .setNString(1. 101. String cols[] = {"ORDER_ID". An OraclePreparedStatement object is created to insert a row in to the ORDERS table. OraclePreparedStatement pstmt = (OraclePreparedStatement) conn. JDBC 3. a sequence. char c[] = {'a'. .. String s = new String(c). So.

Note: You need to have the ojdbc6*.Support for JDBC 4. when a commit operation is performed.1) JDBC drivers are the following: ■ ■ ■ ■ ■ Wrapper Pattern Support Enhanced Exception Hierarchy and SQLException The RowId Data Type LOB Creation National Language Character Set Support This document provides only an overview of these new features. see "Java 2 Platform. Oracle Database 11g Release 1 (11.0 standard support is provided by JDK 1. The commit operation could be either implicit or explicit. Oracle Database supports only HOLD_CURSORS_OVER_COMMIT. String str. Support for JDBC 4.com/javase/6/docs/ Wrapper Pattern Support Wrapper pattern is a common coding pattern used in Java applications to provide extensions beyond the traditional JDBC API that are specific to a data source. Any attempt to change holdability will throw a SQLException exception.0 standard support. String str) not applicable getAsciiOutputStream(long pos) getCharacterOutputStream(long pos) trim (long len) Result Set Holdability Result set holdability was introduced since JDBC 3.0 Standard The JDBC 4.sun.0 Standard Method setString(long pos. You may need to use these extensions to access the resources that are wrapped as proxy class instances representing the actual resources.1) JDBC drivers provide support for the JDBC 4. For detailed information about these features. Some of the new features available in Oracle Database 11g Release 1 (11. Therefore. This feature enables applications to decide whether the ResultSet objects should be open or closed. Standard Edition (JSE) 6. it is the default value for Oracle JDBC drivers. JDBC 4.0 introduces the Wrapper 3-6 Oracle Database JDBC Developer's Guide and Reference . int len) setAsciiStream(long pos) setCharacterStream(long pos) truncate(long len) Oracle Proprietary Method putString(long pos.6 and later versions.0.0 Standard Table 3–3 CLOB Method Equivalents JDBC 3. String str) setString(long pos.0 standard. int offset.0 specification" at http://java.jar in your classpath environment variable in order to have JDBC 4.

html Enhanced Exception Hierarchy and SQLException JDBC 3. ■ The other JDBC 4. You can retrieve a RowId value using the getter methods defined in the ResultSet and CallableStatement interfaces.0 defines only a single exception.0 interfaces. all implement this interface. including timeouts.Support for JDBC 4. ResultSet. A RowId object may also be valid for the following: ■ ■ ■ The duration of the transaction in which it is created The duration of the session in which it is created An undefined duration where by it is valid forever The lifetime of the RowId object can be determined by calling the DatabaseMetaData. Clob. except those that represent SQL data. The created large objects (LOBs) do not contain any data. Permanent errors are a result of the correct operation of the system and will always occur. A RowId object is valid until the identified row is not deleted. public <T> T unwrap(Class<T> iface) throws SQLException. The interface provides the createBlob. and the metadata interfaces.sql.RowId data type to represent SQL ROWID values. of some part of the system and may not reoccur. Statement and its subtypes. The Wrapper interface provides the following two methods: ■ public boolean isWrapperFor(Class<?> iface) throws SQLException. New exceptions have been added to represent transient and permanent errors and the different categories of these errors. To retrieve the data from these JDBC Standards Support 3-7 .com/javase/6/docs/api/java/sql/Wrapp er. and NClob objects. This feature provides subclasses of the SQLException class to identify the different categories of errors. These include Connection. to permit direct access to the resource delegates. createClob. Transient errors are the result of failures.sun. The primary distinction is between permanent errors and transient errors. LOB Creation In JDBC 4. CLOB.0 Standard interface that describes a standard mechanism to access these wrapped resources represented by their proxy. and createNClob methods that enable you to create Blob.0.getRowIdLifetime method. and NCLOB objects. See Also: http://java. The RowId Data Type JDBC 4. You can add data in these objects by calling the appropriate setXXX methods.0 provides the java. the Connection interface has been enhanced to provide support for the creation of BLOB. Also. the SQLException class and its subclasses have been enhanced to provide support for the J2SE chained exception functionality. You can also use a RowId value in a parameterized PreparedStatement to set a parameter with a RowId object or in an updatable result set to update a column with a specific RowId value. However. there are large categories of errors and it is useful to distinguish them. SQLException.

.Support for JDBC 4. This may result in unwarranted use of memory during a long running transaction. You can also pass LOBs as input parameters to a PreparedStatement object using the setBlob. Connection con = DriverManager. and updateNClob methods to update a column value in an updatable result set. These types are similar to the CHAR. LONGVARCHAR. LOBs remain valid for at least the duration of the transaction in which they are created. . // Add data to the BLOB object. props). val).. you can call the getBlob. setClob.. You can use the updateBlob. except that the values are encoded using the national character set. LONGNVARCHAR.free(). You can release LOBs by calling their free method. 100).createClob(). . Blob aBlob = con.. NVARCHAR.. updateClob.0 introduces the NCHAR..createBlob(). as follows: . getClob. 3-8 Oracle Database JDBC Developer's Guide and Reference .getConnection(url. and setNClob methods. National Language Character Set Support JDBC 4. VARCHAR. and NCLOB JDBC types to access the national character set types.setString(1.0 Standard objects. . and getNClob methods defined in the ResultSet and CallableStatement interfaces. The following code snippet illustrates how to retrieve 100 bytes of data from a BLOB object starting at offset 200: . You can either retrieve the entire content or a part of the content from these objects... and CLOB types.. // Retrieve part of the data from the BLOB object.getBinaryStream(200.. aClob. Clob aClob = con. int numWritten = aClob. InputStream is = aBlob.

These extensions are provided through the following Java packages: ■ oracle. This chapter contains the following sections: ■ ■ ■ ■ ■ ■ ■ Overview of Oracle Extensions Features of the Oracle Extensions Oracle JDBC Packages Oracle Character Data Types Support Additional Oracle Type Extensions DML Returning Accessing PL/SQL Index-by Tables Note: This chapter focuses on type extensions.jdbc Provides interfaces to support database access and updates in Oracle type formats See Also: "Oracle JDBC Packages" on page 4-5 Oracle Extensions 4-1 . which are discussed in detail in Chapter 23. Compared to standard JDBC.sql Provides classes that represent SQL data in Oracle format ■ oracle. Overview of Oracle Extensions Beyond standard features. as opposed to performance extensions. "Performance Extensions". This chapter provides an overview of the classes and interfaces provided by Oracle that extend the JDBC standard implementation. enabling you to access and manipulate Oracle data types and use Oracle performance extensions.4 Oracle Extensions Oracle provides Java classes and interfaces that extend the Java Database Connectivity (JDBC) standard implementation. the Oracle extensions offer greater flexibility in manipulating the data. Oracle JDBC drivers provide Oracle-specific type extensions and performance extensions. It also describes some of the key support features of the extensions.

in the oracle. excluding a couple of desupported character sets. This is a known limitation while converting data from oracle. oracle.sql types are supported only for backward compatibility and their use is discouraged.sql types in your program: ■ For numeric type of data.lang. If the functionalities of your program is limited to reading data from one table and writing the same to another table. But. These include the following: ■ ■ ■ ■ ■ ■ Database Management Using JDBC Support for Oracle Data Types Support for Oracle Objects Support for Schema Naming DML Returning Accessing PL/SQL Index-by Tables Database Management Using JDBC Oracle Database 11g Release 1 (11.sql.sql types to standard Java types.String is always faster and represents the same character sets.sql package. the conversion to standard Java types does not guarantee to retain full precision due to limitations of the data conversion process.Features of the Oracle Extensions Features of the Oracle Extensions The Oracle extensions to JDBC include a number of features that enhance your ability to work with Oracle Databases. oracle. oracle.lang. the conversion to standard Java types can be dependent on the system settings and your program may not run as expected. For certain data types. if your program involves even a simple data manipulation opearation like compare or print. then for numeric and date data. Support for Oracle Data Types One of the features of the Oracle JDBC extensions is the type support in the oracle.CHAR is constructed from java.sql types are slightly faster as compared to standard Java types. oracle. ■ ■ ■ Note: Oracle strongly recommends you to use standard Java types and convert any existing oracle.1) introduces new JDBC methods. These new features have been discussed in details in "Database Management".CHAR is not an exact representation of the data in Oracle format. There is no advantage of using oracle. then standard Java types are faster. the Oracle JDBC drivers strive to maximize the performance of Java standard types.CHAR because java. You also have support for the Database Change Notification feature of Oracle Database. This package includes classes that are an exact representation of the data in Oracle format. Use the BigDecimal type to minimize any data loss issues.sql. when you use oracle. 4-2 Oracle Database JDBC Developer's Guide and Reference . startup and shutdown.sql type of data to standard Java types.sql.jdbc. Keep the following important points in mind. Internally.String.OracleConnection interface that enable you to start up and shut down an Oracle Database instance.

The ORAData interface works more easily and flexibly in conjunction with other features of the Oracle platform offerings using Java. in situations where portability is not a concern. a type map defines the correspondence between Oracle object data types and Java classes.SQLData interface or the Oracle extension oracle. you must consider the following: ■ ■ ■ ■ How to map between Oracle object data types and Java classes How to store Oracle object attributes in corresponding Java objects How to convert attribute data between SQL and Java formats How to access data Oracle objects can be mapped either to the weak java. For example. Type maps are objects that specify which Java class corresponds to each Oracle object data type.sql. Each interface specifies methods to convert data between SQL and Java. When you work with Oracle object data types in a Java application. For SQLData interface implementations. Oracle JDBC supports Oracle object data types. Oracle Extensions 4-3 . Note: Oracle recommends using the ORAData interface.Struct type or to strongly typed customized classes. Oracle JPublisher performs this task seamlessly with command-line options and can generate either SQLData or ORAData interface implementations. which must implement either the standard java.Features of the Oracle Extensions See Also: ■ ■ ■ Package oracle. JPublisher automatically defines getXXX methods of the custom Java classes.sql.sql on page 4-5 "Oracle Character Data Types Support" on page 4-10 "Additional Oracle Type Extensions" on page 4-13 Support for Oracle Objects Oracle JDBC supports the use of structured objects in the database. and an employeenumber attribute (integer). where an object data type is a user-defined type with nested attributes. These strong types are referred to as custom Java classes. which retrieve data into your Java application. Note: The ORAData interface has replaced the CustomDatum interface.sql. instead of the SQLData interface. Oracle JDBC uses these type maps to determine which Java class to instantiate and populate when it retrieves Oracle object data from a result set. a lastname attribute (character string). The latter interface is desupported in Oracle Database release 11.ORAData interface. where each Employee object has a firstname attribute (character string).1. a user application could define an Employee object type. Oracle recommends the use of the Oracle JPublisher utility to create custom Java classes to correspond to your Oracle objects.

you can specify only the type name.address is not within quotation marks. assume that user Scott creates a type called person.). if the SQL type name has a period in it. if Scott. the JDBC driver will not change the character case even if the object type name is within quotation marks. schema_name is the name of the schema and sql_type_name is the SQL type name of the object. However.EMPLOYEE. ■ ■ JDBC passes the object type name string to the database unchanged. This enables you to combine two SQL statements into one. "Working with Oracle Object Types" Oracle Database JPublisher User's Guide. In this case. such as CORPORATE. Support for Schema Naming Oracle object data type classes have the ability to accept and return fully qualified schema names. instead of specifying the fully qualified name if the object type name belongs to the current schema. that is. For example. without indicating a schema.Features of the Oracle Extensions See Also: ■ ■ Chapter 13. then the JDBC driver will pass the string to the database unchanged. schema_name and sql_type_name are separated by a period (. use its fully qualified name. if there is white space between characters in the type name string. That is. Scott may want to skip the schema name and pass in person. then the JDBC driver will not remove the white space. then the JDBC driver takes the current schema as default. If no period is found. Schema naming follows these rules: ■ Both the schema name and the type name may or may not be within quotation marks. This also explains why you must put the type name within quotation marks if the type name has a dot in it. A fully qualified schema name has this syntax: {[schema_name]. To specify an object type in JDBC.}[sql_type_name] Where. The JDBC driver looks for the first period in the object name that is not within quotation marks and uses the string before the period as the schema name and the string following the period as the type name. if person. the current schema.PersonType is passed to the JDBC driver as an object type name.address and then wants to use it in his session. Both the Oracle JDBC Oracle Call Interface (OCI) driver and the Oracle JDBC Thin driver support DML returning. the type name must be quoted. That is. See Also: "DML Returning" on page 4-26 4-4 Oracle Database JDBC Developer's Guide and Reference . DML Returning Oracle Database supports the use of the RETURNING clause with data manipulation language (DML) statements. For example.address to the JDBC driver. As another example. It is not necessary to enter a schema name if the type name is in the current naming space. then the period will be detected and the JDBC driver will mistakenly interpret person as the schema name and address as the type name.

Array BLOB (binary large objects) implements java.sql package supports direct access to data in SQL format.CLOB Oracle Data Type Classes Oracle SQL Types and Interfaces Implemented STRUCT (objects) implements java. TIMESTAMPTZ.sql data type classes and their corresponding Oracle SQL types.sql. Note: Classes of the oracle.sql.sql.0-compliant data types. as well as extending the oracle.Datum class.sql. This package consists primarily of classes that provide Java mappings to SQL data types and their support classes.STRUCT oracle. "Accessing PL/SQL Index-by Tables" on page 4-28 See Also: Oracle JDBC Packages This section describes the following Java packages. implement standard JDBC 2.sql package. the classes act as Java containers for SQL data. a superclass that encapsulates functionality common to all the data types.sql.0 interfaces in the java.* are provided primarily for backward compatibility or for support of a few Oracle specific features such as OPAQUE.sql.jdbc Package oracle. OraData. The types in the package oracle. Some of the classes are for JDBC 2. which support the Oracle JDBC extensions: ■ ■ Package oracle.sql.sql. These classes. Table 4–1 Java Class oracle.Ref VARRAY or nested table (collections) implements java.REF oracle.Struct REF (object references) implements java.sql. as Table 4–1 indicates.* data type classes extends oracle.Clob Oracle Extensions 4-5 .sql.sql.Blob SQL CLOB (character large objects) and globalization support NCLOB data types both implement java.Oracle JDBC Packages Accessing PL/SQL Index-by Tables Oracle JDBC drivers enable JDBC applications to make PL/SQL calls with index-by table parameters.sql The oracle. Oracle recommends the use of standard JDBC types or Java types whenever possible.sql.ARRAY oracle. and so on. Each of the oracle. Essentially.sql. Oracle JDBC drivers support PL/SQL index-by tables of scalar data types Note: Index-by tables of PL/SQL records are not supported.BLOB oracle.sql.sql Package oracle.Datum.sql Package Table 4–1 lists the oracle.

sql. It describes the SQL type of the array.sql. the following: ■ Data storage as Java byte arrays for SQL data 4-6 Oracle Database JDBC Developer's Guide and Reference .NCLOB oracle.NClob BFILE (external files) CHAR.sql. primarily for use with objects and collections: ■ oracle. ■ oracle.ORAData and oracle. In addition to the data type classes.sql.sql package includes the following support classes and interfaces.) Oracle Data Type Classes Java Class oracle. Use standard JDBC functionality for these types.ROWID oracle. which you can use as a default mapping to Oracle objects in the database.ArrayDescriptor This class is used in constructing oracle.Oracle JDBC Packages Table 4–1 (Cont.* classes.sql.sql.TIMESTAMPTZ oracle. NCHAR.ARRAY objects.sql.OPAQUE oracle.* Data Type Support Each of the Oracle data type classes provides. the oracle. ■ oracle.TypeDescriptor This class is used to represent transient and persistent SQL types in Java.sql.sql.OpaqueDescriptor This class is used to obtain the metadata for an instance of the oracle.RowId OPAQUE ANYDATA Note: The LONG and LONG RAW SQL types and REF CURSOR type category have no oracle.BFILE oracle.sql.sql.sql.sql. Use the getCursor method for REF CURSOR types.sql.OPAQUE class.sql.sql.TIMESTAMP oracle.STRUCT objects. ■ oracle.TIMESTAMPLTZ oracle. among other things. ■ oracle.sql.sql.ORADataFactory These interfaces are used in Java classes implementing the Oracle ORAData scenario of Oracle object support.sql.sql. General oracle. For example.sql. NVARCHAR2 DATE TIMESTAMP TIMESTAMP WITH TIME ZONE TIMESTAMP WITH LOCAL TIME ZONE NUMBER RAW ROWID (row identifiers) implements java.NUMBER oracle.sql.StructDescriptor This class is used in constructing oracle.sql. VARCHAR2.sql.sql.ANYDATA Oracle SQL Types and Interfaces Implemented NCLOB implements java.CHAR oracle. retrieve LONG or LONG RAW data as input streams using the standard JDBC result set and callable statement methods getBinaryStream and getCharacterStream.RAW oracle.DATE oracle.

sql.sql.lang. it is usually desirable to define a custom mapping between SQL and Java. No translation is performed. if you use the getOracleAttributes method.sql. booleanValue.sql. The STRUCT class implements the standard JDBC 2.Struct interface and extends the oracle. if you use a SQLData custom Java class. getXXX and setXXX. It is the value returned by the Struct. If you want to create a STRUCT object. ■ Appropriate xxxValue methods to convert SQL data to Java type. which returns the SQL data as a byte array A toJdbc() method that converts the data into an object of a corresponding Java class as defined in the JDBC specification The JDBC driver does not convert Oracle-specific data types that are not part of the JDBC specification.* format: ■ Materializing oracle. then the mapping must be defined in a type map. Object[] attributes) throws SQLException The parameters in this signature are as follows: ■ The typeName parameter is the SQL type name of the SQL structured type to which the STRUCT object maps. ■ You can materialize attributes of a STRUCT object as oracle. ■ Overview of Class oracle. for the functionality of the data type. It contains the SQL type name of the Oracle object and an array of oracle.STRUCT For any given Oracle object type.* format.sql. or as java. then use the createStruct method of the oracle. dateValue.sql.OracleConnection interface. such as methods in the large object (LOB) classes that get the data as a stream and methods in the REF class that get and set object data through the object reference.sql. then data from the object type will be materialized in Java in an instance of the oracle.sql. as appropriate. For example. and bigDecimalValue Additional conversion methods. ■ Oracle Extensions 4-7 .* objects gives you the following advantages of the oracle.Datum class. If you choose not to define a mapping. For example. This is useful if you want to access data but not necessarily display it. Materializing the attributes as oracle. however. intValue.sql.getSQLTypeName method.0 java.Datum[] objects.Oracle JDBC Packages ■ ■ A getBytes() method. The typeName is the name of a user-defined type that has been defined for this database. A STRUCT object is a Java representation of the raw bytes of an Oracle object.STRUCT data in oracle.* format completely preserves data by maintaining it in SQL format.Datum objects that hold the attribute values in SQL format. if you use the getAttributes method.sql.STRUCT class. The driver returns the object in the corresponding oracle. The attributes parameter specifies the attributes that populate the returned object. such as BFILE.jdbc. The signature of this factory method for creating STRUCT objects is as follows: Struct createStruct (String typeName. stringValue. It allows complete flexibility in how your Java application unpacks data.sql.Object[] objects.

Ref interface.* type appropriate for the given attribute. either VARRAYs or nested tables.sql.Datum class. Nested objects in the values array of a STRUCT object are materialized by the JDBC driver as instances of STRUCT. the database table stores a locator that points to the location of the actual data.sql.* type as desired. ■ Overview of Class oracle. as with all oracle. although of the generic Datum type.CLOB class.Datum. character large objects (CLOBs). But the REF class also includes methods to retrieve and pass the object data. ■ 4-8 Oracle Database JDBC Developer's Guide and Reference . You can cast the element to the appropriate oracle. This class.sql.* data type classes.ARRAY class extends the oracle.sql. perhaps to insert into the database. CLOBs point to large character data items and are supported by the oracle. a CHAR data attribute within the STRUCT is materialized as oracle.0 java.BLOB. "Using Oracle Object References". To use it as CHAR data.sql.sql.ARRAY The oracle. The oracle. you can use the createARRAY method of the OracleConnection interface to create an ARRAY object to pass it to a prepared statement or callable statement.ARRAY class supports Oracle collections. actually contain data associated with the relevant oracle. However.BFILE Binary large objects (BLOBs).Datum class and implements the standard JDBC 2. and binary files (BFILEs) are for data items that are too large to store directly in a database table.REF class is the generic class that supports Oracle object references.sql. This does not materialize the object itself.Oracle JDBC Packages Note: ■ Elements of the array.CLOB.Array interface. You can use the setARRAY method of the OraclePreparedStatement or OracleCallableStatement interface to pass an ARRAY as an input parameter to a prepared statement.BLOB class.CHAR. selecting an object reference retrieves only a pointer to an object. then the JDBC driver materializes it as an object of the ARRAY class.sql. is a subclass of the oracle. For example.REF The oracle.sql. The REF class has methods to retrieve and pass object references. See Also: "Overview of Collection Functionality" on page 16-3 Overview of Classes oracle.sql.sql. Instead.sql. you must cast it to oracle.sql. It implements the standard JDBC 2.sql.sql.0 java. The oracle. Similarly. You can only retrieve existing REF objects from the database. The structure of the data is equivalent in either case. oracle.sql.sql. oracle. You cannot create REF objects in your JDBC application. Overview of Class oracle. If you select either a VARRAY or a nested table from the database. See Also: Chapter 15.sql.sql.sql package supports these data types in several ways: ■ BLOBs point to large unstructured binary data items and are supported by the oracle.

sql.sql. Time zones are specified by using the java.TIMESTAMPTZ. CLOB.NaN). or BFILE locator from the database using a standard SELECT statement.TIMESTAMP oracle. you can access a TIMESTAMP WITH TIME ZONE column as a DATE value. and supply conversions to and from the corresponding JDBC Java types. and oracle. oracle. BFiles are read-only.sql.Oracle JDBC Packages ■ BFILEs point to the content of external files (operating system files) and are supported by the oracle. which is a time zone name not defined in the JDK: TimeZone tz = TimeZone. GregorianCalendar gcal = new GregorianCalendar(tz).TIMESTAMPTZ oracle.NUMBER class.TIMESTAMP.NaN value is converted into an Oracle NUMBER using the oracle. System.NaN value or a Float. For instance.sql. and not the data.sql.out.Calendar class.getTimeZone to create time zone objects. The following code shows how the TimeZone and Calendar objects are created for US_PACIFIC.DATE.doubleValue()).NUMBER n = new oracle.println(n. and oracle.sql. tz.RAW These classes map to primitive SQL data types. The following Java classes represent the SQL date/time types: ■ ■ ■ oracle. which are a part of standard JDBC.sql.sql. // throws NullPointerException Classes oracle. The Oracle time zone data types support more time zone names than does the JDK.TIMESTAMPLTZ The JDBC drivers support the following date/time data types: ■ ■ ■ TIMESTAMP (TIMESTAMP) TIMESTAMP WITH TIME ZONE (TIMESTAMPTZ) TIMESTAMP WITH LOCAL TIME ZONE (TIMESTAMPLTZ) The JDBC drivers allow conversions between DATE and date/time data types. oracle. Note: Do not use TimeZone. Because Java Double and Float NaN values do not have an equivalent Oracle NUMBER representation.sql. See Also: Chapter 14. Additional steps are necessary to retrieve the data. a NullPointerException is thrown whenever a Double.setID("US_PACIFIC"). "Working with LOBs and BFILEs".NUMBER. The JDBC drivers support the most popular time zone names used in the industry as well as most of the time zone names defined in the JDK.sql.util.BFILE class.NUMBER(Double.sql.sql. For example. you receive only the locator. the following code throws a NullPointerException: oracle. Classes oracle.setSessionTimeZone(String regionName) method to Oracle Extensions 4-9 .TIMESTAMPLTZ Before accessing TIMESTAMP WITH LOCAL TIME ZONE data. However.getDefault().sql. call the OracleConnection. You can select a BLOB.

Package oracle. the setUnicodeStream and getUnicodeStream methods are not supported for NCHAR data type access. The SQL NCHAR data types include NCHAR. there are no separate.CHAR SQL CHAR Data Types The SQL CHAR data types include CHAR. The character set of the database is established when you create the database. Class oracle. JDBC uses the same classes and methods to access SQL NCHAR data types that are used for the corresponding SQL CHAR data types.* classes: ■ ■ ■ SQL CHAR Data Types SQL NCHAR Data Types Class oracle. Note: Because the UnicodeStream class is deprecated in favor of the CharacterStream class.Oracle Character Data Types Support set the session time zone.jdbc package define the Oracle extensions to the interfaces in java. These extensions provide access to Oracle SQL-format data and other Oracle-specific functionality. Note: There is minimal support for the OPAQUE type. which never changes.sql. the JDBC driver sets the session time zone of the connection and saves the session time zone so that any TIMESTAMP WITH LOCAL TIME ZONE data accessed through JDBC can be adjusted using the session time zone. These data types allow you to store Unicode data in the database NCHAR character set encoding. including Oracle performance enhancements.jdbc Package" on page 4-19 Oracle Character Data Types Support Oracle character data types include the SQL CHAR and NCHAR data types. is established when you create the database.sql. VARCHAR2. The usage of SQL NCHAR data types is similar to that of the SQL CHAR data types. The OPAQUE type provides access only to the uninterrupted bytes of the instance.sql. The NCHAR character set. and NCLOB. and CLOB.OPAQUE The oracle.sql. See Also: "The oracle. When this method is called.sql. Therefore. The following sections describe how these data types can be accessed using the oracle. NVARCHAR2. Use the setCharacterStream method and the getCharacterStream method if you want to use stream access.jdbc The interfaces of the oracle. SQL NCHAR Data Types The SQL NCHAR data types were created for Globalization Support. These data types let you store character data in the database character set encoding scheme.OPAQUE class gives you the name and characteristics of the OPAQUE type and any attributes. 4-10 Oracle Database JDBC Developer's Guide and Reference .

jdbc.1).sql. Note: In versions of Oracle JDBC drivers prior to 10g release 1 (10.OraclePreparedStatement) conn.prepareStatement("insert into TEST values(?.sql. Without the Globalization Support character set information. When processing byte data from another source. myUnicodeString1).CHAR to convert the bytes to java. // NVARCHAR2 and NCLOB data types. there are no longer any such advantages.execute().sql.CharacterSet instance that represents the Globalization Support character set used to encode the data bytes.lang. // NVARCHAR2 column pstmt.CHAR. 1). // pstmt.CHAR. The only remaining use of the oracle.OraclePreparedStatement.OracleTypes class for SQL NCHAR data types. ?.CHAR class is to handle character data in the form of raw bytes encoded in an Oracle Globalization Support character set. Starting from Oracle Database 10g.sql. // NUMBER column pstmt. This class has two key attributes: Globalization Support character set and the character data.FORM_NCHAR should be used for all NCHAR. Class oracle. To convert an oracle. The Globalization Support character set defines the encoding of the character data.Oracle Character Data Types Support corresponding classes defined in the oracle.NUMBER // .CHAR The oracle.NVARCHAR2 // .OraclePreparedStatement pstmt = (oracle. // NCHAR column pstmt. corresponding constant defined in the oracle. ?)"). you can use an oracle.jdbc.CHAR class is used by Oracle JDBC in handling and converting character data.setNString(3.NCHAR // oracle.sql. Using the oracle. optimum performance is achieved using the java. there is no separate. All character data retrieved from Oracle Database should be accessed using the java.CHAR does not prevent conversions between the database character set and UCS2 character set. The oracle.String.sql.lang.SQL. It is a parameter that is always passed when a CHAR object is constructed.CHAR class is used for both SQL CHAR and SQL NCHAR data types. there were performance advantages to using the oracle. Oracle Extensions 4-11 . The following code shows how to access SQL NCHAR data: // // Table TEST has the following columns: // . In fact. // // oracle.lang.String. All Oracle JDBC drivers handle all character data in the Java UCS2 character set.setInt(1. myUnicodeString2).jdbc.sql package for SQL NCHAR data types.String class.sql. you must provide the data bytes and an oracle. Similarly.jdbc.sql.setNString(2. This class provides the Globalization Support functionality to convert character data. the data bytes in the CHAR object are meaningless.

■ ■ 4-12 Oracle Database JDBC Developer's Guide and Reference . or an object as input along with the CharacterSet object. The server recognizes the special value CharacterSet. In the case of a String.make method. mycharset). a byte array. For the client. For example: int oracleId = CharacterSet. For example: String mystring = "teststring". Each instance of this class represents one of the Globalization Support character sets that Oracle supports. or the bytes that represent the string. because the JDBC driver automatically creates CHAR objects as needed. 2. Create a CharacterSet object by calling the static CharacterSet.sql.DEFAULT_CHARSET as the database character set.. JDBC application code rarely needs to construct CHAR objects directly. Note: ■ ■ The CharacterSet object cannot be a null value. CHAR mychar = new CHAR(teststring. // this is character set ID.CHAR Object Follow these general steps to construct a CHAR object: 1.. A CharacterSet instance encapsulates methods and attributes of the character set.. predefined Oracle ID. Pass a string.. The CharacterSet class is an abstract class. which corresponds to a character set ID that Oracle supports. There are multiple factory methods for CHAR. mainly involving functionality to convert to or from other character sets. To construct a CHAR object. Constructing an oracle. to the factory method along with the CharacterSet object that indicates how to interpret the bytes based on the character set. CharacterSet mycharset = CharacterSet.Oracle Character Data Types Support The CHAR objects that are Oracle object attributes are returned in the database character set. The make method takes an integer as input. this value is not meaningful. // 832 . which can take a String. the string is converted to the character set indicated by the CharacterSet object before being placed into the CHAR object.JA16SJIS_CHARSET. you must provide character set information to the CHAR object by way of an instance of the CharacterSet class. .make(oracleId). Oracle does not intend or recommend that users extend the CharacterSet class. This method is a factory for the character set instance. therefore it has no constructor. Each character set that Oracle supports has a unique. Construct a CHAR object. The only way to create instances is to use the make method.

the drivers use Globalization Support. See Also: Chapter 19.ResultSet interface and the setCursorName method specified in the java. The ROWID can be thought of as a virtual column. This section describes the ROWID and REF CURSOR type extensions. or application running on the client. then the character set will not be recognized and the toString method will return a hexadecimal representation of the CHAR data and will not throw a SQLException exception. The oracle. returning a Java String object. can use different character sets. When you use the methods of the CHAR class to transfer data between the server and the client. then the character set will not be recognized and the getString method will throw a SQLException exception. The ROWID is supported as a Java string.Statement interface. except a default replacement character replaces characters that have no unicode representation in the CHAR object character set.sql. Oracle Extensions 4-13 .sql. The database server and the client. ROWIDs provide functionality similar to the getCursorName method specified in the java. "Globalization Support" Additional Oracle Type Extensions Oracle JDBC drivers support the Oracle-specific BFILE and ROWID data types and REF CURSOR types. ■ toString This method is identical to the getString method.Additional Oracle Type Extensions oracle.ANYDATA Types The oracle. This section covers the following topics: ■ ■ ■ ■ ■ Oracle ROWID Type Oracle REF CURSOR Type Category Oracle BINARY_FLOAT and BINARY_DOUBLE Types Oracle SYS.jdbc Package Oracle ROWID Type A ROWID is an identification tag unique for each row of an Oracle Database table. which are not part of the standard JDBC specification. and REF CURSOR types are supported as JDBC result sets. But if you enter an invalid OracleID. containing the ID for each row.CHAR Conversion Methods The CHAR class provides the following methods for translating character data to strings: ■ getString This method converts the sequence of characters represented by the CHAR object to a string.sql.ANYTYPE and SYS. To convert the data.sql.ROWID class is supplied as a container for ROWID SQL data type. but is often a question mark (?). ■ getStringWithReplacement This method is identical to the getString method. This default character varies from character set to character set. the JDBC drivers must convert the data from the server character set to the client character set or vice versa. If you enter an invalid OracleID.

a pointer has the data type REF x. oracle.getROWID (2).prepareStatement ("UPDATE emp SET ename = ? WHERE rowid = ?"). A REF CURSOR. To create a cursor variable. You can also bind a ROWID to a PreparedStatement parameter with the setString method.ROWID class replaces oracle. // Do the update } Oracle REF CURSOR Type Category A cursor variable holds the memory location of a query work area. ename.createStatement(). use the java.executeQuery ("SELECT ename. ResultSet rset = stmt. In SQL. rather than the contents of the area.5. Note: The oracle. then you can retrieve the ROWIDs with the result set getString method. identifies a reference to a cursor variable.ROWID rowid = rset. // Prepare a statement to update the ENAME column at a given ROWID PreparedStatement pstmt = conn.sql. rowid). // Get the ROWID as a String pstmt.setROWID (2.driver. Note: REF CURSOR instances are not scrollable. Because many cursor variables might exist to point to many work areas. For example: DECLARE TYPE DeptCursorTyp IS REF CURSOR Then.next ()) { String ename = rset. // Select the ROWID to identify the rows to be updated.ROWID.Additional Oracle Type Extensions If you include the ROWID pseudo-column in a query. REF CURSOR can be thought of as a category or data type specifier that identifies many different types of cursor variables. For JSE 6.toLowerCase ()).RowId interface instead. as in the example that follows. create the cursor variable by declaring it to be of the type DeptCursorTyp: 4-14 Oracle Database JDBC Developer's Guide and Reference .sql. rowid FROM emp FOR UPDATE").getString (1).jdbc. use the former class only when using J2SE 1. then. // Query the employee names with "FOR UPDATE" to lock the rows. which was used in previous releases of Oracle JDBC.setString (1.sql. // Loop through the results of the query while (rset. This enables in-place updating. begin by identifying a type that belongs to the REF CURSOR category. Example The following example shows how to access and manipulate ROWID data: Statement stmt = conn. where REF is short for REFERENCE and x represents the entity being referenced. But. Declaring a cursor variable creates a pointer.executeUpdate (). // Pass ROWID to the update statement pstmt. pstmt.

because there is an output parameter.declare cursor variable REF CURSOR.out.jdbc. The result set is processed as requested. .. Important: 2. ResultSet cursor. The cursor associated with a REF CURSOR is closed whenever the statement object that produced the REF CURSOR is closed. // Use a PL/SQL block to open the cursor cstmt = conn. a REF CURSOR is materialized as a ResultSet object and can be accessed as follows: 1.. end. Stored procedures can return cursor variables of the REF CURSOR category. is a category of data types. cstmt. The stored procedure returns a REF CURSOR. Use a JDBC callable statement to call a stored procedure.prepareCall ("begin open ? for select ename from emp.. cstmt. as opposed to a prepared statement. OracleTypes. // Use the cursor like a standard ResultSet while (cursor. This output is equivalent to a database cursor or a JDBC result set. In JDBC.. The Java application casts the callable statement to an Oracle callable statement and uses the getCursor method of the OracleCallableStatement class to materialize the REF CURSOR as a JDBC ResultSet object. CallableStatement cstmt. cursor = ((OracleCallableStatement)cstmt). The callable statement implements a PL/SQL procedure that returns a REF CURSOR.} In the preceding example: ■ A CallableStatement object is created by using the prepareCall method of the connection class. rather than a particular data type. It must be a callable statement.println (cursor.. import oracle.CURSOR). Unlike in past releases."). .execute(). the cursor associated with a REF CURSOR is not closed when the result set object in which the REF CURSOR was materialized is closed. 3.registerOutParameter(1.*.Additional Oracle Type Extensions dept_cv DeptCursorTyp . 4.getCursor(1). A REF CURSOR essentially encapsulates the results of a query.getString(1)).next ()) {System. ■ Oracle Extensions 4-15 . then. Example This example shows how to access REF CURSOR data.

the same is true for BINARY_FLOAT. returning the REF CURSOR.Additional Oracle Type Extensions ■ As always.1) provides a Java interface to access the SYS. If you use setBinaryDouble for a NUMBER parameter. the getDouble method will return the data in the binary format. setFloat(int. and returns the REF CURSOR into a ResultSet object. and REAL data types use the Oracle NUMBER representation. then the data is retrieved from the database in the binary format. to send internal binary bits instead of NUBMER bits. float).ANYTYPE and SYS. DOUBLE PRECISION. The data will be correct. where it will be converted back to binary format. the output parameter of the callable statement must be registered to define its type. Oracle SYS. These correspond to the Java float and double scalar types with the exception of negative zero and NaN.OraclePreparedStatement interface converts the data to the internal binary bits and sends them to the database. Also. double) method of the oracle.jdbc. A call to the JDBC standard setDouble(int. the number bits are returned and converted to the Java double data type. 4-16 Oracle Database JDBC Developer's Guide and Reference . double) method of the PreparedStatement interface converts the Java double argument to Oracle NUMBER style bits and send them to the database. See Also: Oracle Database SQL Language Reference If you include a BINARY_DOUBLE column in a query. If you use setDouble for a BINARY_DOUBLE parameter. Note: The Oracle representation for the SQL FLOAT. which is an Oracle extension to the standard JDBC API. then the binary bits are sent to the server and converted to NUMBER format.CURSOR for a REF CURSOR. The SetFloatAndDoubleUseBinary connection property when set to true causes the JDBC standard APIs. The callable statement is run. but server CPU load will be increased. The BINARY_FLOAT and BINARY_DOUBLE data types can be regarded as proprietary types. You must ensure that the data format used matches the type of the target parameter of the PreparedStatement interface. for a NUMBER data type column.ANYTYPE and SYS. Use the type code OracleTypes. double).ANYDATA Types Oracle Database 11g Release 1 (11. The CallableStatement object is cast to OracleCallableStatement to use the getCursor method. This will result in correct data and least use of CPU. the setBinaryDouble(int. Note: Although this section largely discusses BINARY_DOUBLE. ■ ■ Oracle BINARY_FLOAT and BINARY_DOUBLE Types The Oracle BINARY_FLOAT and BINARY_DOUBLE types are used to store IEEE 574 float and double data. and all the variations. In contrast. In contrast. This will increase the CPU load on both client and server and can result in data corruption as well. then the data will first be converted to NUMBER bits on the client and sent to the server. setDouble(int.ANYDATA Oracle types.

Example 4–2 Creating a Transient Object Type Through PL/SQL and Retrieving Through JDBC This example provides a code snippet illustrating how to retrieve a transient object type through JDBC.OracleTypes. An ANYTYPE instance can be retrieved from a PL/SQL procedure or a SQL SELECT statement where SYS."). You can use the oracle. if(!obj.ANYTYPE type contains a type description of any SQL type. This method returns an instance of the TypeDescriptor. TypeDescriptor td = (TypeDescriptor)rs. use the getObject method. including object types and collection types.isTransientType()) { AttributeDescriptor[] attributes = ((StructDescriptor)td). To retrieve an ANYTYPE instance from the database.getTypeName()). cstmt.OPAQUE.. The retrieved ANYTYPE instance could be any of the following: ■ ■ ■ ■ Transient object type Transient predefined type Persistent object type Persistent predefined type Example 4–1 Code Snippet for Accessing SYS. TypeDescriptor obj = (TypeDescriptor)cstmt.length. .getAttributeName()).prepareCall ("BEGIN ? := transient_obj_type (). named or unnamed.TYPECODE_OBJECT) { // check if it's a transient type if(td.Additional Oracle Type Extensions See Also: For information about these Oracle types.TypeDescriptor class to access the SYS. Oracle Extensions 4-17 .ANYTYPE Type The following code snippet illustrates how to retrieve an instance on ANYTYPE from the database: .ANYTYPE"). OracleCallableStatement cstmt = (OracleCallableStatement)conn.getInternalTypeCode().println(td.getAttributesDescriptor().execute().getObject(1). i++) System...ANYTYPE type..out.println(attributes[i].getObject(1). ResultSet rs = stmt.. cstmt."SYS. short typeCode = td.. END.sql.ANYTYPE is used as a column type. } else { System.registerOutParameter(1. for(int i=0.close(). persistent or transient. } } . if(typeCode == TypeDescriptor.out. cstmt.executeQuery("select anytype_column from my_table"). i<attributes.out. refer Oracle Database PL/SQL Packages and Types Reference An instance of the SYS.println("This must be a JDBC bug").isTransient()) System.

ANYDATA) Statement stmt = conn.accessDatum()..sql.registerOutParameter(1. if(td..prepareCall("BEGIN ? := dumpanytype(?).next()) { ANYDATA anydata = (ANYDATA)rs. // obj is the instance of TypeDescriptor that you have retrieved cstmt.executeQuery("select data from my_anydata_tab").getObject(1). cstmt. ename VARCHAR2(10) ) 4-18 Oracle Database JDBC Developer's Guide and Reference .").getTypeDescriptor(). data SYS. END.OracleTypes.createStatement().setObject(2.getTypeCode() == OracleType. Example 4–4 Accessing an Instance of ANYDATA from the Database . The oracle. The convertDatum factory method takes an instance of Datum and returns an instance of ANYDATA.. cstmt..isNull()) { TypeDescriptor td = anydata. while(rs. . Example 4–5 Inserting an Object as ANYDATA in a Database Table Consider the following table and object type definition: CREATE TABLE anydata_tab ( id NUMBER.TYPECODE_OBJECT) STRUCT struct = (STRUCT)anydata...Additional Oracle Type Extensions return obj.ANYDATA) CREATE OR REPLACE TYPE employee AS OBJECT ( empno NUMBER. if(!anydata. CallableStatement cstmt = conn.getObject(1).ANYDATA class enables you to access SYS. The syntax for this factory method is as follows: public static ANYDATA convertDatum(Datum datum) throws SQLException The following is sample code for creating an instance of oracle.sql. Example 4–3 Calling a PL/SQL Stored Procedure That Takes an ANYTPE as IN Parameter The following code snippet illustrates how to call a PL/SQL stored procedure that takes an ANYTYPE as IN parameter: .. An instance of this class can be obtained from any valid instance of oracle.Datum class. ResultSet rs = stmt..VARCHAR).ANYDATA instances from the database..execute().sql.obj). ANYDATA myAnyData = ANYDATA. .ANYDATA: // struct is a valid instance of oracle. String str = (String)cstmt.sql.convertDatum(struct). // anydata_table has been created as: // CREATE TABLE anydata_tab (data SYS.STRUCT that either comes from the // database or has been constructed in Java. } } ..

stmt. Example 4–6 Selecting an ANYDATA Column from a Database Table . They also provide access to other Oracle-specific functionality. Object[] objattr = new Object[2].Connection.objattr).createDescriptor("EMPLOYEE".executeUpdate()...anyda).jdbc Package Interface or Class Class Interface Key Functionality Implements java. pstmt.getObject(1). Oracle Extensions 4-19 ..jdbc Package The interfaces of the oracle. pstmt.. objattr[1] = new String("Papageno"). StructDescriptor sd = StructDescriptor.conn.jdbc package define the Oracle extensions to the interfaces in java. Table 4–2 Name OracleDriver OracleConnection Key Interfaces and Classes of the oracle. and result sets..getTypeDescriptor(). ResultSet rs = stmt.123).close().. Implements java. For the oracle. . objattr[0] = new BigDecimal(1120). STRUCT myEmployeeStr = new STRUCT(sd.(OracleConnection)conn). The oracle.. PreparedStatement pstmt = conn.Additional Oracle Type Extensions To create an instance of the EMPLOYEE SQL object type and to insert it into anydata_tab: .close().Driver Provides methods to start and stop an Oracle Database instance and to return Oracle statement objects and methods to set Oracle performance extensions for any statement run in the current connection. TypeDescriptor td = obj. } rs.sql.sql.convertDatum(myEmployeeStr). These extensions provide access to SQL-format data as described in this chapter.sql. statements.setObject(2. .setInt(1. including Oracle performance enhancements. while(rs.next()) { ANYDATA obj = (ANYDATA)rs. pstmt.createStatement(). Table 4–2 lists key interfaces and classes used for connections.. ANYDATA anyda = ANYDATA.?)").prepareStatement("insert into anydata_table values (?. Statement stmt = conn.executeQuery("select data from anydata_table").jdbc package.

OracleResultSet Interface Provides getXXX methods to retrieve data in oracle. OracleDatabaseMetaData Class Provides methods to get metadata information about the database. and default transaction isolation level.sql.sql.jdbc.* types into a callable statement. In addition.OraclePreparedStatement 4-20 Oracle Database JDBC Developer's Guide and Reference . it adds constants for Oracle extended types. Is a supertype of OraclePreparedStatement and OracleCallableStatement. Is a supertype of OracleCallableStatement.CallableStatement. OraclePreparedStatement Interface Provides setXXX methods to bind oracle.DatabaseMetaData). Extends OraclePreparedStatement. Implements java.jdbc.ResultSetMetaData. such as database product name and version.ResultSet.OracleConnection Interface oracle. Implements java.OracleStatement Interface oracle.Types class.sql.sql format and setXXX methods to bind oracle.sql. Implements java.sql. This section covers the following topics: ■ ■ ■ Interface oracle. Implements java. Extends OracleStatement.sql. such as column names and data types. table information. Implements java.sql. OracleCallableStatement Interface Provides getXXX methods to retrieve data in oracle.jdbc Package Name OracleStatement Interface or Class Interface Key Functionality Provides methods to set Oracle performance extensions for individual statement.sql.PreparedStatement. it uses the same values as the standard java.sql. OracleTypes Class Defines integer constants used to identify SQL types. For standard types.* types into a prepared statement. Implements java.sql format.Additional Oracle Type Extensions Table 4–2 (Cont. OracleResultSetMetaData Interface Provides methods to get metadata information about Oracle result sets.Statement.) Key Interfaces and Classes of the oracle.jdbc.

STRUCT.OracleResultSet Interface oracle. All code that constructs instances of the standard types should use the JDBC 4. BLOB.jdbc. CLOB. set flags and options for Oracle performance extensions.OracleConnection This interface extends standard JDBC connection functionality to create and return Oracle statement objects. ARRAY.OracleTypes Method getJavaSqlConnection Interface oracle.sql data values like DATE and NUMBER. and so on. BFILE. support type maps for Oracle objects. all connection properties are defined as constants in the OracleConnection interface. In Oracle Database 11g Release 1 (11.jdbc. For example.0 standard factory methods. TIMESTAMP. JAVA_STRUCT. and support client identifiers.OracleCallableStatement Interface oracle. For example.OracleConnection methods are Oracle-defined extensions: ■ cancel Performs an immediate (asynchronous) termination of any currently executing operation on this connection ■ commit Commits the transaction with the given options ■ getDefaultExecuteBatch Retrieves the default update-batching value for this connection ■ setDefaultExecuteBatch Sets the default update-batching value for this connection ■ getDefaultRowPrefetch Oracle Extensions 4-21 . ArrayDescriptor. and StructDescriptor. ■ ■ Client Identifiers In a connection pooling environment.jdbc. A client identifier can also be used to share the Globally Accessed Application Context between different database sessions.jdbc. These types are for internal driver use only. NUMBER. This interface also defines factory methods for constructing oracle.jdbc. for better visibility and clarity. See Also: Oracle Database Advanced Application Developer's Guide The following oracle.1). There are no factory methods for CHAR. NCLOB. Also. Remember the following points while using factory methods: ■ All code that constructs instances of the oracle.sql types should use the Oracle extension factory methods. DATE.Additional Oracle Type Extensions ■ ■ ■ ■ ■ Interface oracle. the client identifier can be used to identify the lightweight user using the database session currently.OracleResultSetMetaData Class oracle.jdbc. INTERVALDS. and so on. The client identifier set in a database session is audited when database auditing is turned on. new methods have been added to this interface that enable the starting up and shutting down of an Oracle Database instance. TIME.

OracleStatement methods are Oracle-defined extensions: ■ defineColumnType Defines the type you will use to retrieve data from a particular database table column Note: This method is no longer needed or recommended for use with the JDBC Thin driver.OracleCallableStatement This interface extends the OraclePreparedStatement interface. which extends the OracleStatement interface and incorporates standard JDBC callable statement functionality.sql. 4-22 Oracle Database JDBC Developer's Guide and Reference . Also. The following oracle.sql.SQLException: Missing IN or OUT parameter at index:: 1 Interface oracle.OracleStatement This interface extends standard JDBC statement functionality and is the superinterface of the OraclePreparedStatement and OracleCallableStatement classes.OraclePreparedStatement interface is extended by the OracleCallableStatement interface. Note: Do not use the PreparedStatement interface to create a trigger that refers to a :NEW or :OLD column.jdbc. and methods to support Oracle performance extensions on a statement-by-statement basis. ■ getRowPrefetch Retrieves the row-prefetch value for this statement ■ setRowPrefetch Sets the row-prefetch value for this statement Interface oracle. Extended functionality consists of setXXX methods for binding oracle. Use Statement instead.* types and objects to prepared statements. as opposed to the OracleConnection interface that sets these on a connectionwide basis.jdbc.OraclePreparedStatement This interface extends the OracleStatement interface and extends standard JDBC prepared statement functionality.jdbc.Additional Oracle Type Extensions Retrieves the default row-prefetch value for this connection ■ setDefaultRowPrefetch Sets the default row-prefetch value for this connection Interface oracle.jdbc.jdbc. the oracle. Using PreparedStatement will cause execution to fail with the message java. Extended functionality includes support for setting flags and options for Oracle performance extensions on a statement-by-statement basis.

. JDBC uses the SQL types identified by the elements of the OracleTypes class in two main areas: registering output parameters and in the setNull method of the PreparedStatement class. using CallableStatement will cause execution to fail with the message java.sql. The oracle.CURSOR (for REF CURSOR types) As in java.BFILE OracleTypes..Types or oracle.jdbc. ■ Interface oracle.Types class and contains these additional type codes for Oracle extensions: ■ ■ ■ OracleTypes.. If you are using setXXX(int.ROWID OracleTypes. OracleTypes and Registering Output Parameters The type codes in java.OracleResultSet This interface extends standard JDBC result set functionality.sql..Additional Oracle Type Extensions Note: Do not use the CallableStatement interface to create a trigger that refers to a :NEW or :OLD column.Types. which is for named parameter notation. Each variable in this class has a constant integer value. all the variable names are in uppercase text.. then any output parameter is bound with registerOutParameter(int....).* objects..) and registerOutParameter(String.jdbc.sql..OracleTypes identify the SQL types of the output parameters in the registerOutParameter method of the Oracle Extensions 4-23 .).. setXXXAtName(String.OracleResultSetMetaData This interface extends standard JDBC result set metadata functionality to retrieve information about Oracle result set objects.sql. Interface oracle.jdbc.) methods can be used only if all binds are procedure or function parameters only.jdbc.. Use Statement instead.) and not registerOutParameter(String.OracleTypes The OracleTypes class defines constants that JDBC uses to identify SQL types. See Also: "Using Result Set Metadata Extensions" on page 11-14 Class oracle.) or a combination of both..sql. The statement can contain no other binds and the parameter binds must be indicated with a question mark (?) and not :XX..OracleTypes class duplicates the type code definitions of the standard Java java.. implementing getXXX methods for retrieving data into oracle..SQLException: Missing IN or OUT parameter at index::1 Note: ■ The setXXX(String.jdbc...

getString (1)). OracleTypes and the setNull Method The type codes in Types and OracleTypes identify the SQL type of the data item. Note the use of the OracleTypes. index represents the parameter index. END. which the setNull method sets to NULL.STRUCT. "EMPLOYEE"). ps.CHAR).CallableStatement and oracle.jdbc.setNull(int index. The form of registerOutParameter requires you to specify the type code. System.jdbc. CallableStatement cs = conn.registerOutParameter (1. int sqlType. // get the value into a STRUCT because it // is assumed that no type map has been defined STRUCT emp = ((OracleCallableStatement)cs). so it is retrieved into a STRUCT data type. cs. index represents the parameter index.OracleCallableStatement interfaces.Additional Oracle Type Extensions java. or ARRAY type code. REF.execute ().STRUCT or OracleTypes."). String sql_name). sqlType is the type code for the SQL data type.execute ().out.prepareCall ("BEGIN charout (?).sql. as well as the SQL name.registerOutParameter(int index. sqlType is the type code for the SQL data type. String sql_name). int sqlType.registerOutParameter(int index. cs. END. when sqlType is a STRUCT. The next example uses a CallableStatement interface to call structout.prepareCall ("BEGIN structout (?). cs. int scale). for 4-24 Oracle Database JDBC Developer's Guide and Reference .PreparedStatement and oracle.sql. int sqlType. cs.CHAR type code in the registerOutParameter method. To retrieve the value of EMPLOYEE as an oracle. int sqlType).STRUCT object. for user-defined types. These are the forms that the setNull method can take for the PreparedStatement and OraclePreparedStatement objects: ps.STRUCT. The example assumes that no type mapping has been declared for the EMPLOYEE type.registerOutParameter (1. The following example uses a CallableStatement interface to call a procedure named charout. sql_name is the name given to the data type. These are the forms that the registerOutputParameter method can take for the CallableStatement and OracleCallableStatement interfaces cs. OracleTypes. the statement object cs is cast to OracleCallableStatement and the Oracle extension getSTRUCT method is invoked. The setNull method can be found in the java.registerOutParameter(int index. EMPLOYEE. and scale represents the number of digits to the right of the decimal point.println ("Out argument is: " + cs. and sql_name is the name given to the data type."). In these signatures. int sqlType). when sqlType is a NUMERIC or DECIMAL type code. which returns a CHAR data type. In these signatures.getSTRUCT (1).sql.OraclePreparedStatement interfaces. Types. cs. cs.setNull(int index. which returns a STRUCT data type. OracleTypes. CallableStatement cs = conn.

sql. Method getJavaSqlConnection The getJavaSqlConnection method of the oracle.BFILE oracle.prepareStatement ("INSERT INTO num_table VALUES (?)"). } Oracle Extensions 4-25 .sql. when sqlType is a STRUCT.prepareStatement ("INSERT INTO employee_table VALUES (?)"). Note the use of OracleTypes. Alternatively.OracleConnection. .STRUCT. "EMPLOYEE"). The following example uses a prepared statement to insert a null value into the database.sql.REF oracle.Connection.CLOB oracle. pstmt. REF.jdbc package in Oracle 9i release. pstmt. or ARRAY type code. In this example. ■ ■ ■ ■ ■ ■ ■ oracle. PreparedStatement pstmt = conn.1). Types.driver package was deprecated in favor of the oracle.ARRAY oracle.setNull (1.OPAQUE oracle.NUMERIC to identify the numeric object set to NULL. This method is available for the following Oracle data type classes: Note: The getConnection method used in Oracle 8i and earlier versions of JDBC driver returns oracle.Connection getJavaSqlConnection() throws SQLException.STRUCT The following code snippet shows the getJavaSqlConnection method in the Array class: public class ARRAY { java.sql. pstmt.NUMERIC can be used..setNull (1.jdbc.jdbc. OracleTypes.sql.execute (). The use of the classes in the oracle. PreparedStatement pstmt = conn.BLOB oracle.driver have been desupported.. pstmt.sql. In Oracle Database 11g Release 1 (11.sql.sql.driver.* classes returns java.NUMERIC). a ParameterTypeConflict exception is thrown. the prepared statement inserts a NULL STRUCT object of type EMPLOYEE into the database. OracleTypes.sql.execute ().Additional Oracle Type Extensions user-defined types. If you enter an invalid sqlType. the classes in the package oracle.sql.jdbc.

If you know the maximum size of return parameters. using registerReturnParameter(int paramIndex. The getReturnResultSet method fetches the data returned from DML returning and returns it as a ResultSet object. ■ The following sections explain the support for DML returning: ■ ■ ■ ■ Oracle-Specific APIs Running DML Returning Statements Example of DML Returning Limitations of DML Returning See Also: "Retrieval of Auto-Generated Keys" on page 3-4 Oracle-Specific APIs The OraclePreparedStatement interface is enhanced with Oracle-specific application programming interfaces (APIs) to support DML returning.jdbc. The method throws a SQLException instance if an error occurs. int maxSize) can reduce memory consumption.DML Returning DML Returning The DML returning feature provides more functionality compared to retrieval of auto-generated keys. Note: The Oracle-specific APIs for the DML returning feature are in ojdbc5. to register parameters that are returned and data retrieved by DML returning. Note: If you do not know the maximum size of the return parameters. The registerReturnParameter method is used to register the return parameter for DML returning. which picks the default maximum size. It can be used to retrieve not only auto-generated keys. You can also specify the maximum bytes or characters of the return parameter.OraclePreparedStatement interface.5 and in ojdbc6. You must pass a positive integer specifying the index of the return parameter.jar for Java Development Kit (JDK) 1. but also other columns or values that the application may use. You cannot use both DML returning and retrieval of auto-generated keys in the same statement.6. int externalType). int externalType. Note: ■ The server-side internal driver does not support DML returning and retrieval of auto-generated keys.jar for JDK 1. The registerReturnParameter and getReturnResultSet methods have been added to the oracle. The method throws a SQLException exception if an error occurs. then you should use registerReturnParameter(int paramIndex. You also must specify the type of the return parameter. You can also specify the fully qualified name of a SQL structure type. This method can be used only with char or RAW types. 4-26 Oracle Database JDBC Developer's Guide and Reference .

. if (count>0) { ResultSet rset = pstmt.. such as type and size. OraclePreparedStatement pstmt = (OraclePreparedStatement)conn. assume that the maximum size of the name column is 100 characters. the maximum size of the return parameters is not known.. Example of DML Returning This section provides two code examples of DML returning. col2 into ?.. When a DML returning statement is run. // process the DML returning statement count = pstmt. Oracle Extensions 4-27 . the returned ResultSet object is also closed. int maxSize) method is used. int externalType) method is used. of the return parameters. The DML returning statement is then processed using one of the standard JDBC APIs. You can then fetch the returned parameters as a ResultSet object using the getReturnResultSet method of the oracle.executeUpdate(). 100). The following code example illustrates the use of DML returning. the JDBC application must call one or more of the registerReturnParameter methods. the registerReturnParameter(int paramIndex..getReturnResultSet(). This is consistent with ResultSet objects that are retrieved by processing SQL query statements. When the underlying Statement object is closed. the underlying Statement object must be open.DML Returning Running DML Returning Statements Before running a DML returning statement. in this case. int externalType. /** register returned parameter * in this case the maximum size of name is 100 chars */ pstmt. In order to read the values in the ResultSet object.. Because the maximum size of the name column is known.OraclePreparedStatement interface. ?").. the concurrency of the ResultSet object returned by the getReturnResultSet method must be CONCUR_READ_ONLY and the type of the ResultSet object must be TYPE_FORWARD_ONLY or TYPE_SCROLL_INSENSITIVE.18). .getString(1).VARCHAR. //rest is not null and not empty while(rset. However.jdbc.next()) { String name = rset. empty_clob()) returning col1.. The following code example also illustrates the use of DML returning.setInt(1. } } .. executeUpdate or execute. . OraclePreparedStatement pstmt = (OraclePreparedStatement)conn. Therefore. OracleTypes.prepareStatement( "insert into lobtab values (100. The method provides the JDBC drivers with information. In this example. the registerReturnParameter(int paramIndex. pstmt.prepareStatement( "delete from tab1 where age < ? returning name into ?").registerReturnParameter(2.

registerReturnParameter(1. clob = (CLOB)rset. PreparedStatement pstmt = conn. be aware of the following: ■ It is unspecified what the getReturnResultSet method returns when it is invoked more than once. pstmt.Accessing PL/SQL Index-by Tables // register return parameters pstmt. OracleTypes.. 966431502). Therefore.registerReturnParam(4.setInt(3. DML returning cannot be combined with batch update.setInt(1. pstmt.executeUpdate(). ?. You cannot use both the auto-generated key feature and the DML returning feature in a single SQL DML statement.setInt(2. pstmt..out.getGeneratedKeys. pstmt. OracleTypes. pstmt.executeUpdate. the applications must know the information of return parameters before running DML returning statements.INTEGER). ResultSet rset = pstmt.CLOB).prepareStatement(’insert into orders (?.next()) { r = rset. System.NEXTVAL).. int r. .getClob(2).. 100).getInt(1). Streams are not supported with DML returning. } . ResultSet rset = pstmt. seq01... pstmt. if (rset.registerReturnParameter(2. For example. ?) returning order_id into ?"). Limitations of DML Returning When using DML returning. . The ResultSet objects returned from the execution of DML returning statements do not support the ResultSetMetaData type.getReturnResultSet(). This section covers the following topics: ■ ■ ■ Overview Binding IN Parameters Receiving OUT Parameters 4-28 Oracle Database JDBC Developer's Guide and Reference .. the following is not allowed: .. // process the DML returning SQL statement pstmt. You should not rely on any specific action in this regard. CLOB clob.println(r). OracleTypes. ■ ■ ■ ■ Accessing PL/SQL Index-by Tables Oracle JDBC drivers enable JDBC applications to make PL/SQL calls with index-by table parameters.INTEGER).

OUT. Object arrayData. and data access methods do not support PL/SQL index-by tables. including function return values. Table 4–3 PL/SQL Types and Corresponding JDBC Types JDBC Types NUMERIC NUMERIC NUMERIC NUMERIC NUMERIC NUMERIC NUMERIC VARCHAR PL/SQL Types BINARY_INTEGER NATURAL NATURALN PLS_INTEGER POSITIVE POSITIVEN SIGNTYPE STRING Note: Oracle JDBC does not support RAW. output registration. int curLen. DATE. int elemMaxLen) throws SQLException Oracle Extensions 4-29 . The OraclePreparedStatement and OracleCallableStatement classes define the additional methods. synchronized public void setPlsqlIndexTable (int paramIndex. and PL/SQL RECORD as element types.Accessing PL/SQL Index-by Tables ■ Type Mappings Note: Index-by tables of PL/SQL records are not supported. See Also: Oracle Database PL/SQL Language Reference Binding IN Parameters To bind a PL/SQL index-by table parameter in the IN parameter mode. use the setPlsqlIndexTable method defined in the OraclePreparedStatement and OracleCallableStatement classes. Overview Oracle JDBC drivers support PL/SQL index-by tables of scalar data types. int elemSqlType. Table 4–3 displays the supported scalar types and the corresponding JDBC type codes. Typical Oracle JDBC input binding. These methods include the following: ■ ■ ■ ■ setPlsqlIndexTable registerIndexTableOutParameter getOraclePlsqlIndexTable getPlsqlIndexTable These methods handle PL/SQL index-by tables as IN. This chapter introduces additional methods to support these types. or IN OUT parameters. int maxLen.

Specifies the index-by table element maximum length in case the element type is CHAR. // set the value procin. or a Java object array.length. 4-30 Oracle Database JDBC Developer's Guide and Reference . maxLen. elemSqlType. elemMaxLen). such as int[]. VARCHAR. "maxLen" should be the // same as "currentLen".Accessing PL/SQL Index-by Tables Table 4–4 describes the arguments of the setPlsqlIndexTable method. such as BigDecimal[]. 3 }. This argument is required. The value can be a Java primitive type array. // index-by table element length in case the element type // is CHAR.NUMBER. If the curLen value is larger than the size of arrayData. Table 4–4 Argument int paramIndex Object arrayData Arguments of the setPlsqlIndexTable Method Description Indicates the parameter position within the statement.setPlsqlIndexTable (1. For standalone binds. then only the curLen number of table elements is passed to the database. This value is ignored for other // types. Is an array of values to be bound to the PL/SQL index-by table parameter. For standalone binds. // index-by table bind value int[] values = { 1. // maximum length of the index-by table bind value. // actual size of the index-by table bind value int currentLen = values. This // value defines the maximum possible "currentLen" for batch // updates. currentLen.length."). int maxLen = values. 2. This value is ignored for other types. end. int maxLen int curLen int elemSqlType int elemMaxLen The following code example uses the setPlsqlIndexTable method to bind an index-by table as an IN parameter: // Prepare the statement OracleCallableStatement procin = (OracleCallableStatement) conn.lang. If the curLen value is smaller than the size of arrayData. VARCHAR or RAW. int elemMaxLen = 0.prepareCall ("begin procin (?). Specifies the index-by table element type based on the values defined in the OracleTypes class. values. The value is of type java. then the entire arrayData is sent to the database. Specifies the maximum table length of the index-by table bind value that defines the maximum possible curLen for batch updates. or RAW.Object. maxLen should use the same value as curLen. // index-by table element type int elemSqlType = OracleTypes. Specifies the actual size of the index-by table bind value in arrayData.

This value is ignored for other // types int elemMaxLen = 0. // index-by table element length in case the element type // is CHAR. // index-by table element type int elemSqlType = OracleTypes. Table 4–5 Argument int paramIndex int maxLen int elemSqlType int elemMaxLen Arguments of the registerIndexTableOutParameter Method Description Indicates the parameter position within the statement. elemSqlType. int maxLen = 10. In addition. The following code example uses the registerIndexTableOutParameter method to register an index-by table as an OUT parameter: // maximum length of the index-by table value. int elemSqlType. Specifies the maximum table length of the index-by table bind value to be returned.Accessing PL/SQL Index-by Tables // execute the call procin.execute (). Registering the OUT Parameters To register a PL/SQL index-by table as an OUT parameter. // register the return value funcnone. synchronized public void registerIndexTableOutParameter (int paramIndex. it describes how to access the OUT bind values in various mapping styles. elemMaxLen). Oracle Extensions 4-31 . maxLen. Note: The methods described in this section apply to function return values and the IN OUT parameter mode as well. This value is ignored for other types.registerIndexTableOutParameter (1. use the registerIndexTableOutParameter method defined in the OracleCallableStatement class. Specifies the index-by table element maximum length in case the element type is CHAR. or FIXED_CHAR. Receiving OUT Parameters This section describes how to register a PL/SQL index-by table as an OUT parameter. int elemMaxLen) throws SQLException Table 4–5 describes the arguments of the registerIndexTableOutParameter method.NUMBER. VARCHAR. int maxLen. This // value defines the maximum table size to be returned. VARCHAR or FIXED_CHAR. Specifies the index-by table element type based on the values defined in the OracleTypes class.

and the getPlsqlIndexTable method returns a BigDecimal[] array. // print the elements for (int i=0.getPlsqlIndexTable (1). For example. i++) System. 4-32 Oracle Database JDBC Developer's Guide and Reference . Class) Type Mappings This section covers the following topics: ■ ■ ■ JDBC Default Mappings Oracle Mappings Java Primitive Type Mappings JDBC Default Mappings The getPlsqlIndexTable(int) method returns index-by table elements using the JDBC default mappings. The return value is a Java array.println (values[i]. for an index-by table with elements of NUMERIC type code.length. the element values are mapped to BigDecimal by Oracle JDBC driver. Oracle Mappings The getOraclePlsqlIndexTable method returns index-by table elements using Oracle mapping. For a JDBC application. The syntax for this method is the following: public Object getPlsqlIndexTable (int paramIndex) throws SQLException Table 4–6 describes the argument of the getPlsqlIndexTable method.intValue()). Table 4–6 Argument int paramIndex Argument of the getPlsqlIndexTable Method Description This argument indicates the parameter position within the statement. The elements of this array are of the default Java type corresponding to the SQL type of the elements. The following code example uses the getPlsqlIndexTable method to return index-by table elements with JDBC default mapping: // access the value using JDBC default mapping BigDecimal[] values = (BigDecimal[]) procout.Accessing PL/SQL Index-by Tables Accessing the OUT Parameter Values To access the OUT bind value. the OracleCallableStatement class defines multiple methods that return the index-by table values in different mapping styles. There are three mapping choices available in JDBC drivers: Mappings JDBC default mappings Oracle mappings Methods to Use getPlsqlIndexTable(int) getOraclePlsqlIndexTable(int) Java primitive type mappings getPlsqlIndexTable(int. i<values.out. you must cast the return value to BigDecimal[] to access the table element values.

length. The return value is a Java array. Table 4–8 Argument int paramIndex Arguments of the getPlsqlIndexTable Method Description Indicates the parameter position within the statement. end.intValue()).execute ().prepareCall ("begin procout (?). The following code example uses the getOraclePlsqlIndexTable method to access the elements of a PL/SQL index-by table OUT parameter. // print the elements for (int i=0.println (outvalues[i].sql.out..Datum array.NUMBER elements. Java Primitive Type Mappings The getPlsqlIndexTable(int.getOraclePlsqlIndexTable (1). // access the value using Oracle JDBC mapping Datum[] outvalues = procout. Class primitiveType) throws SQLException Table 4–8 describes the arguments of the getPlsqlIndexTable method.sql. i++) System. Oracle Extensions 4-33 .sql. using Oracle mapping: // Prepare the statement OracleCallableStatement procout = (OracleCallableStatement) conn.Datum array that contains oracle."). the element values of an index-by table of numeric elements are mapped to the oracle.sql. // run the call procout. Class) method returns index-by table elements in Java primitive types.NUMBER type in Oracle mapping. i<outvalues.Accessing PL/SQL Index-by Tables public Datum[] getOraclePlsqlIndexTable (int paramIndex) throws SQLException Table 4–7 describes the argument of the getOraclePlsqlIndexTable method. . The syntax for this method is the following: synchronized public Object getPlsqlIndexTable (int paramIndex. and the getOraclePlsqlIndexTable method returns an oracle.. Table 4–7 Argument int paramIndex Argument of the getOraclePlsqlIndexTable Method Description Indicates the parameter position within the statement. and the elements in the array are of the default Datum type corresponding to the SQL type of the element. The return value is an oracle. For example.

// execute the call funcnone.Integer.registerIndexTableOutParameter (1.lang.Integer.lang.getPlsqlIndexTable (1.TYPE java. VARCHAR or RAW.lang. This // value defines the maximum table size to be returned. if you specify java.lang.TYPE.lang. // print the elements for (int i=0.lang. the return value is an int array. elemSqlType. // index-by table element length in case the element type // is CHAR.lang.Integer. i++) System. OracleCallableStatement funcnone = (OracleCallableStatement) conn. // index-by table element type int elemSqlType = OracleTypes.prepareCall ("begin ? := funcnone.TYPE The following code example uses the getPlsqlIndexTable method to access the elements of a PL/SQL index-by table of numbers. In the example. // register the return value funcnone.TYPE). int maxLen = 10.Long.execute (). This value is ignored for other // types int elemMaxLen = 0.length. maxLen. // maximum length of the index-by table value. java.TYPE java. The following are the possible values of this parameter: java. 4-34 Oracle Database JDBC Developer's Guide and Reference .NUMBER.TYPE and the return value of the getPlsqlIndexTable method is an int array.").) Arguments of the getPlsqlIndexTable Method Argument Class primitiveType Description Specifies a Java primitive type to which the index-by table elements are to be converted.lang.TYPE java.println (values[i]).Float.TYPE java. i<values. int[] values = (int[]) funcnone. For example.Double. the second parameter specifies java.Integer.Accessing PL/SQL Index-by Tables Table 4–8 (Cont. end.Short.out. elemMaxLen). // access the value as a Java primitive array.

and therefore. It provides high performance. It can be used for application servers as well as for applets. a protocol developed by Oracle to access data from Oracle Database. On the server-side. The JDBC Thin driver can be used on both the client-side and the server-side. The driver allows a direct connection to the database by providing an implementation of TCP/IP that implements Oracle Net and TTC on top of Java sockets. The JDBC Thin driver also provides support for the following additional features: ■ ■ Support for Applets Default Support for Native XA Features Specific to JDBC Thin 5-1 . It also provides basic information about working with Oracle JDBC applets.5 Features Specific to JDBC Thin This chapter introduces the Java Database Connectivity (JDBC) Thin client and covers the features supported only by the JDBC Thin driver. this driver does not require any additional Oracle software on the client-side. On the client-side. The JDBC Thin driver communicates with the server using TTC. this driver is used to access a remote Oracle Database instance or another session on the same database. Both of these protocols are lightweight implementation versions of their counterparts on the server. Additional Features Supported The JDBC Thin driver supports all standard JDBC features. Also. The Oracle Net protocol runs over TCP/IP only. drivers can be used in Java applications or Java applets that run either on the client or in the middle tier of a three-tier configuration. It is lightweight and easy to install. The JDBC Thin driver is written entirely in Java. it is platform-independent. This following topics are covered in this chapter: ■ ■ ■ Overview of JDBC Thin Client Additional Features Supported JDBC in Applets Overview of JDBC Thin Client The JDBC Thin client is a pure Java. Type IV driver. comparable to the performance provided by the JDBC Oracle Call Interface (OCI) driver.

The HTTP protocol. This driver can be downloaded along with the Java applet that is being run in a browser. It also describes how your applet can connect to a database through a firewall. This section describes what you must do to connect an applet to a database. the communication between the browser and the database is stateful and in a two-tier configuration. an applet can open TCP/IP sockets only to the host from which it was downloaded. is stateless. the browser used on the client-side must have the capability to support Java sockets. Therefore. your applet can connect only to a database that is running on the same host as the Web server. which is usually used for communication over a network. the JDBC Thin driver also provides support for Native XA. After the JDBC Thin driver establishes the database connection. the initial HTTP request to download the applet and the JDBC Thin driver is stateless. in which the support for Native XA is not enabled by default. The section concludes with how to package and deploy the applet. The following topics are covered: ■ ■ ■ ■ ■ Connecting to the Database Through the Applet Connecting to a Database on a Different Host Than the Web Server Using Applets with Firewalls Packaging Applets Specifying an Applet in an HTML Page Connecting to the Database Through the Applet The most common task of an applet using the JDBC driver is to connect to and query a database. or signed applets if you are connecting to a database that is running on a different host from the Web server. However.JDBC in Applets Support for Applets The JDBC Thin driver is the only Oracle JDBC driver that provides support for applets. See Also: "JDBC in Applets" Default Support for Native XA Similar to the JDBC OCI driver. This is unlike the case of the JDBC OCI driver. This means that without these steps. See Also: "Native-XA in Oracle JDBC Drivers" on page 28-20 JDBC in Applets You can use only the Oracle JDBC Thin driver for an applet. This description includes how to use the Connection Manager feature of Oracle Database. unless particular steps are taken. Note: When the JDBC Thin driver is used with an applet. This is the host on which the Web server is running. However. Because of applet security restrictions. the JDBC Thin driver provides support for Native XA by default. 5-2 Oracle Database JDBC Developer's Guide and Reference . the JDBC Thin driver is not stateless.

■ Your applet can also take advantage of the data encryption and integrity checksum features of the Advanced Security option of Oracle Database. ods. ods. ods. then there is no issue and no special steps are required. ods. your applet connects to a database on a host other than the one on which the Web server runs.setURL(connString). then you must overcome applet security restrictions.getConnection(). then you must declare the protocol as TCP.getConnection().setPassword("tiger").JDBC in Applets If your database and Web server are running on the same host. Connection conn = ods. and system identifier (SID) ORCL. which connects to a database on another computer. Connection conn = ods. However. there are two ways in which you can specify the connection information to the driver. and you want to connect with user name scott and password tiger.setUser("scott"). As with connecting from an application.setURL(connString). Connecting to a Database on a Different Host Than the Web Server If you are connecting to a database on a host other than the one on which the Web server is running. If you use the TNS keyword-value pair to specify the connection information to the JDBC Thin driver. OracleDataSource ods = new OracleDataSource(). For example. You seldom find both servers running on the same computer. The applet can connect to the Connection Manager. ■ Using TNS keyword-value syntax: String connString = "jdbc:oracle:thin:@(description=(address_list= (address=(protocol=tcp)(port=1521)(host=prodHost))) (connect_data=(INSTANCE_NAME=ORCL)))". OracleDataSource ods = new OracleDataSource(). ods. ods. You can do this in the following ways: ■ ■ Using the Oracle Connection Manager Using Signed Applets Features Specific to JDBC Thin 5-3 . You can provide it in the form of host:port:sid or in the form of TNS keyword-value syntax.setPassword("tiger"). if the database to which you want to connect resides on host prodHost. a Web server and database server both require many resources. which can request socket connection privileges to other computers.setUser("scott"). Usually. If you want your applet to connect to a database running on a different computer. Use signed applets. at port 1521. then use either of the two following connection strings: ■ Using host:port:sid syntax: String connString="jdbc:oracle:thin:@prodHost:1521:ORCL". You can connect to the database as you would from an application. then you have the following options: ■ Use the Oracle Connection Manager on the host computer.

the Oracle Connection Manager. and the database.ORA file include firewall and connection pooling support. start the Connection Manager at the operating system prompt with the following command: cmctl start 5-4 Oracle Database JDBC Developer's Guide and Reference . Replace web-server-host with the name of your Web server host. available on the Oracle distribution media. cman = (ADDRESS_LIST = (ADDRESS = (PROTOCOL=TCP) (HOST=web-server-host) (PORT=1610))) cman_profile = (parameter_list = (MAXIMUM_RELAYS=512) (LOG_LEVEL=1) (TRACING=YES) (RELAY_STATISTICS=YES) (SHOW_TNS_INFO=YES) (USE_ASYNC_CALL=YES) (AUTHENTICATION_LEVEL=0) ) After you create the file. You must use the same port number in your connection string for JDBC. On the Web server host. Here is an example of a very simple CMAN. Figure 5–1 Applet. create a CMAN. An applet that uses the JDBC Thin driver can connect to a Connection Manager running on the Web server host and have the Connection Manager redirect the Oracle Net packets to an Oracle server running on a different host.ORA file in the ORACLE_HOME/NET8/ADMIN directory. onto the Web server host. The fourth line in the file indicates that the Connection Manager is listening on port 1610. Installing and Running the Oracle Connection Manager You must install the Connection Manager. the Connection Manager looks exactly like a database server. and Database Relationship Oracle Net Listener Applet in Browser TCP/IP (only) CMAN any Oracle Net protocol Web Server webHost oraHost Using the Oracle Connection Manager requires two steps: ■ ■ Install and run the Connection Manager. Figure 5–1 illustrates the relationship between the applet.ORA file. Write the connection string that targets the Connection Manager. To a client running Oracle Net. The options you can declare in a CMAN. highly scalable program that can receive Oracle Net packets and retransmit them to a different server.JDBC in Applets Using the Oracle Connection Manager The Oracle Connection Manager is a lightweight. Connection Manager.

If you are using Netscape. To do this.setPassword("tiger"). in the order that you plan to access them. and name of the host on which the database is running. You write the URL in TNS keyword-value format: String myURL = "jdbc:oracle:thin:@(description=(address_list= (address=(protocol=tcp)(port=1610)(host=webHost)) (address=(protocol=tcp)(port=1521)(host=oraHost))) (connect_data=(INSTANCE_NAME=orcl)) (source_route=yes))". The database listener should be the last address on this list. Include applet code that asks for appropriate privileges before opening a socket. ods. For information about the steps you must follow to sign an applet. if the Connection Managers form a proxy chain. The following example describes the configuration illustrated in Figure 5–1.PrivilegeManager. The first element in the address_list entry represents the connection to the Connection Manager. refer to the Sun Microsystems Web site. such as the preceding one. so that the applet connects to the Connection Manager and the Connection Manager connects with the database. Connection conn = ods. The order in which you list the addresses is important. ods. it will function exactly as if it were connected directly to the database on the host oraHost. writing a signed applet. that is. OracleDataSource ods = new OracleDataSource().JDBC in Applets To use your applet. Writing the URL that Targets the Connection Manager The following text describes how to write the URL in your applet. Starting from Netscape 4.setURL(myURL). and name of the Web server host on which the Connection Manager is running. ods.2. The second element represents the database to which you want to connect.x-based or later browser. Features Specific to JDBC Thin 5-5 . Connection conn = ods. Sign the applet. you specify an address list that lists the protocol. add the addresses of the Connection Managers to the address list. listening on port 1521. 2. Using Signed Applets In a Java Development Kit (JDK) 1. OracleDataSource ods = new OracleDataSource().setUser("scott"). The Web server on which the Connection Manager is running is on host webHost and is listening on port 1610.security.enablePrivilege("UniversalConnect").0. and SID ORCL. then your code would include a statement like this: netscape. For example. followed by the protocol. you perform this by signing your applet. you must now write the connection string for it. The database to which you want to connect is running on host oraHost. You must follow these steps: 1.getConnection().setURL("jdbc:oracle:thin:scott/tiger@dlsun511:1721:orcl"). In the URL. port. an applet can request socket connection privileges and connect to a database running on a different host than the Web server host.getConnection(). When your applet uses a URL. ods. Connecting Through Multiple Connection Managers Your applet can reach its target database even if it first has to go through multiple Connection Managers. port.

the firewall on the target host controls the access. ■ 5-6 Oracle Database JDBC Developer's Guide and Reference . never appears in the firewall rules. and which cannot.sun. In this case. The firewall is designed to do this so that users can specify rules that include host names as well as IP addresses. If you do enter this host name in the list of rules. This time. You must obtain an object-signing certificate. For information about the Java Security API. either grant the client access or deny access. As a result. Oracle Net-compliant firewalls are available from many leading vendors. Refer to a site that provides information about obtaining and installing a certificate. In general. you must do the following to the list of firewall rules: ■ Add the IP address. including signed applet examples. firewalls are rule-based. based on this comparison. the firewall prevents the opening of a TCP/IP socket to the database. They have a list of rules that define which clients can connect. Java applets do not have access to the local system. then every applet using the JDBC Thin driver will be able to go through your firewall. You can solve the firewall issue by using an Oracle Net-compliant firewall and connection strings that comply with the firewall configuration. If the host name lookup fails. applets cannot access the host name or environment variables on the local system.JDBC in Applets 3. In this case. then the firewall tries again. an applet that uses the JDBC Thin driver cannot access the database through a firewall. a signed applet can connect to any host. In the case of applets trying to connect to the database. and not the host name. the Oracle Net-compliant firewall must be installed on that host. of the host on which the JDBC applet is running. as described in the following sections: ■ ■ Configuring a Firewall for Applets that use the JDBC Thin Driver Writing a URL to Connect Through a Firewall Configuring a Firewall for Applets that use the JDBC Thin Driver The instructions in this section assume that you are running an Oracle Net-compliant firewall.com/security Using Applets with Firewalls Under standard circumstances. the purpose of a firewall is to prevent unauthorized clients from reaching the server. In contrast. Connecting through a firewall requires two steps. Firewalls compare the host name of the client with the rules and. see the following Sun Microsystems site: http://java. To allow requests from JDBC Thin clients to go through the firewall. This host name has been hard-coded as a false host name inside the driver to force an IP address lookup. Because of the security limitations. "__jdbc__". In general. Ensure that the host name. the firewall extracts the IP address of the client and compares it to the rules. the JDBC Thin driver cannot access the host name on which it is running. The firewall cannot be provided with the host name. An unsigned applet can access only the same host from which it is downloaded.

Connection conn = ods.setUser("scott").setURL(connString). When your applet uses a URL similar to the preceding URL. You can also write the preceding URL in the following format: String connString = "jdbc:oracle:thin:@(description=(address_list= (address=(protocol=tcp)(port=1600)(host=fireWallHost)) (address=(protocol=tcp)(port=1521)(host=oraHost))) (connect_data=(INSTANCE_NAME=orcl)) (source_route=yes))". The second element represents the database to which you want to connect. ods. and you are going though a firewall on host fireWallHost. Features Specific to JDBC Thin 5-7 . ods. For example. you must specify the name of the firewall host and the name of the database host to which you want to connect. Note: To connect through a firewall. it will act as if it were connected to the database on host oraHost. For example. with SID ORCL.com:1521:orcl". ods. listening on port 1521.setUser("scott"). OracleDataSource ods = new OracleDataSource(). ods. Connection conn = ods.setUser("scott"). The first element in the address_list represents the connection to the firewall.JDBC in Applets Writing a URL to Connect Through a Firewall To write a URL that enables you to connect through a firewall. ods. ods.setURL(connString). ods. ).getConnection().setPassword("tiger"). Note that the order in which you specify the addresses is important.us. a URL specified as follows will not work: String connString = "jdbc:oracle:thin:@example. OracleDataSource ods = new OracleDataSource(). then use the following URL: OracleDataSource ods = new OracleDataSource(). ods. if you want to connect to a database on host oraHost.getConnection().setPassword("tiger"). listening on port 1610.setURL("jdbc:oracle:thin:" + "@(description=(address_list=" + (address=(protocol=tcp)(host=<firewall-host>)(port=1610))" + "(address=(protocol=tcp)(host=oraHost)(port=1521)))" + "(source_route=yes)" + "(connect_data=(SERVICE_NAME=orcl)))"). you cannot specify the URL in host:port:sid syntax.oracle. Connection conn = ods.getConnection().setPassword("tiger"). ods.

JDBC in Applets

Note:

All the parameters shown in the preceding example are required. In address_list, the firewall address must precede the database server address.

Packaging Applets
After you have coded your applet, you must package it and make it available to users. To package an applet, you will need your applet class files and the JDBC driver class files contained in the ojdbc5.jar or ojdbc6.jar files. Follow these steps:
1.

Move the JDBC driver classes file ojdbc5.jar or ojdbc6.jar to an empty directory. If your applet connects to a database with a non-US7ASCII and non-WE8ISO8859P1 character set and uses Oracle object types, then also move the orai18n.jar file to the same directory.

2. 3.

Add your applet classes files to the directory and any other files that the applet may require. Zip the applet classes and driver classes together into a single ZIP or Java Archive (JAR) file. The single ZIP file should contain the following:

Class files from the ojdbc5.jar or ojdbc6.jar files and required class files from the orai18n.jar files, if the applet requires Globalization Support Your applet classes

4.

Ensure that the ZIP or JAR file is not compressed.

You can now make the applet available to users. One way to do this is to add the APPLET tag to the HTML page from which the applet will be run. For example:
<APPLET WIDTH=500 HEIGHT=200 CODE=JdbcApplet ARCHIVE=JdbcApplet.zip CODEBASE=Applet_Samples </APPLET>

Specifying an Applet in an HTML Page
The APPLET tag specifies an applet that runs in the context of an HTML page. The APPLET tag can have the following attributes: CODE, ARCHIVE, CODEBASE, WIDTH, and HEIGHT. These attributes are described in the following sections:
■ ■ ■

CODE, HEIGHT, and WIDTH CODEBASE ARCHIVE

CODE, HEIGHT, and WIDTH
The HTML page that runs the applet must have an APPLET tag with an initial width and height to specify the size of the applet display area. You use the HEIGHT and WIDTH attributes to specify the size, measured in pixels. This size should not count any windows or dialog boxes that the applet opens. The APPLET tag must also specify the name of the file that contains the compiled applet. Specify the file name with the CODE attribute. Any path specified must be relative to the base URL of the applet. The path cannot be absolute.
5-8 Oracle Database JDBC Developer's Guide and Reference

JDBC in Applets

In the following example, JdbcApplet.class is the name of the compiled applet:
<APPLET CODE="JdbcApplet" WIDTH=500 HEIGHT=200> </APPLET>

If you use this form of the CODE attribute, then the classes for the applet and the JDBC Thin driver must be in the same directory as the HTML page.
Note: Do not include the file name extension, .class, in the CODE attribute.

CODEBASE
The CODEBASE attribute is optional. It specifies the base URL of the applet, that is, the name of the directory that contains the code of the applet. If it is not specified, then the URL of the document is used. This means that the classes for the applet and the JDBC Thin driver must be in the same directory as the HTML page. For example, if the current directory is my_Dir:
<APPLET WIDTH=500 HEIGHT=200 CODE=JdbcApplet CODEBASE="." </APPLET>

The attribute, CODEBASE=".", indicates that the applet resides in the current directory, my_Dir. Now, consider that the value of CODEBASE is set to Applet_Samples, as follows:
<APPLET WIDTH=500 HEIGHT=200 CODE=JdbcApplet CODEBASE="Applet_Samples" </APPLET>

This would indicate that the applet resides in the my_Dir/Applet_Samples directory.

ARCHIVE
The ARCHIVE attribute is optional. It specifies the name of the archive file that contains the applet classes and resources the applet needs. Oracle recommends using an archive file, which saves many extra round-trips to the server. The archive file will be preloaded. If you have more than one archive file in the list, separate them with commas. In the following example, the class files are stored in the archive file, JdbcApplet.zip:
<APPLET CODE="JdbcApplet" ARCHIVE="JdbcApplet.zip" WIDTH=500 HEIGHT=200> </APPLET>

Note:

Version 3.0 browsers do not support the ARCHIVE attribute.

Features Specific to JDBC Thin 5-9

JDBC in Applets

5-10 Oracle Database JDBC Developer's Guide and Reference

6
Features Specific to JDBC OCI Driver
This chapter introduces the features specific to the Java Database Connectivity (JDBC) Oracle Call Interface (OCI) driver. It also describes the OCI Instant Client. This chapter contains the following sections:
■ ■ ■ ■ ■ ■

OCI Connection Pooling Client Result Cache Transparent Application Failover OCI Native XA OCI Instant Client Instant Client Light (English)

OCI Connection Pooling
The OCI connection pooling feature is an Oracle-designed extension. The connection pooling provided by the JDBC OCI driver enables applications to have multiple logical connections, all of which are using a small set of physical connections. Each call on a logical connection is routed on to the physical connection that is available at the given time.
See Also:

Chapter 24, "OCI Connection Pooling"

Client Result Cache
Client result cache feature enables client-side caching of SQL query result sets in client memory. In this way, OCI applications can use client memory to take advantage of the client result cache to improve response times of repetitive queries.

Usage Guidelines in JDBC
You must annotate a query with a /*+ result_cache */ hint to indicate that results are to be stored in the client result cache. For example, look at the following code snippet:
String query = "select /*+ result_cache */ * from emp where empno < : 1"; ((oracle.jdbc.OracleConnection)conn).setImplicitCachingEnabled(true); ((oracle.jdbc.OracleConnection)conn).setStatementCacheSize(10); PreparedStatement pstmt; ResultSet rs; for (int j = 0 ; j < 10 ; j++ )

Features Specific to JDBC OCI Driver

6-1

Transparent Application Failover

{ pstmt = conn.prepareStatement (query); pstmt.setInt(1,7500); rs = pstmt.executeQuery(); while (rs.next( ) ) { // see the values } rs.close; pstmt.close( ) ; } }

In the preceding example, the client result cache hint /*+ result_cache */ is annotated to the actual query, that is, select * from emp where empno < : 1. So, the first execution of the query goes to the database and the result set is cached for the remaining nine executions of the query. This improves the performance of your application significantly.
See Also:

Oracle Call Interface Programmer's Guide

You must use JDBC statement caching or cache statements at the application level when using the JDBC OCI client result cache.
See Also: "Statement and Result Set Caching" for more information on JDBC statement caching

Validation of the Client Result Cache
Validation of the JDBC OCI client result cache can be achieved in the following ways:

Client Cache Statistics Verification
JDBC OCI driver periodically sends statistics related to the client result cache to the server. These statistics that contain information such as the number of result sets successfully cached, number of cache hits, and number of cached result sets invalidated are stored in CLIENT_RESULT_CACHE_STATS$.
See Also:

Oracle Call Interface Programmer's Guide

Timing Measurement
First, you measure the time taken to run the queries without the /*+ result_cache */ hints. Then add the /*+ result_cache */ hints to the query and measure the time again. You will see the performance gain.

Transparent Application Failover
The Transparent Application Failover feature of JDBC OCI driver enables you to automatically reconnect to a database if the database instance to which the connection is made goes down. The new database connection, though created by a different node, is identical to the original.
See Also:

Chapter 27, "Transparent Application Failover"

OCI Native XA
The JDBC OCI driver also provides a feature called Native XA.

6-2 Oracle Database JDBC Developer's Guide and Reference

OCI Instant Client

See Also:

"OCI Native XA" on page 28-20

OCI Instant Client
This section covers the following topics:
■ ■ ■ ■ ■ ■ ■ ■

Overview of Instant Client Benefits of Instant Client JDBC OCI Instant Client Installation Process Usage of Instant Client Patching Instant Client Shared Libraries Regeneration of Data Shared Library and ZIP files Database Connection Names for OCI Instant Client Environment Variables for OCI Instant Client

Overview of Instant Client
The Instant Client feature makes it extremely easy to deploy OCI, Oracle C++ Call Interface (OCCI), Open Database Connectivity (ODBC), and JDBC-OCI based customer applications, by eliminating the need for an Oracle home. The storage space requirement of a JDBC OCI application running in the Instant Client mode is significantly reduced compared to the same application running on a full client-side installation. The Instant Client shared libraries occupy only about one-fourth the disk space used by a full client installation. Table 6–1 shows the Oracle client-side files required to deploy a JDBC OCI application. Library names of release 11.1 are used in the table. The number part of library names will change in future releases to agree with the release.
Table 6–1 OCI Instant Client Shared Libraries
Description for Linux and UNIX Systems Client Code Library OCI Instant Client Data Shared Library Security Library OCI Instant Client JDBC Library Microsoft Windows oci.dll oraociei11.dll orannzsbb11.dll ocijdbc11.dll All JDBC JAR files Description for Microsoft Windows Forwarding functions that applications link with Data and code Security Library OCI Instant Client JDBC Library See Also: "Check the Environment Variables" on page 2-3

Linux and UNIX Systems libclntsh.so.11.1 libociei.so libnnz11.so libocijdbc11.so

ALL JDBC Java Archive See Also: "Check the Environment (JAR) files Variables" on page 2-3

To provide Native XA functionality, you must copy the JDBC XA class library. On UNIX systems, this library, libheteroxa11.so, is located in the ORACLE_HOME/jdbc/lib directory. On Microsoft Windows, this library, heteroxa11.dll, is located in the ORACLE_HOME\bin directory.
Note:

Benefits of Instant Client
The benefits of Instant Client are the following:

Features Specific to JDBC OCI Driver

6-3

OCI Instant Client

■ ■

Installation involves copying a small number of files. The number of required files and the total disk storage on the Oracle client-side are significantly reduced. There is no loss of functionality or performance for applications deployed with the Instant Client. It is simple for independent software vendors to package applications.

JDBC OCI Instant Client Installation Process
The Instant Client libraries can be installed by choosing the Instant Client option from Oracle Universal Installer. The Instant Client libraries can also be downloaded from the Oracle Technology Network Web site. The installation process is as follows:
1. 2.

Download and install the Instant Client shared libraries and Oracle JDBC class libraries to a directory, such as instantclient. Set the library path environment variable to the directory from Step 1. For example, on UNIX systems, set the LD_LIBRARY_PATH environment variable to instantclient. On Microsoft Windows, set the PATH environment variable to locate the instantclient directory. Add the full path names of the JDBC class libraries to the CLASSPATH environment variable.

3.

After completing these steps you are ready to run the JDBC OCI application. The JDBC OCI application operates in the Instant Client mode when the OCI and JDBC shared libraries are accessible through the library path environment variable. In the Instant Client mode, there is no dependency on the ORACLE_HOME and none of the other code and data files provided in ORACLE_HOME is needed by JDBC OCI, except for the tnsnames.ora file. Instant Client can be also installed from Oracle Universal Installer by selecting the Instant Client option. The Instant Client files should always be installed in an empty directory. As with the OTN installation, you must set the LD_LIBRARY_PATH environment variable to the Instant Client directory to operate in the Instant Client mode. If you have done a complete client installation by choosing the Admin option, then the Instant Client shared libraries are also installed. The location of the Instant Client shared libraries and JDBC class libraries in a full client installation is: On Linux or UNIX systems:
■ ■

libociei.so library is in $ORACLE_HOME/instantclient libclnstsh.so.11.1, libocijdbc11.so, and libnnz11.so are in $ORACLE_HOME/lib The JDBC class libraries are in $ORACLE_HOME/jdbc/lib

On Microsoft Windows:
■ ■ ■

oraociei11.dll library is in ORACLE_HOME\instantclient oci.dll, ocijdbc11.dll, and orannzsbb11.dll are in ORACLE_HOME\bin The JDBC class libraries are in ORACLE_HOME\jdbc\lib

By copying these files to a different directory, setting the library path to locate this directory, and adding the path names of the JDBC class libraries to the CLASSPATH

6-4 Oracle Database JDBC Developer's Guide and Reference

OCI Instant Client

environment variable, you can enable running the JDBC OCI application in the Instant Client mode.
Note:

To provide Native XA functionality, you must copy the JDBC XA class library. On UNIX, this library, libheteroxa11.so, is located in ORACLE_HOME/jdbc/lib. On Windows, this library, heteroxa11.dll, is located in ORACLE_HOME\bin. All the libraries must be copied from the same ORACLE_HOME and must be placed in the same directory. On hybrid platforms, such as Sparc64, if the JDBC OCI driver needs to be operated in the Instant Client mode, then you must copy the libociei.so library from the ORACLE_HOME/instantclient32 directory. You must copy all other Sparc64 libraries needed for the JDBC OCI Instant Client from the ORACLE_HOME/lib32 directory. Only one set of Oracle libraries should be specified in the library path environment variable. That is, if you have multiple directories containing Instant Client libraries, then only one such directory should be specified in the library path environment variable. If you have an Oracle home on your computer, then you should not have the ORACLE_HOME/lib and Instant Client directories in the library path environment variable simultaneously, regardless of the order in which they appear in the variable. That is, only one of ORACLE_HOME/lib directory (for non-Instant Client operation) or Instant Client directory (for Instant Client operation) should be specified in the library path environment variable. Oracle recommends that you download Instant Client from Oracle Technology Network (OTN)
http://www.oracle.com/technology/tech/oci/instantclien t/instantclient.html

Usage of Instant Client
Instant Client is a deployment feature and should be used for running production applications. For development, a full installation is necessary to access demonstration programs and so on. In general, all JDBC OCI functionality is available to an application being run in the Instant Client mode, except that the Instant Client mode is for client-side operation only. Therefore, server-side external procedures cannot operate in the Instant Client mode.

Patching Instant Client Shared Libraries
Because Instant Client is a deployment feature, the emphasis has been on reducing the number and size of files required to run a JDBC OCI application. Therefore, all files needed to patch Instant Client shared libraries are not available in an Instant Client deployment. An ORACLE_HOME based full client installation is needed to patch the Instant Client shared libraries. The opatch utility will take care of patching the Instant Client shared libraries.

Features Specific to JDBC OCI Driver

6-5

OCI Instant Client

Note:

On Microsoft Windows, you cannot patch the shared libraries.

After applying the patch in an ORACLE_HOME environment, copy the files listed in Table 6–1, " OCI Instant Client Shared Libraries" to the instant client directory as described in "JDBC OCI Instant Client Installation Process". Instead of copying individual files, you can generate Instant Client ZIP files for OCI, OCCI, JDBC, and SQL*Plus as described in "Regeneration of Data Shared Library and ZIP files". Then, you can copy the ZIP files to the target computer and unzip them as described in "JDBC OCI Instant Client Installation Process". The opatch utility stores the patching information of the ORACLE_HOME installation in libclnstsh.so.11.1. This information can be retrieved by the following command:
genezi -v

Note that if the computer from where Instant Client is deployed does not have the genezi utility, then it must be copied from the ORACLE_HOME/bin directory on the computer that has the ORACLE_HOME installation.

Regeneration of Data Shared Library and ZIP files
The OCI Instant Client Data Shared Library, libociei.so, can be regenerated by performing the following steps in an Administrator Installation of ORACLE_HOME:
mkdir -p $ORACLE_HOME/rdbms/install/instantclient/light cd $ORACLE_HOME/rdbms/lib make -f ins_rdbms.mk ilibociei

A new version of the libociei.so Data Shared Library based on the current files in the ORACLE_HOME is then placed in the ORACLE_HOME/rdbms/install/instantclient directory. Note that the location of the regenerated Data Shared Library, libociei.so, is different from that of the original Data Shared Library, libociei.so, which is located in the ORACLE_HOME/instantclient directory. The preceding steps also generate Instant Client ZIP files for OCI, OCCI, JDBC, and SQL*Plus. Regeneration of data shared library and ZIP files is not available on Microsoft Windows platforms.

Database Connection Names for OCI Instant Client
All Oracle Net naming methods that do not require the ORACLE_HOME or TNS_ADMIN environment variables to locate configuration files, such as tnsnames.ora or sqlnet.ora, work in the Instant Client mode. In particular, the connection string can be specified in the following formats:

A Thin-style connection string of the form:
host:port:service_name

For example:
url="jdbc:oracle:oci:@//example.com:5521:bjava21"

A SQL connection URL string of the form:

6-6 Oracle Database JDBC Developer's Guide and Reference

OCI Instant Client

//host:[port][/service name]

For example:
url="jdbc:oracle:oci:@//example.com:5521/bjava21

As an Oracle Net keyword-value pair. For example:
url="jdbc:oracle:oci:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp) (HOST=dlsun242) (PORT=5521)) (CONNECT_DATA=(SERVICE_NAME=bjava21)))"

Naming methods that require TNS_ADMIN to locate configuration files continue to work if the TNS_ADMIN environment variable is set.
See Also: Oracle Database Net Services Administrator's Guide for more information about connection formats

If the TNS_ADMIN environment variable is not set and TNSNAMES entries, such as inst1, are used, then the ORACLE_HOME environment variable must be set and the configuration files are expected to be in the $ORACLE_HOME/network/admin directory.
Note:

In this case, the ORACLE_HOME environment variable is used only for locating Oracle Net configuration files. No other component of Client Code Library uses the value of the ORACLE_HOME environment variable.

The empty connection string is not supported. However, an alternate way to use the empty connection string is to set the TWO_TASK environment variable on UNIX systems, or the LOCAL variable on Microsoft Windows, to either a tnsnames.ora entry or an Oracle Net keyword-value pair. If TWO_TASK or LOCAL is set to a tnsnames.ora entry, then the tnsnames.ora file must be loaded by the TNS_ADMIN or ORACLE_HOME setting. Example Consider that the listener.ora file on the database server contains the following information:
LISTENER = (ADDRESS_LIST=(ADDRESS=(PROTOCOL=tcp)(HOST=server6)(PORT=1573))) SID_LIST_LISTENER = (SID_LIST= (SID_DESC=(SID_NAME=rdbms3) (GLOBAL_DBNAME=rdbms3.server6.us.alchemy.com) (ORACLE_HOME=/home/dba/rdbms3/oracle)))

You can connect to this server in one of the following ways:
url = "jdbc:oracle:oci:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp) (HOST=server6)(PORT=1573)) (CONNECT_DATA=(SERVICE_NAME=rdbms3.server6.us.alchemy.com)))"

or:
url = "jdbc:oracle:oci:@//server6:1573/rdbms3.server6.us.alchemy.com"

Alternatively, you can set the TWO_TASK environment variable to any of the connection strings and connect to the database server without specifying the
Features Specific to JDBC OCI Driver 6-7

If this tnsnames. then you can set the TNS_ADMIN environment variable (or LOCAL on Microsoft Windows) as follows: setenv TNS_ADMIN /home/webuser/instantclient Now. However.ora file contains the following: conn_str = (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=server6)(PORT=1573)) (CONNECT_DATA=(SERVICE_NAME=rdbms3.com)))" or: setenv TWO_TASK //server6:1573/rdbms3. as specified previously.ora file.server6.ora file is located in the /network/server6/home/dba/oracle/network/admin directory in the Oracle home. if the variable is 6-8 Oracle Database JDBC Developer's Guide and Reference .com))) If this tnsnames.OCI Instant Client connection string along with the sqlplus command.server6.us. you can set the ORACLE_HOME environment variable as follows: setenv ORACLE_HOME /network/server6/home/dba/oracle Now. then instead of using TNS_ADMIN to locate the tnsnames. then TWO_TASK can be set to: setenv TWO_TASK conn_str You can then connect with the following URL: url = "jdbc:oracle:oci:@" Environment Variables for OCI Instant Client The ORACLE_HOME environment variable no longer determines the location of the Globalization Support files and error message files.ora file.ora file.com Now. you can connect as follows: url = "jdbc:oracle:oci:@conn_str" Note: The TNS_ADMIN environment variable specifies the directory where the tnsnames. TNS_ADMIN does not specify the full path of the tnsnames. For example. An OCI-only application does not require the ORACLE_HOME environment variable to be set.ora can be located by TNS_ADMIN or ORACLE_HOME. you can connect to the database server using the following URL: url = "jdbc:oracle:oci:@" The connection string can also be stored in the tnsnames.us. However. you can connect with either of the conn_str connection strings. instead it specifies the directory.alchemy. For example. If tnsnames. consider that the tnsnames. set the TWO_TASK environment in one of the following ways: setenv TWO_TASK "(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=server6)(PORT=1573)) (CONNECT_DATA=(SERVICE_NAME=rdbms3.ora file is located.ora file is located in the /home/webuser/instantclient directory.us.alchemy.server6.alchemy.

dat On Microsoft Windows: set ORA_TZFILE timezlrg.so. libociicus. Even though the ORACLE_HOME environment variable is not required to be set. This reduces the disk space requirements of the client installation by about 63 MB. then the ORA_TZFILE variable. Table 6–2 Platform Sun Solaris Linux Microsoft Windows Data Shared Library for Instant Client and Instant Client Light (English) Instant Client libociei. if the ORA_TZFILE variable is not set. names a complete path name. then the smaller. Instant Client Light is designed for applications that require English-only error messages and use either US7ASCII. If the Data Shared Library is not available. The table also specifies the size of each data shared library in parentheses following the library file name. if it is set. default. Instant Client Light is a significantly smaller version of Instant Client.dll (15 MB) Features Specific to JDBC OCI Driver 6-9 . Instant Client Light (English) The lightweight version of Instant Client is called Instant Client Light (English).Instant Client Light (English) set. as it does in previous Oracle Database releases. then set the ORA_TZFILE environment variable to the name of the file without any absolute or relative path names. then the ORACLE_HOME/network/admin directory must contain Oracle Net Services configuration files.dll (85 MB) Instant Client Light (English) libociicus. That is: On UNIX systems: setenv ORA_TZFILE timezlrg. then.dat file from the Data Shared Library is used. Table 6–2 lists the names of the data shared libraries for Instant Client and Instant Client Light (English) on different platforms. OCI will always obtain its data from the Data Shared Library. If the larger timezlrg. Therefore. WE8DEC.so on UNIX systems. or one of the Unicode character sets.so (4 MB) oraociicus11.dat If the driver is not operating in the Instant Client mode.dat file is to be used from the Data Shared Library. which is 67 MB in size. Environment variables ORA_NLS10 and ORA_NLSPROFILES33 are ignored in the Instant Client mode. Instant Client Light is the short name. only then is the ORACLE_HOME environment variable used and a full client installation is assumed.so (67 MB) oraociei11.so (4 MB) libociicus. which is 4 MB in size and a subset of the data shared library. In the Instant Client mode. if set.so (67 MB) libociei. timezone. then it does not have an impact on the operation of the OCI driver. If TNSNAMES entries are used. libociei. This is achieved by the lightweight Data Shared Library. the TNS_ADMIN directory must contain the TNSNAMES configuration files. the name Instant Client Light (English). and if TNS_ADMIN is not set. as mentioned earlier. then it must be set to a valid operating system path name that identifies a directory. The lightweight data shared library supports only a few character sets and error messages that are only in English.

the valid values for the NLS_LANG setting are of the type: American_territory. and character set as language_territory.so in the LD_LIBRARY_PATH environment variable in UNIX 6-10 Oracle Database JDBC Developer's Guide and Reference . Therefore. Operation To operate in the Instant Client Light mode. territory. the error messages obtained are only in English. Instant Client Light can operate with the OCI environment handles created in the OCI_UTF16 mode.characterset.Instant Client Light (English) This section covers the following topics: ■ ■ ■ Globalization Settings Operation Installation Globalization Settings The NLS_LANG setting determines the language. an application must set the LD_LIBARARY_PATH environment variable in UNIX systems or the PATH environment variable in Microsoft Windows to a location containing the client and data shared libraries. See Also: Oracle Database Globalization Support Guide for more information about NLS settings. libociei.characterset where. language can only be American. OCI applications by default look for the OCI Data Shared Library. territory can be any valid and supported territory and characterset can be any one the previously listed character sets. and characterset can be any one of the following: ■ Single-byte – – – – US7ASCII WE8DEC WE8MSWIN1252 WE8ISO8859P1 ■ Unicode – – – UTF8 AL16UTF16 AL32UTF8 Specifying character set or national character set other than those listed as the client or server character set or setting the language in NLS_LANG on the client will throw one of the following errors: ■ ■ ■ ■ ORA-12734 ORA-12735 ORA-12736 ORA-12737 With Instant Client Light. In Instant Client Light. territory can be any that is supported.

Instant Client Light (English)

systems or the oraociei11.dll Data Shared Library in the PATH environment variable in Microsoft Windows, to determine if the application should operate in the Instant Client mode. In case this library is not found, then OCI tries to load the Instant Client Light Data Shared Library, libociicus.so in UNIX systems or libociicus11.dll in Microsoft Windows. If this library is found, then the application operates in the Instant Client Light mode. Otherwise, a non-Instant Client mode is assumed.

Installation
Instant Client Light can be installed in one of the following ways:

From OTN You can download the required file from http://www.oracle.com/technology/tech/oci/instantclient/insta ntclient.html For Instant Client Light, instead of downloading and expanding the Basic package, download and unzip the Basic Light package. The instantclient_11_1 directory in which the lightweight libraries are unzipped should be empty before unzipping the files.

From Client Admin Install Instead of copying libociei.so or oraociei11.dll from the ORACLE_HOME/instantclient directory, copy libociicus.so or oraociic10.dll from the ORACLE_HOME/instantclient/light directory. That is, the Instant Client directory on the LD_LIBRARY_PATH environment variable, in UNIX systems, should contain the Instant Client Light Data Shared Library, libociicus.so, instead of the larger OCI Instant Client Data Shared Library, libociei.so. In Microsoft Windows, the PATH environment variable should contain oraociicus11.dll instead of oraociei11.dll.

From Oracle Universal Installer If the Instant Client option is selected from Oracle Universal Installer, then libociei.so (or oraociei11.dll on Microsoft Windows) is installed in the base directory of the installation which is going to be placed on the LD_LIBRARY_PATH environment variable. This is so that Instant Client Light is not enabled by default. The Instant Client Light Data Shared Library, libociicus.so (or oraociicus11.dll on Microsoft Windows), is installed in the light subdirectory of the base directory. Therefore, to operate in the Instant Client Light mode, the OCI Data Shared Library, libociei.so (or oraociei11.dll on Windows) must be deleted or renamed and the Instant Client Light Data Shared Library must be copied from the light subdirectory to the base directory of the installation. For example, if Oracle Universal Installer has installed the Instant Client in my_oraic_11_1 directory on the LD_LIBRARY_PATH environment variable, then one would need to do the following to operate in the Instant Client Light mode:
cd my_oraic_11_1 rm libociei.so mv light/libociicus.so .

Features Specific to JDBC OCI Driver 6-11

Instant Client Light (English)

Note:

All the Instant Client files should always be copied or installed in an empty directory. This is to ensure that no incompatible binaries exist in the installation.

6-12 Oracle Database JDBC Developer's Guide and Reference

7
Server-Side Internal Driver
This chapter covers the following topics:
■ ■ ■ ■ ■ ■

Overview of the Server-Side Internal Driver Connecting to the Database Exception-Handling Extensions Session and Transaction Context Testing JDBC on the Server Loading an Application into the Server

Overview of the Server-Side Internal Driver
The server-side internal driver is intrinsically tied to Oracle Database and to the Java Virtual Machine (JVM). The driver runs as part of the same process as the database. It also runs within the default session, the same session in which the JVM was started. The server-side internal driver is optimized to run within the database server and provide direct access to SQL data and PL/SQL subprograms on the local database. The entire JVM operates in the same address space as the database and the SQL engine. Access to the SQL engine is a function call. This enhances the performance of your Java Database Connectivity (JDBC) applications and is much faster than running a remote Oracle Net call to access the SQL engine. The server-side internal driver supports the same features, application programming interfaces (APIs), and Oracle extensions as the client-side drivers. This makes application partitioning very straightforward. For example, if you have a Java application that is data-intensive, then you can easily move it into the database server for better performance, without having to modify the application-specific calls.

Connecting to the Database
As described in the preceding section, the server-side internal driver runs within a default session. Therefore, you are already connected. There are two methods to access the default connection:

Use the OracleDataSource.getConnection method, with any of the following forms as the URL string: – – – jdbc:oracle:kprb jdbc:default:connection jdbc:oracle:kprb:

Server-Side Internal Driver 7-1

Connecting to the Database


jdbc:default:connection:

Use the Oracle-specific defaultConnection method of the OracleDriver class.

Using defaultConnection is generally recommended.
Note:

You are no longer required to register the OracleDriver class for connecting with the server-side internal driver.

Connecting with the OracleDriver Class defaultConnection Method The defaultConnection method of the oracle.jdbc.OracleDriver class is an Oracle extension and always returns the same connection object. Even if you call this method multiple times, assigning the resulting connection object to different variable names, then only a single connection object is reused. You need not include a connection string in the defaultConnection call. For example:
import java.sql.*; import oracle.jdbc.*; class JDBCConnection { public static Connection connect() throws SQLException { Connection conn = null; try { // connect with the server-side internal driver conn = ora.defaultConnection(); } } catch (SQLException e) {...} return conn; } }

Note that there is no conn.close call in the example. When JDBC code is running inside the target server, the connection is an implicit data channel, not an explicit connection instance as from a client. It should not be closed. If you do call the close method, then be aware of the following:

All connection instances obtained through the defaultConnection method, which actually reference the same database connection, will be closed and unavailable for further use, with state and resource cleanup as appropriate. Running defaultConnection afterward would result in a new connection object. Even though the connection object is closed, the implicit connection to the database will not be closed.

Connecting with the OracleDataSource.getConnection Method To connect to the internal server connection from code that is running within the target server, you can use the OracleDataSource.getConnection method with either of the following URLs:
OracleDataSource ods = new OracleDataSource(); ods.setURL("jdbc:oracle:kprb");

7-2 Oracle Database JDBC Developer's Guide and Reference

Exception-Handling Extensions

Connection conn = ods.getConnection();

or:
OracleDataSource ods = new OracleDataSource(); ods.setURL("jdbc:default:connection"); Connection conn = ods.getConnection();

or:
OracleDataSource ods = new OracleDataSource(); ods.setURL("jdbc:oracle:kprb:"); Connection conn = ods.getConnection();

or:
OracleDataSource ods = new OracleDataSource(); ods.setURL("jdbc:default:connection:"); Connection conn = ods.getConnection();

Any user name or password you include in the URL is ignored in connecting to the default server connection. The OracleDataSource.getConnection method returns a new Java Connection object every time you call it. The fact that OracleDataSource.getConnection returns a new connection object every time you call it is significant if you are working with object maps or type maps. A type map is associated with a specific Connection object and with any state that is part of the object. If you want to use multiple type maps as part of your program, then you can call getConnection to create a new Connection object for each type map.
Note:

Although the OracleDataSource.getConnection method is returning a new object every time you call it, it is not creating a new database connection every time.

Exception-Handling Extensions
The server-side internal driver, in addition to having standard exception-handling capabilities, such as getMessage(), getErrorCode(), and getSQLState(), provides the oracle.jdbc.driver.OracleSQLException class, which is a legacy from the earliest server-side internal driver. This class is a subclass of the standard java.sql.SQLException class and is not available to the client-side JDBC drivers or the server-side Thin driver. When an error condition occurs in the server, it often results in a series of related errors being placed in an internal error stack. The JDBC server-side internal driver retrieves errors from the stack and places them in a chain of OracleSQLException objects. You can use the following methods in processing these exceptions:

SQLException getNextException() This method returns the next exception in the chain or a null value if there are no further exceptions. You can start with the first exception you receive and work through the chain. This is a standard method.

int getNumParameters() (Oracle extension) Errors from the server usually include parameters, or variables, that are part of the error message. These may indicate what type of error occurred, what kind of

Server-Side Internal Driver 7-3

Session and Transaction Context

operation was being attempted, or the invalid or affected values. This method returns the number of parameters included with this error. It is an Oracle extension.

Object[] getParameters() (Oracle extension) This method returns a Java Object[] array containing the parameters included with this error. It is an Oracle extension.

However, in 11g release 1, only a subset of the exceptions thrown by the driver are instances of this class. In 11g release 1 (11.1), this class is deprecated and will be removed in the next release.

Note:

Oracle strongly discourages the use of this class.

Exception-handling differs depending on the version of JDK you are using.

Session and Transaction Context
The server-side driver operates within a default session and default transaction context. The default session is the session in which the JVM was started. In effect, you are already connected to the database on the server. This is different from the client-side where there is no default session. You must explicitly connect to the database. Auto-commit mode is disabled in the server. You must manage transaction COMMIT and ROLLBACK operations explicitly by using the appropriate methods on the connection object:
conn.commit();

or:
conn.rollback();

Note:

As a best practice, it is recommended not to commit or rollback a transaction inside the server.

Testing JDBC on the Server
Almost any JDBC program that can run on a client can also run on the server. All the programs in the samples directory can be run on the server, with only minor modifications. Usually, these modifications concern only the connection statement. Consider the following code fragment which obtains a connection to a database:
ods.setUrl( "jdbc:oracle:oci:@(DESCRIPTION= (ADDRESS=(PROTOCOL=TCP)(HOST=cluster_alias) (PORT=1521)) (CONNECT_DATA=(SERVICE_NAME=service_name)))"); ods.setUser("scott"); ods.setPassword("tiger"); Connection conn = ods.getConnection();

7-4 Oracle Database JDBC Developer's Guide and Reference

Loading an Application into the Server

We can modify this code fragment for use in the server-side internal driver. In the server-side internal driver, no user, password, or database information is necessary. For the connection statement, you use:
ods.setUrl( "jdbc:oracle:kprb:@"); Connection conn = ods.getConnection();

However, the most convenient way to get a connection is to call the OracleDriver.defaultConnection method, as follows:
Connection conn = OracleDriver.defaultConnection();

Loading an Application into the Server
When loading an application into the server, you can load .class files that you have already compiled on the client or you can load .java source files and have them automatically compiled on the server. In either case, use the loadjava utility to load your files. You can either specify source file names on the command line or put the files into a Java Archive (JAR) file and specify the JAR file name on the command line. The loadjava script, which runs the actual utility, is in the bin directory in your Oracle home. This directory should already be in your path once Oracle has been installed.
Note:

The loadjava utility supports compressed files.

Loading Class Files into the Server Consider a case where you have the following three class files in your application: Foo1.class, Foo2.class, and Foo3.class. Each class is written into its own class schema object in the server. You can load the class files using the default JDBC Oracle Call Interface (OCI) driver in the following ways:

Specifying the individual class file names, as follows:
loadjava -user scott Foo1.class Foo2.class Foo3.class Password: password

Specifying the class file names using a wildcard, as follows:
loadjava -user scott Foo*.class Password: password

Specifying a JAR file that contains the class files, as follows:
loadjava -user scott Foo.jar Password: password

You can load the files using the JDBC Thin driver, as follows:
loadjava -thin -user scott@localhost:1521:ORCL Foo.jar Password: password

Server-Side Internal Driver 7-5

Loading an Application into the Server

Note:

Because the server-side embedded JVM uses Java Development Kit (JDK) 1.5, it is advisable to compile classes under JDK 1.5, if they will be loaded into the server. This will catch incompatibilities during compilation, instead of at run time.

Loading Source Files into the Server If you enable the loadjava -resolve option when loading a .java source file, then the server-side compiler will compile your application as it is loaded, resulting in both a source schema object for the original source code and one or more class schema objects for the compiled output. If you do not specify -resolve, then the source is loaded into a source schema object without any compilation. In this case, however, the source is implicitly compiled the first time an attempt is made to use a class defined in the source. For example, run loadjava as follows to load and compile Foo.java, using the default JDBC OCI driver:
loadjava -user scott -resolve Foo.java Password: password

Or, use the following command to load using the JDBC Thin driver:
loadjava -thin -user scott@localhost:1521:ORCL -resolve Foo.java Password: password

Either of these will result in appropriate class schema objects being created in addition to the source schema object.

Note:

Oracle generally recommends compiling source on the client, whenever possible, and loading the .class files instead of the source files into the server.

7-6 Oracle Database JDBC Developer's Guide and Reference

Part III
Connection and Security
This part consists of chapters that discuss the use of data sources and URLs to connect to the database. It also includes chapters that discuss the security features supported by the Oracle Java Database Connectivity (JDBC) Oracle Call Interface (OCI) and Thin drivers, Secure Sockets Layer (SSL) support in JDBC Thin driver, and middle-tier authentication through proxy connections. Part III contains the following chapters:
■ ■ ■

Chapter 8, "Data Sources and URLs" Chapter 9, "JDBC Client-Side Security Features" Chapter 10, "Proxy Authentication"

You can use both facilities in the same application. The data source facility provides a complete replacement for the previous JDBC DriverManager facility. general-use objects for specifying databases or other resources to use. as well as the URLs that describe databases. This section covers the following topics: ■ ■ ■ ■ ■ ■ ■ ■ ■ Overview of Oracle Data Source Support for JNDI Features and Properties of Data Sources Creating a Data Source Instance and Connecting Creating a Data Source Instance. For convenience and portability. The JDBC 2.0 extension application programming interface (API) introduced the concept of data sources. so that you can access databases by logical names. and Connecting Supported Connection Properties Using Roles for SYS Login Configuring Database Remote Login Bequeath Connection and SYS Logon Properties for Oracle Performance Extensions Overview of Oracle Data Source Support for JNDI The JNDI standard provides a way for applications to find and access remote services and resources. Data Sources and URLs 8-1 . but it is recommended that you transition your application to data sources. These services can be any enterprise services. for a JDBC application. However. data sources can be bound to Java Naming and Directory Interface (JNDI) entities. Registering with JNDI. This chapter contains the following sections: ■ ■ Data Sources Database URLs and Database Specifiers Data Sources Data sources are standard. these services would include database connections and services.8 Data Sources and URLs This chapter discusses connecting applications to databases using Java Database Connectivity (JDBC) data sources.

The DataSource Interface and Oracle Implementation A JDBC data source is an instance of a class that implements the standard javax. The developer is not required to use this functionality. These properties follow the JavaBeans design pattern.pool package. removing vendor-specific syntax from application code. . This would take priority over the property settings. provides a set of properties that can be used to specify a database to connect to. because it has been tested with the Oracle drivers. You must add it to the CLASSPATH environment variable separately. This ensures that the code for opening database connections is portable to other environments. but accessing databases through JNDI logical names makes the code more portable.sql.Referenceable interfaces.DataSource interface: public interface DataSource { Connection getConnection() throws SQLException. All Oracle JDBC data sources are JNDI-referenceable. you can set properties using appropriate setter methods. The overloaded getConnection method returns a connection to the database. 8-2 Oracle Database JDBC Developer's Guide and Reference . } Oracle implements this interface with the OracleDataSource class in the oracle.Serializable and javax. You can also obtain it from the Sun Microsystems Web site. This file is included with the Java products on the installation CD.naming. For alternative user names and passwords. JNDI has the functionality to associate a logical name with a particular source for a desired service. you do not need to register the vendor-specific JDBC driver class name and you can use logical names for URLs and other properties... String password) throws SQLException. Connection getConnection(String username.jar file to be in the CLASSPATH environment variable. Properties of DataSource The OracleDataSource class. Note: The OracleDataSource class and all subclasses implement the java. but it is advisable to use the version from Oracle.io.jdbc. Note: Using JNDI functionality requires the jndi. as with any class that implements the DataSource interface. To use other values. Features and Properties of Data Sources By using the data source functionality with JNDI.Data Sources JNDI allows an application to use logical names in accessing these services. you can also use the getConnection method that takes these parameters as input.

there is no getPassword() method. Number of the port where the server listens for requests Name of the database server Name for the login databaseName dataSourceName description networkProtocol String String password portNumber serverName user String int String String The OracleDataSource class implements the following setter and getter methods for the standard properties: ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ public synchronized void setDatabaseName(String dbname) public synchronized String getDatabaseName() public synchronized void setDataSourceName(String dsname) public synchronized String getDataSourceName() public synchronized void setDescription(String desc) public synchronized String getDescription() public synchronized void setNetworkProtocol(String np) public synchronized String getNetworkProtocol() public synchronized void setPassword(String pwd) public synchronized void setPortNumber(int pn) public synchronized int getPortNumber() public synchronized void setServerName(String sn) public synchronized String getServerName() public synchronized void setUser(String user) public synchronized String getUser() Note: For security reasons. The properties in Table 8–1 are standard properties according to the Sun Microsystems specification. Description of the data source. Name of the underlying data source class. Data Sources and URLs 8-3 . For Oracle. Password for the connecting user. this is an underlying pooled connection data source class.Data Sources Table 8–1 and Table 8–2 list OracleDataSource properties. Note: Oracle does not implement the standard roleName property. For distributed transactions. Network protocol for communicating with the server. this applies only to the JDBC Oracle Call Interface (OCI) drivers and defaults to tcp. Also known as the SID in Oracle terminology. The properties in Table 8–2 are Oracle extensions. For connection pooling. Table 8–1 Name Standard Data Source Properties Type String String Description Name of the particular database on the server. this is an underlying XA data source class.

The TNS entry name corresponds to the TNS entry specified in the tnsnames. or kprb. If the tnsEntry property is not set when using the Native XA feature. It can be one of oci. Specifies whether the implicit statement connection cache is enabled. roperties String Specifies Oracle JDBC driver type. You can use this property in place of the Oracle tnsEntry and driverType properties and the standard portNumber. Provided as a convenience.Pri Specifies the log writer for this data source. and databaseName properties. This property is only for OracleXADatasource. Specifies the TNS entry name.Data Sources Table 8–2 Name connectionCacheName Oracle Extended Data Source Properties Type String Description Specifies the name of the cache. serverName.1. relevant only for the OCI driver. connectionCacheProperties connectionCachingEnabled connectionProperties driverType java. java. Allows an OracleXADataSource using the Native XA feature with the OCI driver. This DataSource property defaults to false. networkProtocol. This cannot be changed after the cache has been created. This property is only for OracleXADatasource.ora configuration file. fastConnectionFailoverEnabled Boolean implicitCachingEnabled loginTimeout Boolean int logWriter maxStatements serviceName tnsEntry java. If the nativeXA property is enabled. to access Oracle pre-8. Enable this OracleXADataSource property when using the Native XA feature with the OCI driver. nativeXA Boolean ONSConfiguration String Specifies the ONS configuration string that is used to remotely subscribe to FaN/ONS events. Specifies the database service name for this data source. to access Oracle pre-8. thin.P Specifies the connection properties. Specifies the maximum time in seconds that this data source will wait while attempting to connect to a database. 8-4 Oracle Database JDBC Developer's Guide and Reference . roperties Boolean Specifies whether implicit connection cache is in use. be sure to set the tnsEntry property as well.P Specifies properties for implicit connection cache. then a SQLException with error code ORA-17207 is thrown url String Specifies the URL of the database connection string.io.util. ntWriter int String String Specifies the maximum number of statements in the application cache.6 databases and later. it can help you migrate from an older Oracle Database.util.6 databases and later.1. Specifies whether Fast Connection Failover is in use.

Data Sources Note: ■ This table omits properties that supported the deprecated connection cache based on OracleConnectionCache. For more information about the properties of the connection refer to "Supported Connection Properties" on page 8-8. use Native XA whenever possible.Properties cp) java. that is. If you are using the JDBC Thin or OCI driver.Properties cp) Note: Use the setConnectionProperties method to set the properties of the connection and the setConnectionCacheProperties method to set the properties of the connection cache. Because Native XA performs better than Java XA.util. ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ boolean getConnectionCachingEnabled() void setImplicitCachingEnabled() String getDriverType() void setDriverType(String dt) String getURL() void setURL(String url) String getTNSEntryName() void setTNSEntryName(String tns) boolean getNativeXA() void setNativeXA(boolean nativeXA) String getONSConfiguration() void setONSConfiguration(String onsConfig) If you are using the server-side internal driver. ■ The OracleDataSource class implements the following setXXX and getXXX methods for the Oracle extended properties: ■ ■ ■ ■ ■ String getConnectionCacheName() java.util.util. then any other property settings are ignored. then note the following: ■ A URL setting can include settings for user and password.Properties getConnectionProperties() void setConnectionProperties(java.util. For more information about the properties of the connection refer to "Connection Cache Properties" on page 21-8. in which case this takes precedence over individual user and password property settings: Data Sources and URLs 8-5 . as in the following example.Properties getConnectionCacheProperties() void setConnectionCacheProperties(java. the driverType property is set to kprb.

serverName. Create an OracleDataSource instance. and Connecting This section exhibits JNDI functionality in using data sources to connect to a database. driverType. either directly through the URL setting or through the getConnection call. 8-6 Oracle Database JDBC Developer's Guide and Reference . Note that this requires vendor-specific. initialize its connection properties as appropriate. "lion"). The user and password settings in a getConnection call take precedence over any property settings. ods. override the user name and password. hard-coded property settings. ods. as in the following example: OracleDataSource ods = new OracleDataSource(). which presumes the url property is not set. you can create portable code by using the logical name in creating data sources from which you will get your connection instances. portNumber. Or. ods. not in a JDBC application. Note: Creating and registering data sources is typically handled by a JNDI administrator. From that point onward.setDriverType("oci"). and the networkProtocol is set to ipc. Registering with JNDI. Connection conn = ods. If the url property is set. as follows: Connection conn = ods. If the tnsEntry property is set. Vendor-specific.setPassword("tiger"). note that getConnectionCacheName() will return the name of the cache only if the ConnectionCacheName property of the data source is set after caching is enabled on the data source. serverName. then any tnsEntry.setNetworkProtocol("tcp"). Creating a Data Source Instance. ods. optionally. ■ ■ ■ Also. ods. ods.setPortNumber(1521). networkProtocol. portNumber.getConnection("bill". Creating a Data Source Instance and Connecting This section shows an example of the most basic use of a data source to connect to a database. and networkProtocol settings are ignored. then any databaseName. which presumes the driverType property is set to oci. without using JNDI functionality.setUser("scott").setServerName("dlsun999"). hard-coded property settings are required only in the portion of code that binds a data source instance to a JNDI logical name. and databaseName property settings are ignored. If you are using an OCI driver. and get a connection instance.getConnection().Data Sources jdbc:oracle:thin:scott/tiger@localhost:1521:orcl ■ Settings for user and password are required. then any other property settings are ignored.setDatabaseName("816"). ods.

In this example. ods). ods.getConnection(). and then initialize its properties as appropriate. which is otherwise a Java Object. ods. ods.setDriverType("oci").lookup("jdbc/sampledb").0 Specification requires that all JDBC data sources be registered in the jdbc naming subcontext of a JNDI namespace or in a child subcontext of the jdbc subcontext. Doing this requires casting the lookup result. ods. as shown in the preceding example. the JNDI name specifies the subcontext jdbc under the root naming context and specifies the logical name sampledb within the jdbc subcontext.setNetworkProtocol("tcp"). use the logical JNDI name.Data Sources Initialize Data Source Properties Create an OracleDataSource instance.setPortNumber(1521).setServerName("dlsun999"). as in the following example: Context ctx = new InitialContext(). Connection conn = odsconn. Register the Data Source Once you have initialized the connection properties of the OracleDataSource instance ods.bind call binds the OracleDataSource instance to a logical JNDI name.bind("jdbc/sampledb". you can register this data source instance with JNDI. Calling the JNDI InitialContext() constructor creates a Java object that references the initial JNDI naming context. instruct JNDI which service provider to use. ods. The ctx. ods. Open a Connection To perform a lookup and open a connection to the database logically bound to the JNDI name. The JNDI namespace has a hierarchy similar to that of a file system. The logical name jdbc/sampledb is logically bound to this database. which are not shown.setUser("scott").naming package. Note: The JDBC 2.setPassword("tiger"). you can use the logical name jdbc/sampledb in opening a connection to the database described by the properties of the OracleDataSource instance ods. Data Sources and URLs 8-7 . The Context interface and InitialContext class are in the standard javax. This means that anytime after the ctx. ods. as in the following example: OracleDataSource ods = new OracleDataSource().setDatabaseName("816"). ctx. System properties. to OracleDataSource and then using its getConnection method to open the connection. Here is an example: OracleDataSource odsconn = (OracleDataSource)ctx.bind call.

Ensure that you keep the two files synchronized.ora. we can get a connection as SYS by setting the internal_logon property. because Oracle Database security system requires a password file for remote connections as an administrator. For a bequeath connection.Data Sources Supported Connection Properties For a detailed list of connection properties that Oracle JDBC drivers support. Stop the database. see the Javadoc.ora file is located at ORACLE_HOME/dbs/ and also at ORACLE_HOME/admin/db_name/pfile/. password is the password for the user SYS. The syntax for the password file name is different on Microsoft Windows and UNIX.ora file is located at %ORACLE_BASE%\ADMIN\db_name\pfile\. Set a password file on the server-side or on the remote database. It can be altered using the ALTER USER statement in SQL Plus. You can add a password file for user sys as follows: ■ In UNIX orapwd file=$ORACLE_HOME/dbs/orapw entries=200 Enter password: password ■ In Microsoft Windows orapwd file=%ORACLE_HOME%\database\PWDsid_name. Perform the following: 1. See Also: 2. Configuring Database Remote Login Before the JDBC Thin driver can connect to the database as SYSDBA. set the internal_logon connection property to SYSDBA or SYSOPER. For a remote connection. Oracle Database Administrator's Guide Enable remote login as sysdba. You should set entries to a value higher than the number of entries you expect. we need additional password file setting procedures. or init. 8-8 Oracle Database JDBC Developer's Guide and Reference .ora. in Microsoft Windows: remote_login_passwordfile=exclusive The initservice_name. Using Roles for SYS Login To specify the role for the SYS login. you must configure the user. using the orapwd password utility. This step grants SYSDBA and SYSOPER system privileges to individual users and lets them connect as themselves. To logon as SYS.ora entries=200 Enter password: password file must be the name of the password file. Note: The ability to specify a role is supported only for the sys user name. use the internal_logon connection property. and add the following line to initservice_name. in UNIX. The init.

prop. the inst1 is a remote database String url = "jdbc:oracle:thin:@//myHost:1521/service_name".Properties(). // set neccessary properties java.jdbc. prop.*. import oracle.put("user".sql. // set the url // the url can use oci driver as well as: // url = "jdbc:oracle:oci8:@inst1".Data Sources 3.util. Verify whether SYS has the SYSDBA privilege. This example works regardless of the database's national-language settings of the database. prop.*. "sys"). This is an optional step. /** case of remote connection using sys **/ import java.jdbc. Example 8–1 Using SYS Login To Make a Remote Connection //This example works regardless of language settings of the database.setConnectionProperties(prop). import oracle. .put("user". ods. // get the connection Connection conn = ods.*.util.put("internal_logon". ods.*. import oracle. SQL> select * from v$pwfile_users. "sysoper").Properties(). "sys").sql. Data Sources and URLs 8-9 .put("password".getConnection().Properties prop = new java. USERNAME SYSDB -----------------------------SYS TRUE SYSOP --------TRUE 5. import oracle.util. "sysdba")..util. "sys"). prop.*. prop.*. // create an OracleDataSource instance OracleDataSource ods = new OracleDataSource().put("internal_logon". // create an OracleDataSource OracleDataSource ods = new OracleDataSource(). ods. prop. Restart the remote database.Properties prop = new java.jdbc.pool.pool. /** Example of bequeath connection **/ import java.put("password". Bequeath Connection and SYS Logon The following example illustrates how to use the internal_logon and SYSDBA arguments to specify the SYS login.. Change the password for the SYS user.jdbc. PASSWORD sys Changing password for sys New password: password Retype new password: password 4.setURL(url). "sys").setConnectionProperties(prop). // set connection properties java.

Properties info = new java.Properties class. //specify the properties object java. 8-10 Oracle Database JDBC Developer's Guide and Reference . .Properties(). Setting these properties is equivalent to using corresponding methods on the OracleConnection object.setUser("scott"). .setConnectionProperties(info). Properties for Oracle Performance Extensions Some of the connection properties are for use with Oracle performance extensions.util.util.put ("user". as follows: ■ Setting the defaultRowPrefetch property is equivalent to calling setDefaultRowPrefetch. in this case.setURL("jdbc:oracle:thin:@//myhost:1521/orcl").OracleDataSource.*. See Also: "DatabaseMetaData TABLE_REMARKS Reporting" on page 23-19 ■ ■ Setting the defaultBatchValue property is equivalent to calling setDefaultExecuteBatch See Also: "Oracle Update Batching" on page 23-3 Example The following example shows how to use the put method of the java. "tiger"). ods. ods.put ("password".*..util. ods.sql."20"). //specify the datasource object OracleDataSource ods = new OracleDataSource(). info.Data Sources // the url for bequeath connection String url = "jdbc:oracle:oci8:@". "scott"). Setting the remarksReporting property is equivalent to calling setRemarksReporting.jdbc.put ("defaultRowPrefetch"... //import packages and register the driver import java. ods. import oracle. import java. "5")..jdbc. info. import oracle. info. info.setURL(url).math.put ("defaultBatchValue". ods.setPassword("tiger"). to set Oracle performance extension parameters.pool.getConnection().*. // retrieve the connection Connection conn = ods.

using an address list: url="jdbc:oracle:thin:@(DESCRIPTION= (LOAD_BALANCE=on) (ADDRESS_LIST= (ADDRESS=(PROTOCOL=TCP)(HOST=host1) (PORT=1521)) (ADDRESS=(PROTOCOL=TCP)(HOST=host2)(PORT=1521))) (CONNECT_DATA=(SERVICE_NAME=service_name)))" OCI.Database URLs and Database Specifiers Database URLs and Database Specifiers Database URLs are strings. listing which JDBC drivers support each specifier. ■ The first part of the URL specifies which JDBC driver is to be used. an @. Oracle Service IDs are not supported. OCI Example Thin. Starting Oracle Database 10g. and some for both. The remainder of the URL contains an optional user name and password separated by a slash. Oracle no longer supports Oracle Names as a naming method. oci. which uniquely identifies the database to which the application is connected. Note: ■ Starting Oracle Database 10g. "jdbc:oracle:thin:scott/tiger@//myhost:1521/myservic ename" Data Sources and URLs 8-11 . Database Specifiers Table 8–3. The supported driver_type values are thin. the internal server-side driver. Some database specifiers are valid only for the JDBC Thin driver. using a cluster: "jdbc:oracle:oci:@(DESCRIPTION= (ADDRESS=(PROTOCOL=TCP)(HOST=cluster_alias) (PORT=1521)) (CONNECT_DATA=(SERVICE_NAME=service_name)))" Thin-style service Thin name Refer to "Thin-style Service Name Syntax" for details. and kprb. some only for the JDBC OCI driver. The complete URL syntax is: jdbc:oracle:driver_type:[username/password]@database_specifier Note: ■ The brackets indicate that the username/password pair is optional. Database URLs for the server-side driver end after the driver_type. kprb. ■ Table 8–3 Specifier Oracle Net connection descriptor Supported Database Specifiers Supported Drivers Thin. uses an implicit connection. shows the possible database specifiers. and the database specifier.

ora file. nothing after @ "jdbc:oracle:oci:scott/tiger/@" Thin.tns_admin". That is.setUser("scott"). this file is located in the ORACLE_HOME\NETWORK\ADMIN directory.net. String url = "jdbc:oracle:thin:@tns_entry".setDriverType("oci"). then write the following: OracleDataSource ods = new OracleDataSource(). On Windows.net.net. OCI Refer to "TNSNames Alias Syntax" for details. java -Doracle. ods. Connection conn = ods.ora file so that the JDBC Thin driver can locate the tnsnames.net. ods. you must set the oracle.) Supported Database Specifiers Specifier LDAP syntax Bequeath connection TNSNames alias Supported Drivers Thin OCI Example Refer to LDAP Syntax for details. Note: When using TNSNames with the JDBC Thin driver.tns_admin=$ORACLE_HOME/network/admin 8-12 Oracle Database JDBC Developer's Guide and Reference .tns_admin system property must be set to the location of the tnsnames. "c:\\Temp"). ods.ora file.getConnection().setProperty("oracle.setPassword("tiger"). On UNIX systems. The oracle. The syntax is: @//host_name:port_number/service_name For example: jdbc:oracle:thin:scott/tiger@//myhost:1521/myservicename Note: The JDBC Thin driver supports only the TCP/IP protocol.Database URLs and Database Specifiers Table 8–3 (Cont. Empty. if you want to connect to the database on host myhost as user scott with password tiger that has a TNSNAMES entry of MyHostString. For example: System. Thin-style Service Name Syntax Thin-style service names are supported only by the JDBC Thin driver.ora file on the client computer from which you are connecting. TNSNames Alias Syntax You can find the available TNSNAMES entries listed in the tnsnames.tns_admin property to the directory that contains your tnsnames. ods.setTNSEntryName("MyTNSAlias"). For example. you can find it in the ORACLE_HOME directory or the directory indicated in your TNS_ADMIN environment variable.

A set of JNDI environment properties. ods. The following example shows a simple clear-text password authentication: String url = "jdbc:oracle:thin:@ldap://ldap. The oracle. The JDBC Thin driver supports LDAP nonanonymous bind.com:7777/sales. without the need for a hardware load balancer. prop.cn=OracleContext.put("java.dc=com /salesdb " + "ldap://ldap2. OracleDataSource ods = new OracleDataSource(). OracleDataSource ods = new OracleDataSource().security. then authentication information must be provided to connect to the LDAP server. When a list of LDAP URLs is specified.ldap_loadbalance". An example.acme. and the oracle.principal".put("java.com:3500/cn=salesdept.security. both failover and load balancing are enabled by default.cn=OracleContext. client-side load balancing is supported for connecting to LDAP servers.Database URLs and Database Specifiers LDAP Syntax An example of database specifier using the Lightweight Directory Access Protocol (LDAP) syntax is as follows: "jdbc:oracle:thin:@ldap://ldap.cn=OracleContext. ods.com:3500/cn=salesdept.put("java. A list of space separated LDAP URLs syntax is used to support failover and load balancing.ldap_loadbalance connection property can be used to disable load balancing.acme.d c=com".security. but with client-side load balancing disabled. The JDBC Thin driver supports failover of a list of LDAP servers during the service name resolution process.authentication".naming.acme. The LDAP server must be configured to use SSL. which uses failover.naming.com:7777/sales.com:3500/cn=salesdept.dc=com" When using SSL. then the connection attempt will hang. Properties prop = new Properties().dc=com"). ods. can be specified for a data source. Data Sources and URLs 8-13 .put("oracle.net.acme.setURL(url).cn=OracleContext.com:7777/sales.dc=com/salesdb". "simple").naming. prop."cn=salesdept.setConnectionProperties(prop).acme.cn=OracleContext.net. If it is not.cn=OracleContext. "OFF" ).cn=salesdept. Also.ldap_failover connection property can be used to disable failover. is as follows: Properties prop = new Properties().acme.credentials". change this to: "jdbc:oracle:thin:@ldaps://ldap. which contains authentication information. "mysecret").setURL(url).dc=com/salesdb " + "ldap://ldap3. prop. String url = "jdbc:oracle:thin:@ldap://ldap1. prop.net.cn=OracleContext. If a LDAP server is configured as not allowing anonymous bind.dc=com" Note: The JDBC Thin driver can use LDAP over SSL to communicate with Oracle Internet Directory if you substitute ldaps: for ldap: in the database specifier.

For example.security. then the default authentication mechanism is "simple".authentication property.Database URLs and Database Specifiers ods. Please refer to relevant JDNI documentation for details. Since JDBC passes down the three properties to JNDI. if the client specifies authentication information without explicitly specifying the java. the authentication mechanism chosen by client is consistent with how these properties are interpreted by JNDI.naming.setConnectionProperties(prop). 8-14 Oracle Database JDBC Developer's Guide and Reference .

JDBC Client-Side Security Features 9-1 . 3DES. third-party authentication.9 JDBC Client-Side Security Features This chapter discusses support in the Oracle Java Database Connectivity (JDBC) Oracle Call Interface (OCI) and JDBC Thin drivers for login authentication. data encryption. and AES.1). with respect to features of the Oracle Advanced Security option. Some of the supported encryption algorithms are RC4. provides industry standards-based data encryption. particularly. data integrity. both the JDBC OCI and Thin drivers support all the Oracle Advanced Security features. This chapter contains the following sections: ■ ■ ■ ■ ■ ■ ■ ■ ■ Support for Oracle Advanced Security Support for Login Authentication Support for Strong Authentication Support for OS Authentication Support for Data Encryption and Integrity Support for SSL Support for Kerberos Support for RADIUS Secure External Password Store Support for Oracle Advanced Security Oracle Advanced Security provides the following security features: ■ Data Encryption Sensitive information communicated over enterprise networks and the Internet can be protected by using encryption algorithms. From 11g release 1 (11. Oracle Advanced Security. Earlier releases of the JDBC drivers did not support some of the ASO features. given that all communication through that driver is completely internal to the server. which transform information into a form that can be deciphered only with a decryption key. and data integrity. and access authorization. previously known as the Advanced Networking Option (ANO) or Advanced Security Option (ASO). Note: This discussion is not relevant to the server-side internal driver. single sign-on. DES.

Properties props = new Properties(). the JDBC OCI driver attempts to use external authentication if you try connecting to a database without providing a password.jdbc. Oracle Advanced Security generates a cryptographically secure message digest.ora file on the client computer. which presumes you are running from a computer with an Oracle client installation.OracleDriver(). which support various third-party authentication services. then support for Oracle Advanced Security and incorporated third-party features is fairly similar to the support provided by in any Oracle client situation.connect( url.sql. Password authentication is the most common means of authentication.Support for Oracle Advanced Security To ensure data integrity during transmission. using MD5 or SHA-1 hashing algorithms. Your use of Advanced Security features is determined by related settings in the sqlnet. deleted packets. and replay attacks. This protects the communicated data from attacks. such as data modification. Starting from Oracle Database 11g Release 1 (11. ■ Strong Authentication To ensure network security in distributed environments.util.close(). conn. props ).*. The following are some examples using the JDBC OCI driver to connect to a database without providing a password: SSL Authentication Example 9–1 uses SSL authentication to connect to the database. Driver driver = new oracle. it is necessary to authenticate the user and check his credentials. Example 9–1 import java.1). Oracle Advanced Security enables strong authentication with Oracle authentication adapters. Oracle Advanced Security supports the following industry-standard authentication methods: – – – – Kerberos Remote Authentication Dial-In User Service (RADIUS) Distributed Computing Environment (DCE) Secure Sockets Layer (SSL) Tip: Oracle Database Advanced Security Administrator's Guide JDBC OCI Driver Support for Oracle Advanced Security If you are using the JDBC OCI driver. and includes it with each message sent across a network.Properties. } } 9-2 Oracle Database JDBC Developer's Guide and Reference . including SSL with digital certificates. Connection conn = driver. public class test { public static void main( String [] args ) throws Exception { String url = "jdbc:oracle:oci:@" +"(DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=stadh25)(PORT=1529))" +"(CONNECT_DATA=(SERVICE_NAME=mydatabaseinstance)))". import java.

jar files. and DCE. Specify the user name and password through a Java properties object or directly through the getConnection method call. Smart Cards.ora file. This is called strong JDBC Client-Side Security Features 9-3 . which uses a special direct connection and does not require a user name or password.jdbc.*.sql. KERBEROS. Therefore. oracle. it uses a Java approach to support Oracle Advanced Security. Certificate-Based Authentication. java.ora.getPooledConnection(). with respect to Java. This requires special attention. JDBC Thin Driver Support for Oracle Advanced Security The JDBC Thin driver cannot assume the existence of an Oracle client installation or the presence of the sqlnet.1). are set using a Java Properties object or through system properties. but is irrelevant if you are using the server-side internal driver. is that the Secure Sockets Layer (SSL) protocol is supported by the Oracle JDBC OCI drivers only if you use native threads in your application. usually set in sqlnet. Starting with 11g release 1 (11. because green threads are generally the default.*. javax.Support for Strong Authentication Using Data Source Example 9–2 uses a data source to connect to the database. External authentication can be with RADIUS. the Oracle JDBC Thin driver implements a challenge-response protocol to authenticate the user. PooledConnection pc = ocpds.*.getConnection(). Support for Strong Authentication Oracle Advanced Security enables Oracle Database users to authenticate externally. as with any other means of logging in to an Oracle server. Security parameters for encryption and integrity. } } Note: The key exception to the preceding. Connection conn = pc. Example 9–2 import import import import java.setURL(url). Token Cards. ocpds.sql. Java classes that implement Oracle Advanced Security are included in the ojdbc5.jar and ojdbc6.pool.Properties. Support for Login Authentication Basic login authentication through JDBC consists of user names and passwords. OracleConnectionPoolDataSource ocpds = new OracleConnectionPoolDataSource().util. public class testpool { public static void main( String args ) throws Exception { String url = "jdbc:oracle:oci:@" +"(DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=stadh25)(PORT=1529))" +"(CONNECT_DATA=(SERVICE_NAME=mydatabaseinstance)))". This applies regardless of which client-side Oracle JDBC driver you are using.

You need to perform the following steps to achieve this: ■ Use the following command to check the value of the Oracle OS_AUTHENT_PREFIX initialization parameter: SQL> SHOW PARAMETER os_authent_prefix NAME TYPE VALUE -----------------------------------. where the username must be the prefix value concatenated to the OS username. Use the following command to create a database user to allow an OS authenticated connection: CREATE USER ops$w_rose IDENTIFIED EXTERNALLY. the OS username is passed to the Oracle server. If the username is recognized. Oracle JDBC drivers provide support for the following strong authentication methods: ■ ■ ■ Kerberos RADIUS SSL (certificate-based authentication) Support for OS Authentication Operating System (OS) authentication allows Oracle to pass control of user authentication to the operating system. Use the following commands to create an OS user w_rose: # useradd w_rose # passwd w_rose Changing password for w_rose New password: password Retype new password: password 2. You need to create a database user to allow an OS authenticated connection. the Oracle the connection is accepted. It allows the users to connect to the database by authenticating their OS username in the database. In other words. the server delegates the authentication to the client OS.ora file: REMOTE_OS_AUTHENT = TRUE When a connection is attempted from the local database server. GRANT CONNECT TO ops$w_rose. ■ Add the following line in the t_init1. No password is associated with the account since it is assumed that OS authentication is sufficient. 3.Support for OS Authentication authentication. Use the following commands to test the OS authentication connection: 9-4 Oracle Database JDBC Developer's Guide and Reference .----------.-----------------------------os_authent_prefix string ops$ SQL> Note: Remember the OS authentication prefix. otherwise the connection is rejected. Configuration Steps for Linux The configuration steps necessary to set up OS authentication on Linux are the following: 1.

com\p_floyd" IDENTIFIED EXTERNALLY.3. 6.Support for OS Authentication su . Oracle Label Security.com\p_floyd".0 . using the Computer Management dialog box.1.0/db_1 export PATH=$PATH:$ORACLE_HOME/bin export ORACLE_SID=DEV1 sqlplus / SQL*Plus: Release 10. Enter details of the user in the New User dialog box and click Create. there is an additional consideration.0.0.Production on Wed Jun 7 08:41:15 2006 Copyright (c) 1982. w_rose. 5. Oracle. Use the following commands to test the OS authentication connection: JDBC Client-Side Security Features 9-5 . GRANT CONNECT TO "OPS$yourdomain. 4. The following option must be set in the %ORACLE_HOME%\network\admin\sqlnet. 3. Connected to: Oracle Database 10g Enterprise Edition Release 10. Note: The preceding steps are only for creating a local user. Domain users can be created in Active Directory.Production With the Partitioning. select Programs. then select Administrative Tools and then select Computer Management. Use the following command to create a database user to allow an OS authenticated connection: CREATE USER "OPS$yourdomain. Click Users.0 .3.1.AUTHENTICATION_SERVICES= (NTS) 3. For this you have to do the following: 1. Select New User from the Action menu. 2.w_rose export ORACLE_HOME=/u01/app/oracle/product/10. Click Start. say. OLAP and Data Mining options SQL> Configuration Steps for Windows The configuration steps necessary to set up OS authentication on Windows are the following: 1. Note: When you create the database user in Windows environment.ora file: SQLNET. From the Start menu.1. 2. 2004. Create a local user. All rights reserved. the user name should be in the following format: <OS_authentication_prefix_parameter>$<DOMAIN>\<OS_user_name> When using a Windows server. Expand Local Users and Groups by clicking on the Plus ("+") sign.

REJECTED. you can use the following JDBC code for connecting to the database: String url = "jdbc:oracle:thin:@oracleserver.1. Oracle. set parameters as you would in any Oracle client situation. which is set by the JVM.getConnection( url. the following thin driver-specific error no longer exists: ORA-17443=Null user or password not supported in THIN driver Note: By default. integrity is enabled or disabled based on a combination of the client-side integrity-level setting and the server-side integrity-level setting. set parameters through a Java properties object. As a result.name system property that is set by the JVM. The JDBC drivers retrieve the OS username from the user. remote OS authentication (through TCP) is disabled in the database for obvious security reasons. Similarly. Data Mining and Real Application Testing options SQL> JDBC Code Using OS Authentication Now that you have set up OS authentication to connect to the database.1.0 . Encryption and integrity support the same setting levels. props). Properties props = new Properties(). When using the Thin driver. Connected to: Oracle Database 11g Enterprise Edition Release 11. 2007.Production With the Partitioning.registerDriver(driver). depending on related settings in the server.Production on Thu July 12 11:47:01 2007 Copyright (c) 1982. and REQUIRED. If the JDBC driver is unable to retrieve this system property or if you want to override the value of this system property.CONNECTION_PROPERTY_THIN_VSESSION_O SUSER connection property. For more information.com:5521:dbja" Driver driver = new oracle. Connection conn = DriverManager. When using the JDBC OCI driver.name system property.OracleDriver(). 9-6 Oracle Database JDBC Developer's Guide and Reference . By default.0. Encryption is enabled or disabled based on a combination of the client-side encryption-level setting and the server-side encryption-level setting. DriverManager.1.0 . see Oracle Javadoc. ACCEPTED. The preceding code assumes that it is executed by p_floyd on the client machine. OLAP.1.mydomain. Support for Data Encryption and Integrity You can use Oracle Advanced Security data encryption and integrity features in your Java database applications.Support for Data Encryption and Integrity C:\> set ORACLE_SID=DB11G C:\> sqlplus / SQL*Plus: Release 11. then you can use the OracleConnection.jdbc.0. the JDBC driver retrieves the OS username from the user. All rights reserved. REQUESTED. Table 9–1 shows how these possible settings on the client-side and server-side combine to either enable or disable the feature.

then you can enable or disable data encryption or integrity and set related parameters as you would in any Oracle client situation. See Also: Oracle Database Advanced Security Administrator's Guide Note: The term checksum still appears in integrity parameter names. through settings in the SQLNET. if encryption is accepted by the client and requested by the server. for example. To summarize.ORA file on the client. it is disabled. again. And. As another example. but is no longer used otherwise. the same is true for integrity. checksum and integrity are synonymous. that if encryption is requested by the client. which presumes an Oracle-client setting with an Oracle client installation. but rejected by the server. The same is true for integrity. the client parameters are shown in Table 9–2: JDBC Client-Side Security Features 9-7 .Support for Data Encryption and Integrity Table 9–1 Client/Server Negotiations for Encryption or Integrity Client Rejected Client Accepted (default) OFF OFF ON ON Client Requested OFF ON ON ON Client Required connection fails ON ON ON Server Rejected Server Accepted (default) Server Requested Server Required OFF OFF OFF connection fails Table 9–1 shows. For all intents and purposes. it is enabled. This section covers the following topics: ■ ■ ■ JDBC OCI Driver Support for Encryption and Integrity JDBC Thin Driver Support for Encryption and Integrity Setting Encryption and Integrity Parameters in Java JDBC OCI Driver Support for Encryption and Integrity If you are using the JDBC OCI driver.

DES40C. 3DES112.ENCRYPTION_CLIENT Possible Settings REJECTED ACCEPTED REQUESTED REQUIRED RC4_40. 3DES112. AES128. Oracle Database Advanced Security Administrator's Guide See Also: JDBC Thin Driver Support for Encryption and Integrity The JDBC Thin driver support for data encryption and integrity parameter settings parallels the JDBC OCI driver support discussed in the preceding section. RC4_40. These parameters are defined in the oracle. SHA-1 Client integrity selected list SQLNET. AES256. AES192.ENCRYPTION_TYPES_CLIENT Client integrity level SQLNET. DES56C.jdbc. SHA1 Parameter Name CONNECTION_PROPERTY_THIN_NET_ENCRYPTION_LEVEL String CONNECTION_PROPERTY_THIN_NET_ENCRYPTION_TYPES String CONNECTION_PROPERTY_THIN_NET_CHECKSUM_LEVEL String CONNECTION_PROPERTY_THIN_NET_CHECKSUM_TYPES String 9-8 Oracle Database JDBC Developer's Guide and Reference . DES40. 3DES168. RC4_56 REJECTED ACCEPTED REQUESTED REQUIRED MD5. 3DES168 (see Note) Parameter Description Client encryption level Client encryption selected list SQLNET. RC4_128. Table 9–3 Thin Driver Client Parameters for Encryption and Integrity Parameter Type Possible Settings REJECTED ACCEPTED REQUESTED REQUIRED AES256. RC4_56. Table 9–3 lists the parameter information for the JDBC Thin driver.OracleConnection interface.CRYPTO_CHECKSUM_CLIENT REJECTED ACCEPTED REQUESTED REQUIRED MD5. RC4_256.CRYPTO_CHECKSUM_TYPES_CLIENT Note: For the Oracle Advanced Security domestic edition only. Corresponding parameters can be set through a Java properties object that you would then be used when opening a database connection. DES. settings of RC4_128 and RC4_256 are also possible. AES192. AES128.Support for Data Encryption and Integrity Table 9–2 OCI Driver Client Parameters for Encryption and Integrity Parameter Name SQLNET.

CONNECTION_PROPERTY_THIN_NET_CHECKSUM_TYPES. prop. prop. you must turn on encryption in the sqlnet. AES192. The following example instantiates a Java properties object. the server and the client negotiate to determine which value is to be actually used. When multiple values are supplied..setProperty(OracleConnection. there is only one version. The parentheses around the values encryption type and checksum type allow for lists of values.. to set the data encryption and integrity parameters supported by the JDBC Thin driver. Note: In the example.util..Properties. .ora file.CRYPTO_CHECKSUM_SERVER = ACCEPTED SQLNET. the following lines will turn on AES256.setProperty(OracleConnection. Connection conn = ods. "REQUESTED"). "( DES40C )").setProperty(OracleConnection. uses it to set each of the parameters in Table 9–3. an instance of java.getConnection().ENCRYPTION_SERVER = ACCEPTED SQLNET. prop.CONNECTION_PROPERTY_THIN_NET_ENCRYPTION_LEVEL. and then uses the properties object in opening a connection to the database: . not separate domestic and export editions. the string "REQUIRED" is retrieved dynamically through functionality of the AnoServices and Service classes. The letter C in DES40C and DES56C refers to Cipher Block Chaining (CBC) mode. Only parameter settings that would be suitable for an export edition are possible.CONNECTION_PROPERTY_THIN_NET_CHECKSUM_LEVEL.setProperty(OracleConnection. "REQUIRED"). Example Example 9–3 is a complete class that sets data encryption and integrity parameters before connecting to a database to perform a query. ■ Setting Encryption and Integrity Parameters in Java Use a Java properties object.Support for Data Encryption and Integrity Note: ■ Because Oracle Advanced Security support for the Thin driver is incorporated directly into the JDBC classes JAR file. ods. "( MD5 )"). For example. SHA1) JDBC Client-Side Security Features 9-9 . Properties prop = new Properties(). OracleDataSource ods = new OracleDataSource().CONNECTION_PROPERTY_THIN_NET_ENCRYPTION_TYPES.CRYPTO_CHECKSUM_TYPES_SERVER= (MD5. that is.. You have the option of retrieving the strings in this manner or hardcoding them as in the previous examples Before running this example. prop. and AES128 for the encryption and MD5 and SHA1 for the checksum: SQLNET. ods.setProperties(prop).setURL("jdbc:oracle:thin:@localhost:1521:main").

" + AnoServices.ANO_REQUIRED). prop. public static final void main(String[] argv) { DemoAESAndSHA1 demo = new DemoAESAndSHA1().ENCRYPTION_AES256 + ". prop.net.An oServices. prop. // We also require the use of the SHA1 algorithm for data integrity checking.PASSWORD). prop.CONNECTION_PROPERTY_THIN_NET_ENCRYPTION_LEVEL.ENCRYPTION_TYPES_SERVER= (AES256. prop.CRYPTO_SEED = 2z0hslkdharUJCFtkwbjOLbgwsj7vkqt3bGoUylihnvkhgkdsbdskkKGhdk Example 9–3 Setting Data Encryption and Integrity Parameters import import import import java.Support for Data Encryption and Integrity SQLNET. then the connection attempt will fail.setProperty(OracleConnection.URL.DemoAESAndSHA1.AnoS ervices.printStackTrace().println("Connection created! Encryption algorithm is: " + 9-10 Oracle Database JDBC Developer's Guide and Reference . OracleConnection oraConn = (OracleConnection)dr.CONNECTION_PROPERTY_THIN_NET_CHECKSUM_LEVEL.CONNECTION_PROPERTY_THIN_NET_ENCRYPTION_TYPES. AES128) SQLNET. Properties prop = new Properties(). try { demo."( " + AnoServices.sql.ENCRYPTION_AES192 + ")"). oracle. AES192. static final String URL = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=WXYZ)(PORT=5561))" +"(CONNECT_DATA=(SERVICE_NAME=mydatabaseinstance)))".run().prop).setProperty(OracleConnection.*.setProperty("password".connect(DemoAESAndSHA1. System. }catch(SQLException ex) { ex.ano.setProperty(OracleConnection.AnoServices.jdbc. public class DemoAESAndSHA1 { static final String USERNAME= "scott". // We require the connection to be encrypted with either AES256 or AES192."( " + AnoServices.ANO_REQUIRED). oracle.Properties.setProperty(OracleConnection. // If the database doesn't accept such a security level.out.USERNAME).util.setProperty("user".CHECKSUM_SHA1 + " )"). } } void run() throws SQLException { OracleDriver dr = new OracleDriver(). static final String PASSWORD= "tiger". prop. java.*.CONNECTION_PROPERTY_THIN_NET_CHECKSUM_TYPES.DemoAESAndSHA1.

Server sends its certificate to the client. It provides a secure enhancement to the standard TCP/IP protocol. JDBC Client-Side Security Features 9-11 ■ ■ ■ .getEncryptionAlgorithmName() + ".. The private key is used to decrypt a message that has been encrypted using the corresponding public key. SSL authentication is supported in the thin driver. SSL provides authentication. The certificate is verified using the corresponding public key. which is used for Internet communication. which is never transmitted over a network. SSL also uses secret key cryptography and digital signatures to ensure privacy and integrity of data. also known as certificate authority. data integrity algorithm is: " + oraConn.Support for SSL oraConn. each generates a session key. SSL is a widely used industry standard protocol that provides secure communication over a network. } } Support for SSL Oracle Database 11g provides support for the Secure Sockets Layer (SSL) protocol. you do not need to provide a username/password pair if you are using SSL authentication. is an entity which issues digitally signed certificates for use by other parties. and the server verifies that the certificate was signed by a trusted CA. This step verifies the identity of the server. the client sends its own certificate to the server. If client authentication is required. Client and server exchange key information using public key cryptography. and data integrity.getDataIntegrityAlgorithmName()). All subsequent communications between the client and the server is encrypted and decrypted by using this set of session keys and the negotiated cipher suite.509v3 standard for authentication and a public and private key pair for encryption. oraConn. So. It is also used to sign certificates. SSL uses digital certificates that comply with the X. certification authority: A certification authority (CA). The certificate can be used to verify that the public key belongs to that individual. and the client verifies that the certificate was signed by a trusted certification authority (CA). private key: A private key is a secret key. the client and server perform an SSL handshake that includes the following steps: ■ Client and server negotiate about the cipher suites to use. cipher suite: A cipher suite is a set of cryptographic algorithms and key sizes used to encrypt data sent over an SSL-enabled network. This includes deciding on the encryption algorithms to be used for data transfer.1). When a network connection over SSL is initiated. Based on this information. data encryption. ■ ■ ■ SSL Terminology The following terms are commonly used in the SSL context: ■ certificate: A certificate is a digitally signed document that binds a public key with an entity.close(). Note: In Oracle Database 11g Release 1 (11.

in Oracle Database 11g. Oracle database server sends its certificate. which they can directly integrate into their applications. JKS.1-based platforms. javax. as long as a provider is available. SSL sockets. These packages provide classes for creating and configuring sockets. The Oracle JDBC Thin driver uses the JSSE framework to create an SSL connection. The public key is used for encrypting the message sent over SSL. ■ Java Version of SSL The Java Secure Socket Extension (JSSE) provides a framework and an implementation for a Java version of the SSL and TLS protocols.security.ssl.cert packages.0. and message integrity.jar osdt_cert. The client may or may not need a certificate or wallet depending on the server configuration. server sockets. JSSE provides support for data encryption. and javax. a public key certificate API compatible with JDK1. It uses the default provider (SunJSSE) to create an SSL context. It abstracts the complex security algorithms and handshaking mechanisms and simplifies application development by providing a building block for application developers. and SSL server sockets. For Oracle wallets. However you can provide your own provider. Keys and certificates containers Java clients can use multiple types of containers such as Oracle wallets. and interfaces for key and trust managers. The JSSE standard application programming interface (API) is available in the javax. The packages also provide a class for secure HTTP connections.net. This section covers the following: ■ ■ Managing Certificates and Wallets Keys and certificates containers Managing Certificates and Wallets To establish an SSL connection with a JDBC client. which is stored in its wallet. and so on. OraclePKI provider must be used because the PKCS12 support provided by SunJSSE provider does not support all the features of PKCS12. Oracle strongly recommends that you have a clear understanding of the JavaTM Secure Socket Extension (JSSE) framework by Sun Microsystems before using SSL in the Oracle JDBC drivers. the following JARs are required: ■ ■ oraclepki. JSSE is integrated into Java Development Kit (JDK) 1. including private keys. unless the SSL_CLIENT_AUTHENTICATION parameter is set on the server. SSL works the same way. wallet: A wallet is a password-protected container that is used to store authentication and signing credentials.0 and 3.4 and later. PKCS12. It is also used to verify a certificate signed by the corresponding private key. In order to use OraclePKI provider. and trusted certificates required by SSL.net. certificates.Support for SSL ■ public key: A public key is an encryption key that can be made public or sent by ordinary means such as an e-mail message. as in any networking environment.jar 9-12 Oracle Database JDBC Developer's Guide and Reference . Thin or OCI. You do not need a certificate for the client. server and client authentication. and supports SSL version 2.

authentication_services = (beq. Kerberos helps you secure your information systems across your entire enterprise by using secret-key cryptography. Kerberos is a network authentication protocol that provides the tools of authentication and strong cryptography over the network. Support for Kerberos Oracle Database 11g Release 1 (11.kerberos5_keytab = /home/Jdbc/Security/kerberos/dbji.ORACLE. The Kerberos architecture is centered around a trusted authentication service called the key distribution center. Users and services in a Kerberos environment are referred to as principals.ORACLE. they can also encrypt all of their communications to assure privacy and data integrity as they go about their business. Use the following command to connect to the database: SQL> connect system Enter password: password 2. 4. such as a password. After a client and server have used Kerberos to prove their identity.1) introduces support for Kerberos.ora 6. Add the following line to $T_WORK/t_init1. SQL> grant create session to "CLIENT@US.COM" identified externally.kerberos5_conf = /home/Jdbc/Security/kerberos/krb5.authentication_kerberos5_service = dbji sqlnet. 3.kerberos5_conf_mit = true sqlnet.conf sqlnet. The Kerberos protocol uses strong cryptography so that a client or a server can prove its identity to its server or client across an insecure network connection.ORACLE.directory_path = (tnsnames) #Kerberos sqlnet.jar All these JAR files should be under $ORACLE_HOME/jlib directory.Support for Kerberos ■ osdt_core. Modify the sqlnet. or KDC.kerberos5) sqlnet.COM". each principal shares a secret.ora file to include the following lines: names. Use the following commands to create a user CLIENT@US. A principal can be a user such as scott or a database server instance. with the KDC.COM that is identified externally: SQL> create user "CLIENT@US. Use the following command to restart the database: SQL> startup pfile=t_init1. Configuring Oracle Database to Use Kerberos Perform the following steps to configure Oracle Database to use Kerberos: 1. Use the following commands to connect to the database as sysdba and dismount it: SQL> connect / as sysdba SQL> shutdown immediate.ora file: OS_AUTHENT_PREFIX="" 5.oracleserver sqlnet.kerberos_cc_name = /tmp/krb5cc_5088 # logging (optional): JDBC Client-Side Security Features 9-13 .

This scenario is in the module connectWithSpecificUser().1) JDBC thin driver.COM Kerberos 4 ticket cache: /tmp/tkt5088 klist: You have no tickets cached > sqlplus '/@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=oracleserver. The credentials are stored in the cache and the driver retrieves the credentials before trying to authenticate to the server. you need to have a working setup.sun. a Kerberos server up and running. Example 9–4 import com.IOException.ORACLE.Before you run this part of the demo.ORACLE.com)(PORT=55 29)) (CONNECT_DATA=(SERVICE_NAME=mydatabaseinstance)))' Code Example This following example demonstrates the new Kerberos authentication feature that is part of Oracle Database 11g Release 1 (11.Krb5LoginModule. Note: 1. use the following command to verify that you have valid credentials: > /usr/kerberos/bin/kinit client where.COM@US. import java.security. This demo covers two scenarios: ■ In the first scenario.mydomain.ORACLE.Support for Kerberos trace_level_server=16 trace_directory_server=/scratch/sqlnet/ 7. Use the following commands to verify that you can connect through SQL*Plus: > kinit client > klist Ticket cache: FILE:/tmp/krb5cc_5088 Default principal: client@US. 9-14 Oracle Database JDBC Developer's Guide and Reference .auth. Note: To run this demo. You then need to change the URLs used in the example to compile and run it. Use the following command to list your tickets: > /usr/kerberos/bin/klist ■ The second scenario covers the case where the application wants to control the user credentials.COM Valid starting 06/22/06 07:13:29 Expires 06/22/06 17:13:29 Service principal krbtgt/US. This is the case of the application server where multiple web users have their own credentials. the OS maintains the user name and credentials.module. the password is welcome.io. This scenario is in the module connectWithDefaultUser(). that is. 2. and an Oracle database server that is configured to use Kerberos authentication.

auth.SQLException.UnsupportedCallbackException.Connection.sql. } catch (Exception e) { e.ano.println("Attempt to connect with a specific user:"). import oracle.Statement.util.Subject. java.PasswordCallback."C:\\WINDOWS\\krb5.printStackTrace().Callback.co nf").HashMap.CallbackHandler. java. KerberosJdbcDemo kerberosDemo = new KerberosJdbcDemo().auth.callback. For example. try { System. public class KerberosJdbcDemo { String url ="jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)"+ "(HOST=oracleserver. javax.out. java.jdbc. System. javax.connectWithSpecificUser().krb5. import oracle.ini: */ // System. } } void connectWithDefaultUser() throws SQLException { JDBC Client-Side Security Features 9-15 .PrivilegedExceptionAction.callback.ini (The system cannot find the path * specified] it's because the JVM cannot locate your kerberos config file.AnoServices.conf".security.mydomain.Properties.OracleDriver. java.net.krb5. * the MIT Kerberos client uses the config file: C\WINDOWS\krb5.security.callback.OracleConnection. import oracle.println("Attempt to connect with the default user:"). kerberosDemo. on Windows. kerberosDemo. } try { System.auth.auth.security.auth.sql.setProperty("java. javax.ini").security.security.conf".sql. java.util.out. * You have to provide the location of the file.printStackTrace().security.ResultSet. java.Support for Kerberos import import import import import import import import import import import import java. javax.setProperty("java.com)(PORT=5561))(CONNECT_DATA=" + "(SERVICE_NAME=mydatabaseinstance)))".security. public static void main(String[] arv) { /* If you see the following error message [Mechanism level: Could not load * configuration file c:\winnt\krb5.connectWithDefaultUser(). javax. } catch (Exception e) { e.security.callback.sql."/home/Jdbc/Security/kerberos/krb5.jdbc.

String auth = ((OracleConnection)conn).setProperty(OracleConnection. 9-16 Oracle Database JDBC Developer's Guide and Reference .out.connect(url.getAuthenticationAdaptorName().conf lrwxrwxrwx 1 root root 47 Jun 22 06:56 /etc/krb5.println("Authentication adaptor="+auth).setProperty(OracleConnection.ORACLE. */ // prop.ORACLE. } void connectWithSpecificUser() throws Exception { Subject specificSubject = new Subject(). "/tmp/krb5cc_5088"). "true"). prop.prop).CONNECTION_PROPERTY_THIN_NET_AUTHENTICATION_KRB5 _CC_NAME.CONNECTION_PROPERTY_THIN_NET_AUTHENTICATION_SERV ICES. conn. "("+AnoServices.ORACLE. System.conf -> /home/Jdbc/Security/kerberos/krb5.CONNECTION_PROPERTY_THIN_NET_AUTHENTICATION_KRB5 _MUTUAL. * * Note that the default location on windows is "C:\Documents and Settings\krb5cc_username". /* If you get the following error [Unable to obtain Princpal Name for * authentication] although you know that you have the right TGT in your * credential cache.setProperty(OracleConnection.Support for Kerberos OracleDriver driver = new OracleDriver().conf > kinit client Password for client@US. Connection conn = driver.CONNECTION_PROPERTY_THIN_NET_AUTHENTICATION_KRB5 _CC_NAME.COM Kerberos 4 ticket cache: /tmp/tkt5088 klist: You have no tickets cached */ prop.setProperty(OracleConnection.close(). /* On linux: > which kinit /usr/kerberos/bin/kinit > ls -l /etc/krb5.COM@US.ORACLE.COM: > klist Ticket cache: FILE:/tmp/krb5cc_5088 Default principal: client@US. printUserName(conn). Properties prop = new Properties(). prop. then it's probably because the JVM can't locate your * cache.COM Valid starting 11/02/06 09:25:11 Expires 11/02/06 19:25:11 Service principal krbtgt/US.AUTHENTICATION_KERBEROS5+")").

// options. options. you have a valid "specificSubject" Subject that // represents a web user that has valid Kerberos credentials. new PrivilegedExceptionAction() { public Object run() { Connection con = null.login()."true").. try { OracleDriver driver = new OracleDriver(). String auth = ((OracleConnection)conn).println("Authentication adaptor="+auth). krb5Module. } }). } void printUserName(Connection conn) throws SQLException JDBC Client-Side Security Features 9-17 . HashMap sharedState = new HashMap()."false").) on behalf of the Subject 'specificSubject': Connection conn = (Connection)Subject."C:\\Documents and Settings\\Jean de Lavarene\\krb5cc").put("ticketCache". HashMap options = new HashMap().AUTHENTICATION_KERBEROS5 + ")").setProperty(AnoServices.ORACLE.options) . } catch (Exception except) { except.initialize(specificSubject.. // to use the TGT from the cache: // options. Krb5LoginModule krb5Module = new Krb5LoginModule().newKrbCallbackHandler(). if(!retLogin) throw new Exception("Kerberos5 adaptor couldn't retrieve credentials (TGT) from the cache").COM").sharedState.commit(). In // a real world scenario. options.printStackTrace(). The second scenario // really starts here: // execute driver.close(). Properties prop = new Properties(). printUserName(conn).doAs(specificSubject.put("useTicketCache".initialize(specificSubject. "(" + AnoServices."true").sharedState.connect(."client@US. // krb5Module. prop).put("useTicketCache".out. krb5Module. conn."false"). } return con.put("principal".AUTHENTICATION_PROPERTY_SERVICES. options.put("doNotPrompt".connect(url. // Now we have a valid Subject with Kerberos credentials.null.getAuthenticationAdaptorName(). // options.put("doNotPrompt". boolean retLogin = krb5Module. System.Support for Kerberos // This first part isn't really meaningful to the sake of this demo.options). prop. con = driver.

UnsupportedCallbackException { for (int i = 0.createStatement().toCharArray()). ResultSet rs = stmt. "Unrecognized Callback"). Oracle Advanced Security uses this standard in a client/server network environment to enable use of any authentication method that supports the RADIUS protocol. including token cards and smart cards.next()) System.println("set password to 'welcome'"). } finally { if(stmt != null) stmt.executeQuery("select user from dual").close(). rs. RADIUS is a client/server security protocol that is most widely known for enabling remote authentication and access.length. Use the following command to connect to the database: 9-18 Oracle Database JDBC Developer's Guide and Reference . } } } class KrbCallbackHandler implements CallbackHandler { public void handle(Callback[] callbacks) throws IOException. while(rs. } } } } Support for RADIUS Oracle Database 11g Release 1 (11. RADIUS can be used with a variety of authentication mechanisms.1) introduces support for Remote Authentication Dial-In User Service (RADIUS). pc. try { stmt = conn.setPassword((new String("welcome")).getString(1)).out. } else { throw new UnsupportedCallbackException(callbacks[i]. i < callbacks.close().println("User is:"+rs. i++) { if (callbacks[i] instanceof PasswordCallback) { PasswordCallback pc = (PasswordCallback)callbacks[i].Support for RADIUS { Statement stmt = null. System. This section contains the following sections: ■ ■ Configuring Oracle Database to Use RADIUS Code Example Configuring Oracle Database to Use RADIUS Perform the following steps to configure Oracle Database to use RADIUS: 1.out.

java. that is.Connection.radius_authentication_timeout = 120 sqlnet. You need to have a working setup. You then need to change the URLs given in the example to compile and run it. 4. and an Oracle database server that is configured to use RADIUS authentication.radius_authentication = <RADUIUS_SERVER_HOST_NAME> sqlnet.SQLException. Add the following lines to the t_init1.1) JDBC thin driver. radius) sqlnet.authentication_services = ( beq. java.ora 6. Example 9–5 import import import import import java.util.sql. 5.radius_secret=/home/Jdbc/Security/radius/radius_key # logging (optional): trace_level_server=16 trace_directory_server=/scratch/sqlnet/ 7. a RADIUS server up and running.sql. SQL> grant create session to aso.com)( PORT=5529)) (CONNECT_DATA=(SERVICE_NAME=mydatabaseinstance)))' Code Example This example demonstrates the new RADIUS authentication feature that is a part of Oracle Database 11g Release 1 (11. java.Properties.ResultSet. Use the following commands to create a new user aso from within a database: SQL> create user aso identified externally.Support for RADIUS SQL> connect system Enter password: password 2.sql. Modify the sqlnet.Statement. Use the following commands to connect to the database as sysdba and dismount it: SQL> connect / as sysdba SQL> shutdown immediate.ora file so that it contains only these lines: sqlnet. java. you need to revert the preceding changes made to the t_init1. 3.ora file. Use the following command to verify that you can connect through SQL*Plus: >sqlplus 'aso/1234@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=oracleserver. Use the following command to restart the database: SQL> startup pfile=?/work/t_init1. JDBC Client-Side Security Features 9-19 .mydomain.ora file: os_authent_prefix = "" Note: Once the test is over.sql.radius_authentication_port = 1812 sqlnet.

prop. conn. Properties prop = new Properties(). import oracle.ano. "("+AnoServices. 9-20 Oracle Database JDBC Developer's Guide and Reference . String auth = ((OracleConnection)conn).connect(). } } /* * This method attempts to logon to the database using the RADIUS * authentication protocol.Support for RADIUS import oracle.jdbc.out.net.close().OracleDriver. try { stmt = conn. System.setProperty("password".OracleConnection.connect(url.println("Authentication adaptor="+auth).setProperty("user". } void printUserName(Connection conn) throws SQLException { Statement stmt = null.AnoServices.CONNECTION_PROPERTY_THIN_NET_AUTHENTICATION_SERV ICES. public static void main(String[] arv) { RadiusJdbcDemo radiusDemo = new RadiusJdbcDemo().jdbc. prop. Connection conn = driver. // The user "aso" needs to be properly setup on the radius server with // password "1234".com)(PORT=5561))(CONNECT_DATA=" + "(SERVICE_NAME=mydatabaseinstance)))". import oracle. try { radiusDemo.mydomain. printUserName(conn).printStackTrace().setProperty(OracleConnection.createStatement(). prop."1234"). public class RadiusJdbcDemo { String url ="jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)"+ "(HOST=oracleserver.prop). } catch (Exception e) { e.getAuthenticationAdaptorName()."aso").AUTHENTICATION_RADIUS+")"). * * It should print the following output to stdout: * ----------------------------------------------------* Authentication adaptor=RADIUS * User is:ASO * ----------------------------------------------------*/ void connect() throws SQLException { OracleDriver driver = new OracleDriver().

it is possible to store such credentials in a client-side Oracle wallet. See Also: Oracle Database Advanced Security Administrator's Guide for information about configuring your client to use secure external password store and for information about managing credentials in it. Instead your system looks for database login credentials in the client wallet.println("User is:"+rs.next()) System. applications can use the following syntax to connect to databases that use password authentication: CONNECT /@database_alias Note that you need not specify database login credentials in this CONNECT statement. or scripts. rs.executeQuery("select user from dual"). while(rs. not having to change application code also makes it easier to enforce password management policies for these user accounts. Storing database password credentials in a client-side Oracle wallet eliminates the need to embed user names and passwords in application code.out. batch jobs.close(). and simplifies maintenance because you need not change your code each time user names and passwords change. An Oracle wallet is a secure software container that is used to store authentication and signing credentials. In addition. } } } Secure External Password Store As an alternative for large-scale deployments where applications use password credentials to connect to databases.close(). } finally { if(stmt != null) stmt.Secure External Password Store ResultSet rs = stmt.getString(1)). JDBC Client-Side Security Features 9-21 . This reduces the risk of exposing passwords in the clear in scripts and application code. When you configure a client to use the external password store.

Secure External Password Store 9-22 Oracle Database JDBC Developer's Guide and Reference .

that is. This feature is supported through both the JDBC Oracle Call Interface (OCI) driver and the JDBC Thin driver. In this case. that is. You can design a middle-tier server to proxy clients in a secure fashion by using the following three forms of proxy authentication: ■ The middle-tier server authenticates itself with the database server and a client. See Also: ■ ■ "Creating Proxy Connections" on page 10-3 In all cases. The client's identity and database password are passed through the middle-tier server to the database server for authentication. a database user. It does not support it across multiple middle tiers. Client identities can be maintained all the way through to the database. Operations done on behalf of a client by a middle-tier server can be audited. Issue the following command to authorize the middle-tier server to proxy a client: ALTER USER jeff GRANT CONNECT THROUGH scott. The client. to act on behalf of the client. also called N-tier authentication.10 Proxy Authentication Oracle Java Database Connectivity (JDBC) provides proxy authentication. a global user. is authenticated by the middle-tier server. About Proxy Authentication Proxy authentication is the process of using a middle-tier for user authentication. an administrator must authorize the middle-tier server to proxy a client. authenticates itself with the middle-tier server. that is. and passes either a Distinguished name (DN) or a Certificate through the middle tier for retrieving the client's user name. Proxy Authentication 10-1 . This chapter contains the following sections: ■ ■ ■ ■ ■ About Proxy Authentication Types of Proxy Connections Creating Proxy Connections Closing a Proxy Session Caching Proxy Connections Note: Oracle Database supports proxy authentication functionality in three tiers only. is not authenticated by the middle-tier server. The client. an application user or another application.

jdbc. ■ Note: In this chapter. GRANT SELECT ON emp TO role1. The list of roles can be empty. The string that follows the identified globally as clause is the distinguished name. Types of Proxy Connections You can create proxy connections using any one of the following options: ■ USER NAME This is done by supplying the user name or the password or both. jeff is the user name and scott is the proxy for jeff. Having no authenticated clause implies default authentication.L=redwoodshores. In this case. You need to use the different fields and methods present in the oracle.OracleConnection interface to set up the different types of proxy connections.O=oracle. The SQL statement for specifying authentication using password is: ALTER USER jeff GRANT CONNECT THROUGH scott AUTHENTICATED USING password. The corresponding SQL statement to specify authentication using distinguished name is: ALTER USER jeff GRANT CONNECT THROUGH scott AUTHENTICATED USING DISTINGUISHED NAME. The password option exists for additional security.C=us'. CREATE ROLE role1. For example.Types of Proxy Connections where. a JDBC connection to a database is a user session in the database and vice versa. It is then necessary to authenticate using this distinguished name. The role clause limits the access only to those database objects that are mentioned in the list of the roles. Disallow a proxy connection by using the REVOKE CONNECT THROUGH clause of ALTER USER command. The SQL statement for specifying default authentication is: ALTER USER jeff GRANT CONNECT THROUGH scott ■ DISTINGUISHED NAME This is a global name in lieu of the password of the user being proxied for.ST=ca. You can also: ■ Specify roles that the middle tier is permitted to activate when connecting as the client. scott is the name of the proxy user.OU=americas. An example of the corresponding SQL statement using a distinguished name is: CREATE USER jeff IDENTIFIED GLOBALLY AS 'CN=jeff. which is using only the user name without the password. 10-2 Oracle Database JDBC Developer's Guide and Reference . ■ Find the users who are currently authorized to connect through a middle tier by querying the PROXY_USERS data dictionary view.

The server returns the new session id.OracleConnection interface: void openProxySession(int type. As a result. The JDBC OCI and Thin driver switch sessions in the same manner. The certificate contains the distinguished name encoded in it. The proxy user. type is the type of the proxy session and can have the following values: ■ OracleConnection. is not available until the new session. jeff. One way of generating the certificate is by creating a wallet and then decoding the wallet to get the certificate.Creating Proxy Connections ■ CERTIFICATE This is a more encrypted way of passing the credentials of the user. with the driver issuing a command to the server to create a session for the user.jdbc. It is then necessary to authenticate using the generated certificate. When opening a new proxied connection.OracleConnection interface to check if the current session associated with your connection is a proxy session. say scott. should have an active authenticated connection. A new proxy session is opened by using the following method from the oracle.Properties prop) throws SQLExceptionOpens Where. to the database. This method returns true if the current session associated with the connection is a proxy session. The wallet can be created using runutl mkwallet. who is to be proxied. jeff.util. java. Note: The use of certificates for proxy authentication will be desupported in future Oracle Database releases. ■ OracleConnection. say jeff. is closed. Note: You can use the isProxySession method from the oracle. the proxy session.PROXYTYPE_DISTINGUISHED_NAME Proxy Authentication 10-3 . and the driver sends a session switch command to switch to this new session.jdbc. Creating Proxy Connections A user. scott. Note: ■ ■ All the options can be associated with roles. scott. a new session is started on the database server. A proxy session is then created on this active connection. has to connect to the database through another user. The drivers permanently switch to the new session.PROXYTYPE_USER_NAME This type is used for specifying the user name. The SQL statement for specifying authentication using certificate is: ALTER USER jeff GRANT CONNECT THROUGH scott AUTHENTICATED USING CERTIFICATE. . jeff. Along with this session a new local transaction is created.

PROXYTYPE_USER_NAME OracleConnection. prop is the property value of the proxy session and can have the following values: ■ PROXY_USER_NAME This property value should be used with the type OracleConnection.lang.PROXY_ROLES. roles).PROXYTYPE_CERTIFICATE.PROXYTYPE_USER_NAME.Properties(). The value should be a java. The value should be a java.PROXYTYPE_CERTIFICATE The value should be a java.PROXYTYPE_USER_NAME.String. See Also: Closing a Proxy Session on page 10-4 ■ PROXY_USER_PASSWORD This property value should be used with the type OracleConnection.close method in the following way: 10-4 Oracle Database JDBC Developer's Guide and Reference . prop).PROXYTYPE_DISTINGUISHED_NAME.util.lang.put(OracleConnection. ■ OracleConnection. ■ PROXY_CERTIFICATE This property value should be used with the type OracleConnection.PROXYTYPE_CERTIFICATE This type is used for specifying the proxy certificate.lang.Properties prop = new java. ■ PROXY_SESSION This property value is used with the close method to close the proxy session. conn.util. ■ PROXY_ROLES This property value can be used with the following types: – – – OracleConnection.PROXYTYPE_USER_NAME.openProxySession(OracleConnection. String[] roles = {"role1".put(OracleConnection. The value should be a java.String. Closing a Proxy Session You can close the proxy session opened with the OracleConnection.String.String.PROXYTYPE_DISTINGUISHED_NAME OracleConnection. prop.Closing a Proxy Session This type is used for specifying the distinguished name of the user. The value is a bytep[] array that contains the certificate. "jeff"). ■ PROXY_DISTINGUISHED_NAME This property value should be used with the type OracleConnection. "role2"}. prop.openProxySession method by passing the OracleConnection. The following code snippet shows the use of the openProxySession method: java.PROXY_SESSION parameter to the OracleConnection.PROXY_USER_NAME.lang.

To cache a proxy connection. See Also: Chapter 21. See Also: Chapter 21. If the close method is called directly. but cannot be retrieved. When the tagged connection is retrieved. "Implicit Connection Caching" A proxy connection may be cached in the connection cache using the connection attributes feature of the connection cache. any user authenticated proxy connection can be cached and retrieved. then both the proxy session and the connection are closed. Therefore.Caching Proxy Connections OracleConnection. See Also: "Closing a Proxy Session" on page 10-4 Proxy Authentication 10-5 . The connection caching mechanism does not remember or reset session state. the connection is returned to the connection cache for reuse. It is recommended that proxy connections should not be closed without applying the connection attributes. like standard connections. Connection attributes are name/value pairs that are user-defined and help tag a connection before returning it to the connection cache for reuse.close(OracleConnection. The standard close method must be called explicitly to close the connection itself. Caching proxy connections enhances the performance. This can be achieved in the following way: OracleConnection. A proxy connection can be removed from the connection cache by closing the connection directly. can be cached. you need to create a connection using one of the getConnection methods on a cache enabled OracleDataSource object. This is similar to closing a proxy session on a non-cached connection.PROXY_SESSION).close(OracleConnection. Implicit connection cache supports caching of any user/password authenticated connection. "Implicit Connection Caching" Caching Proxy Connections Proxy connections. it can be directly used without having to do a round-trip to create or close a proxy session.INVALID_CONNECTION). If a proxy connection is closed without applying the connection attributes. without closing the proxy session.

Caching Proxy Connections 10-6 Oracle Database JDBC Developer's Guide and Reference .

such as nested tables. "Working with LOBs and BFILEs" Chapter 15. "Working with Oracle Object Types" Chapter 14. "Accessing and Manipulating Oracle Data" Chapter 12. Part IV contains the following chapters: ■ ■ ■ ■ ■ ■ ■ ■ ■ Chapter 11. "Globalization Support" . large object (LOB) and binary file (BFILE) locators and data. object references. "Result Set" Chapter 18. "JDBC RowSets" Chapter 19. This part also provides chapters that discuss the result set functionality in JDBC. "Java Streams in JDBC" Chapter 13. and Oracle collections. "Using Oracle Object References" Chapter 16. and globalization support provided by Oracle JDBC drivers. It also includes chapters that provide information about Java Database Connectivity (JDBC) support for user-defined object types. JDBC row sets.Part IV Data Access and Manipulation This part provides a chapter that discusses about accessing and manipulating Oracle data. "Working with Oracle Collections" Chapter 17.

.

and using the getOracleObject. OraclePreparedStatement. JDBC type codes.* formats involves casting your result sets and statements to OracleResultSet.sql package.sql. as opposed to standard Java formats.sql.* formats. This section contains the following topics: ■ ■ Table of Mappings Notes Regarding Mappings Table of Mappings Table 11–1 shows the default mappings between SQL data types. The Oracle Extension Java Types column lists the oracle. OracleStatement.sql.jdbc. getXXX. This chapter covers the following topics: ■ ■ ■ ■ ■ ■ Data Type Mappings Data Conversion Considerations Result Set and Statement Extensions Comparison of Oracle get and set Methods to Standard JDBC Using Result Set Metadata Extensions Using SQL CALL and CALL INTO Statements Data Type Mappings The Oracle JDBC drivers support standard JDBC types as well as Oracle-specific data types. This section documents standard and Oracle-specific SQL-Java default type mappings.sql.sql. These are Oracle extensions that let you retrieve all SQL data in the form of a oracle.* Java types that correspond to each SQL data type in the database.OracleTypes class. The JDBC Type Codes column lists data type codes supported by the JDBC standard and defined in the java. Using oracle. and Oracle extended types.Types class or by Oracle in the oracle. the codes are identical in these two classes. setOracleObject.* Java type. Manipulating Accessing and Manipulating Oracle Data 11-1 . as appropriate. and setXXX methods of these classes. The SQL Data Types column lists the SQL types that exist in Oracle Database 11g. The Standard Java Types column lists standard types defined in the Java language. For standard type codes. and OracleCallableStatement. where XXX corresponds to the types in the oracle.11 Accessing and Manipulating Oracle Data This chapter describes data access in oracle. standard Java types.

sql.TINYINT java.CHAR 11-2 Oracle Database JDBC Developer's Guide and Reference .DATE java.sql.math.Types.NUMBER oracle.Types.REF java.lang.sql.Ref java.sql.sql.Types.Types.Types.sql.sql.STRUCT oracle.String java.CHAR java.NClob java.sql.ROWID java.sql.Types.sql.Types.FLOAT java.sql.sql.ARRAY oracle.sql.Types.Date java.REF oracle.sql.DOUBLE java.Types.NUMERIC java.sql.sql.sql.sql.NUMBER l boolean byte short int long float double double byte[] byte[] oracle.sql.sql.Blob java.sql. See Also: "Package oracle.NUMBER oracle.NUMBER l java.sql.RowId java.sql.Types.DECIMAL java.sql.sql.Types.sql.VARCHAR java.sql.NUMBER oracle.Types.sql.sql.NUMBER oracle.sql.NUMBER oracle.sql.sql.sql.String java.sql.TIMESTAMP java.Struct java.Types.sql.sql.RAW oracle.sql.sql.NCLOB oracle.RAW oracle.Clob java.sql.Types.Time javal.LONGVARCHAR java.STRUCT java.sql.Types.sql.sql" on page 4-5 Table 11–1 Default Mappings Between SQL Types and Java Types JDBC Type Codes STANDARD JDBC TYPES: Standard Java Types Oracle Extension Java Types SQL Data Types CHAR VARCHAR2 LONG NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER RAW RAW LONGRAW DATE DATE TIMESTAMP BLOB CLOB user-defined object user-defined reference user-defined collection ROWID NCLOB NCHAR java.lang.BLOB java.NCHAR ORACLE EXTENSIONS: java.SMALLINT java.sql.sql.Types.* data types minimizes conversions.sql.TIMESTAMP java.Types.Timestamp oracle.Types.sql.CLOB oracle.ARRAY java.ROWID oracle.lang.CHAR oracle.Types.DATE java.INTEGER java.LONGVARBINARY byte[] java.math.Types.sql.NUMBER oracle.sql.Types.REAL java.sql.Types.BLOB oracle.sql.CHAR java.sql.CHAR oracle.BigDecima oracle.sql.lang.RAW oracle.BigDecima oracle.sql.sql.Types.Types. improving performance and eliminating conversion losses.BIGINT java.NUMBER oracle.Types.sql.sql.sql.DATE oracle.sql.Types.sql.BIT java.TIME java.sql.NCLOB java.BINARY java.sql.CLOB java.Array java.VARBINARY java.sql.sql.Types.sql.String oracle.String oracle.sql.sql.NUMBER oracle.Data Type Mappings SQL data as oracle.

such as objects. such as 8.TIME java. "Oracle Extensions" Notes Regarding Mappings This section provides further detail regarding mappings for NUMBER and user-defined types.OracleTypes. which do not support the TIMESTAMP data type.sql.) Default Mappings Between SQL Types and Java Types SQL Data Types BFILE REF CURSOR TIMESTAMP TIMESTAMP WITH TIME ZONE TIMESTAMP WITH LOCAL TIME ZONE JDBC Type Codes Standard Java Types Oracle Extension Java Types oracle.1. This section covers the following topics: Accessing and Manipulating Oracle Data 11-3 .Timestamp STAMPTZ oracle.BFILE oracle.ResultSet OR oracle.SQLData The Oracle-specific oracle.jdbc.OracleTypes.jdbc.sql. map by default to weak Java types.TIME java.Data Conversion Considerations Table 11–1 (Cont.sql.sql.jdbc. object references.sql.sql.TIMESTAMP LTZ oracle.sql package.TIMESTAMP oracle.CURS java.jdbc.7. Custom Java classes can implement one of two interfaces: ■ ■ The standard java.OracleTypes.Struct. call the getter routine that is appropriate for the size of the data for mapping to work properly.sql. call getByte to get a Java tinyint value for an item x. and collections.sql. such as java. NUMBER Types For the different type codes that an Oracle NUMBER value can correspond to.ORAData See Also: "Mapping Oracle Objects" on page 13-1 and "Creating and Using Custom Object Classes for Oracle Objects" on page 13-6 Data Conversion Considerations When JDBC programs retrieve SQL data into Java.sql.OracleRe sultSet oracle.jdbc. but alternatively can map to strongly typed custom Java classes.OracleTypes. For example. or you can use types of the oracle. TIMESTAMP is mapped to DATE. where -128 < x < 128.jdbc.sql.Timestamp STAMP oracle.BFIL NA E oracle.sql.OracleTypes.TIME java. you can use standard Java types.Timestamp STAMPLTZ Note: For database versions.TIMESTAMP TZ oracle. See Also : ■ ■ "Valid SQL-JDBC Data Type Mappings" on page A-1 Chapter 4. User-Defined Types User-defined types.

Data Conversion Considerations

■ ■ ■

Standard Types Versus Oracle Types Converting SQL NULL Data Testing for NULLs

Standard Types Versus Oracle Types
The Oracle data types in oracle.sql store data in the same bit format as used by the database. In versions of the Oracle JDBC drivers prior to Oracle Database 10g, the Oracle data types were generally more efficient. The Oracle Database 10g JDBC drivers were substantially updated. As a result, in most cases the standard Java types are preferred to the data types in oracle.sql. In particular, java.lang.String is much more efficient than oracle.sql.CHAR. In general, Oracle recommends that you use the Java standard types. The exceptions to this are:

Use the oracle.sql.OraData rather than the java.sql.SqlData if the OraData functionality better suits your needs. Use oracle.sql.NUMBER rather than java.lang.Double if you need to retain the exact values of floating point numbers. Oracle NUMBER is a decimal representation and Java Double and Float are binary representations. Conversion from one format to the other can result in slight variations in the actual value represented. Additionally, the range of values that can be represented using the two formats is different. Use oracle.sql.DATE or oracle.sql.TIMESTAMP rather than java.sql.Date or java.sql.Timestamp if you are using JDK 1.5 or earlier versions or require maximum performance. You may also use the oracle.sql data type if you want to read many date values or compute or display only a small percentage. Due to a bug in all versions of Java prior to JDK 1.6, construction of java.lang.Date and java.lang.Timestamp objects is slow, especially in multithreaded environments. This bug is fixed in JDK 1.6.
Note:

If you convert an oracle.sql data type to a Java standard data type, then the benefits of using the oracle.sql data type are lost.

Converting SQL NULL Data
Java represents a SQL NULL datum by the Java value null. Java data types fall into two categories: primitive types, such as byte, int, and float, and object types, such as class instances. The primitive types cannot represent null. Instead, they store null as the value zero, as defined by the JDBC specification. This can lead to ambiguity when you try to interpret your results. In contrast, Java object types can represent null. The Java language defines an object container type corresponding to every primitive type that can represent null. The object container types must be used as the targets for SQL data to detect SQL NULL without ambiguity.

Testing for NULLs
You cannot use a relational operator to compare NULL values with each other or with other values. For example, the following SELECT statement does not return any row even if the COMM column contains one or more NULL values.

11-4 Oracle Database JDBC Developer's Guide and Reference

Comparison of Oracle get and set Methods to Standard JDBC

PreparedStatement pstmt = conn.prepareStatement( "SELECT * FROM EMP WHERE COMM = ?"); pstmt.setNull(1, java.sql.Types.VARCHAR);

The next example shows how to compare values for equality when some return values might be NULL. The following code returns all the ENAMES from the EMP table that are NULL, if there is no value of 100 for COMM.
PreparedStatement pstmt = conn.prepareStatement("SELECT ENAME FROM EMP WHERE COMM =? OR ((COMM IS NULL) AND (? IS NULL))"); pstmt.setBigDecimal(1, new BigDecimal(100)); pstmt.setNull(2, java.sql.Types.VARCHAR);

Result Set and Statement Extensions
The JDBC Statement object returns an OracleResultSet object, typed as a java.sql.ResultSet. If you want to apply only standard JDBC methods to the object, then keep it as a ResultSet type. However, if you want to use the Oracle extensions on the object, then you must cast it to OracleResultSet. All of the Oracle Result Set extensions are in the oracle.jdbc.OracleResultSet interface and all the Statement extensions are in the oracle.jdbc.OracleStatement interface. For example, assuming you have a standard Statement object stmt, do the following if you want to use only standard JDBC ResultSet methods:
ResultSet rs = stmt.executeQuery("SELECT * FROM emp");

If you need the extended functionality provided by the Oracle extensions to JDBC, you can select the results into a standard ResultSet variable and then cast that variable to OracleResultSet later. Key extensions to the result set and statement classes include the getOracleObject and setOracleObject methods, used to access and manipulate data in oracle.sql.* formats.

Comparison of Oracle get and set Methods to Standard JDBC
This section describes get and set methods, particularly the JDBC standard getObject and setObject methods and the Oracle-specific getOracleObject and setOracleObject methods, and how to access data in oracle.sql.* format compared with Java format. Although there are specific getXXX methods for all the Oracle SQL types, you can use the general get methods for convenience or simplicity, or if you are not certain in advance what type of data you will receive. This section covers the following topics:
■ ■ ■ ■ ■ ■ ■

Standard getObject Method Oracle getOracleObject Method Summary of getObject and getOracleObject Return Types Other getXXX Methods Data Types For Returned Objects from getObject and getXXX The setObject and setOracleObject Methods Other setXXX Methods
Accessing and Manipulating Oracle Data 11-5

Comparison of Oracle get and set Methods to Standard JDBC

Note: You cannot qualify a column name with a table name and pass it as a parameter to the getXXX method. For example:
ResultSet rset = stmt.executeQuery("SELECT emp.deptno, dept.deptno FROM emp, dept"); rset.getInt("emp.deptno");

The getInt method in the preceding code will throw an exception. To uniquely identify the columns in the getXXX method, you can either use column index or specify column aliases in the query and use these aliases in the getXXX method.

Standard getObject Method
The standard getObject method of a result set or callable statement has a return type of java.lang.Object. The class of the object returned is based on its SQL type, as follows:

For SQL data types that are not Oracle-specific, getObject returns the default Java type corresponding to the SQL type of the column, following the mapping in the JDBC specification. For Oracle-specific data types, getObject returns an object of the appropriate oracle.sql.* class, such as oracle.sql.ROWID. For Oracle database objects, getObject returns a Java object of the class specified in your type map. Type maps specify a mapping from database named types to Java classes. The getObject(parameter_index) method uses the default type map of the connection. The getObject(parameter_index, map) enables you to pass in a type map. If the type map does not provide a mapping for a particular Oracle object, then getObject returns an oracle.sql.STRUCT object.

Oracle getOracleObject Method
If you want to retrieve data from a result set or callable statement as an oracle.sql.* object, then you must follow a special process. For a Result Set, you must cast the Result Set itself to oracle.jdbc.OracleResultSet and then call getOracleObject instead of getObject. The same applies to CallableStatement and oracle.jdbc.OracleCallableStatement. The return type of getOracleObject is oracle.sql.Datum. The actual returned object is an instance of the appropriate oracle.sql.* class. The method signature is:
public oracle.sql.Datum getOracleObject(int parameter_index)

When you retrieve data into a Datum variable, you can use the standard Java instanceof operator to determine which oracle.sql.* type it really is. Example: Using getOracleObject with a Result Set The following example creates a table that contains a column of CHAR data and a column containing a BFILE locator. A SELECT statement retrieves the contents of the table as a result set. The getOracleObject then retrieves the CHAR data into the char_datum variable and the BFILE locator into the bfile_datum variable. Note that because getOracleObject returns a Datum object, the return values must be cast to CHAR and BFILE, respectively.
stmt.execute ("CREATE TABLE bfile_table (x VARCHAR2 (30), b BFILE)"); stmt.execute

11-6 Oracle Database JDBC Developer's Guide and Reference

Comparison of Oracle get and set Methods to Standard JDBC

("INSERT INTO bfile_table VALUES ('one', BFILENAME ('TEST_DIR', 'file1'))"); ResultSet rset = stmt.executeQuery ("SELECT * FROM bfile_table"); while (rset.next ()) { CHAR char_datum = (CHAR) ((OracleResultSet)rset).getOracleObject (1); BFILE bfile_datum = (BFILE) ((OracleResultSet)rset).getOracleObject (2); ... }

Example: Using getOracleObject in a Callable Statement The following example prepares a call to the procedure myGetDate, which associates a character string with a date. The program passes "SCOTT" to the prepared call and registers the DATE type as an output parameter. After the call is run, getOracleObject retrieves the date associated with "SCOTT". Note that because getOracleObject returns a Datum object, the results are cast to DATE.
OracleCallableStatement cstmt = (OracleCallableStatement)conn.prepareCall ("begin myGetDate (?, ?); end;"); cstmt.setString (1, "SCOTT"); cstmt.registerOutParameter (2, Types.DATE); cstmt.execute (); DATE date = (DATE) ((OracleCallableStatement)cstmt).getOracleObject (2); ...

Summary of getObject and getOracleObject Return Types
Table 11–2 lists the underlying return types for the getObject and getOracleObject methods for each Oracle SQL type. Keep in mind the following when you use these methods:
■ ■

getObjectalways returns data into a java.lang.Object instance getOracleObject always returns data into an oracle.sql.Datum instance

You must cast the returned object to use any special functionality.

Table 11–2

getObject and getOracleObject Return Types getObject Underlying Return Type String String String String java.math.BigDecimal byte[] byte[] java.sql.Date java.sql.Timestamp
1

Oracle SQL Type CHAR VARCHAR2 NCHAR LONG NUMBER RAW LONGRAW DATE TIMESTAMP

getOracleObject Underlying Return Type oracle.sql.CHAR oracle.sql.CHAR oracle.sql.CHAR oracle.sql.CHAR oracle.sql.NUMBER oracle.sql.RAW oracle.sql.RAW oracle.sql.DATE oracle.sql.TIMESTAMP

Accessing and Manipulating Oracle Data 11-7

Comparison of Oracle get and set Methods to Standard JDBC

Table 11–2 (Cont.) getObject and getOracleObject Return Types Oracle SQL Type TIMESTAMP WITH TIME ZONE TIMESTAMP WITH LOCAL TIME ZONE BINARY_FLOAT BINARY_DOUBLE INTERVAL DAY TO SECOND INTERVAL YEAR TO MONTH ROWID REF CURSOR BLOB CLOB NCLOB BFILE Oracle object getObject Underlying Return Type oracle.sql.TIMESTAMPTZ oracle.sql.TIMESTAMPLTZ java.lang.Float java.lang.Double oracle.sql.INTERVALDS oracle.sql.INTERVALYM oracle.sql.ROWID java.sql.ResultSet oracle.sql.BLOB oracle.sql.CLOB java.sql.NClob oracle.sql.BFILE class specified in type map or oracle.sql.STRUCT (if no type map entry) Oracle object reference collection (varray or nested table)
1

getOracleObject Underlying Return Type oracle.sql.TIMESTAMPTZ oracle.sql.TIMESTAMPLTZ oracle.sql.BINARY_FLOAT oracle.sql.BINARY_DOUBLE oracle.sql.INTERVALDS oracle.sql.INTERVALYM oracle.sql.ROWID (not supported) oracle.sql.BLOB oracle.sql.CLOB oracle.sql.NCLOB oracle.sql.BFILE oracle.sql.STRUCT

oracle.sql.REF oracle.sql.ARRAY

oracle.sql.REF oracle.sql.ARRAY

ResultSet.getObject returns java.sql.Timestamp only if the oracle.jdbc.J2EE13Compliant connection property is set to TRUE, else the method returns oracle.sql.TIMESTAMP.

11-8 Oracle Database JDBC Developer's Guide and Reference

Comparison of Oracle get and set Methods to Standard JDBC

The ResultSet.getObject method returns java.sql.Timestamp for the TIMESTAMP SQL type, only when the connection property oracle.jdbc.J2EE13Compliant is set to TRUE. This property has to be set when the connection is obtained. If this connection property is not set or if it is set after the connection is obtained, then the ResultSet.getObject method returns oracle.sql.TIMESTAMP for the TIMESTAMP SQL type.
Note:

The oracle.jdbc.J2EE13Compliant connection property can also be set without changing the code in the following ways:

Including the ojdbc5dms.jar or ojdbc6dms.jar files in the CLASSPATH. These files set oracle.jdbc.J2EE13Compliant to TRUE by default. These are specific to the Oracle Application Server release and are not available as part of the general JDBC release. They are located in $ORACLE_HOME/jdbc/lib. Setting the system property by calling the java command with the flag -Doracle.jdbc.J2EE13Compliant=true. For example,
java -Doracle.jdbc.J2EE13Compliant=true ...

When the J2EE13Compliant is set to TRUE the action is as in Table B-3 of the JDBC specification.
See Also: Table A–1, " Valid SQL Data Type-Java Class Mappings" on page A-1, for information about type compatibility between all SQL and Java types.

Other getXXX Methods
Standard JDBC provides a getXXX for each standard Java type, such as getByte, getInt, getFloat, and so on. Each of these returns exactly what the method name implies. In addition, the OracleResultSet and OracleCallableStatement classes provide a full complement of getXXX methods corresponding to all the oracle.sql.* types. Each getXXX method returns an oracle.sql.XXX object. For example, getROWID returns an oracle.sql.ROWID object. There is no performance advantage in using the specific getXXX methods. However, they do save you the trouble of casting, because the return type is specific to the object being returned. This section covers the following topics:
■ ■

Return Types of getXXX Methods Special Notes about getXXX Methods

Return Types of getXXX Methods
Refer to the Java doc to know the return types for each getXXX method and also which are Oracle extensions under Java Development Kit (JDK) 1.6. You must cast the returned object to OracleResultSet or OracleCallableStatement to use methods that are Oracle extensions.

Accessing and Manipulating Oracle Data 11-9

Comparison of Oracle get and set Methods to Standard JDBC

Special Notes about getXXX Methods
This section provides additional details about some getXXX methods. getBigDecimal JDBC 2.0 simplified method signatures for the getBigDecimal method. The previous input signatures were:
(int columnIndex, int scale) or (String columnName, int scale)

The simplified input signature is:
(int columnIndex) or (String columnName)

The scale parameter, used to specify the number of digits to the right of the decimal, is no longer necessary. The Oracle JDBC drivers retrieve numeric values with full precision. getBoolean Because there is no BOOLEAN database type, when you use getBoolean a data type conversion always occurs. The getBoolean method is supported only for numeric columns. When applied to these columns, getBoolean interprets any zero value as false and any other value as true. When applied to any other sort of column, getBoolean raises the exception java.lang.NumberFormatException.

Data Types For Returned Objects from getObject and getXXX
The return type of getObject is java.lang.Object. The returned value is an instance of a subclass of java.lang.Object. Similarly, the return type of getOracleObject is oracle.sql.Datum, and the class of the returned value is a subclass of oracle.sql.Datum. You typically cast the returned object to the appropriate class to use particular methods and functionality of that class. In addition, you have the option of using a specific getXXX method instead of the generic getObject or getOracleObject methods. The getXXX methods enable you to avoid casting, because the return type of getXXX corresponds to the type of object returned. For example, the return type of getCLOB is oracle.sql.CLOB, as opposed to java.lang.Object. Example of Casting Return Values This example assumes that you have fetched data of the NUMBER type as the first column of a result set. Because you want to manipulate the NUMBER data without losing precision, cast your result set to OracleResultSet and use getOracleObject to return the NUMBER data in oracle.sql.* format. If you do not cast your result set, then you have to use getObject, which returns your numeric data into a Java Float and loses some of the precision of your SQL data. The getOracleObject method returns an oracle.sql.NUMBER object into an oracle.sql.Datum return variable unless you cast the output. Cast the getOracleObject output to oracle.sql.NUMBER if you want to use a NUMBER return variable and any of the special functionality of that class.
NUMBER x = (NUMBER)ors.getOracleObject(1);

11-10 Oracle Database JDBC Developer's Guide and Reference

Comparison of Oracle get and set Methods to Standard JDBC

The setObject and setOracleObject Methods
Just as there is a standard getObject and Oracle-specific getOracleObject in result sets and callable statements, there are also standard setObject and Oracle-specific setOracleObject methods in OraclePreparedStatement and OracleCallableStatement. The setOracleObject methods take oracle.sql.* input parameters. To bind standard Java types to a prepared statement or callable statement, use the setObject method, which takes a java.lang.Object as input. The setObject method does support a few of the oracle.sql.* types. However, the method has been implemented so that you can enter instances of the oracle.sql.* classes that correspond to the following JDBC standard types: Blob, Clob, Struct, Ref, and Array. To bind oracle.sql.* types to a prepared statement or callable statement, use the setOracleObject method, which takes a subclass of oracle.sql.Datum as input. To use setOracleObject, you must cast your prepared statement or callable statement to OraclePreparedStatement or OracleCallableStatement. Example of Using setObject and setOracleObject For a prepared statement, the setOracleObject method binds the oracle.sql.CHAR data represented by the charVal variable to the prepared statement. To bind the oracle.sql.* data, the prepared statement must be cast to OraclePreparedStatement. Similarly, the setObject method binds the Java String data represented by the variable strVal.
PreparedStatement ps= conn.prepareStatement("text_of_prepared_statement"); ((OraclePreparedStatement)ps).setOracleObject(1,charVal); ps.setObject(2,strVal);

Other setXXX Methods
As with the getXXX methods, there are several specific setXXX methods. Standard setXXX methods are provided for binding standard Java types, and Oracle-specific setXXX methods are provided for binding Oracle-specific types. Similarly, there are two forms of the setNull method:

void setNull(int parameterIndex, int sqlType) This is specified in the standard java.sql.PreparedStatement interface. This signature takes a parameter index and a SQL type code defined by the java.sql.Types or oracle.jdbc.OracleTypes class. Use this signature to set an object other than a REF, ARRAY, or STRUCT to NULL.

void setNull(int parameterIndex, int sqlType, String sql_type_name) With JDBC 2.0, this signature is also specified in the standard java.sql.PreparedStatement interface. This method takes a SQL type name in addition to a parameter index and a SQL type code. Use this method when the SQL type code is java.sql.Types.REF, ARRAY, or STRUCT. If the type code is other than REF, ARRAY, or STRUCT, then the given SQL type name is ignored.

Similarly, the registerOutParameter method has a signature for use with REF, ARRAY, or STRUCT data:
void registerOutParameter (int parameterIndex, int sqlType, String sql_type_name)

Accessing and Manipulating Oracle Data 11-11

Comparison of Oracle get and set Methods to Standard JDBC

Binding Oracle-specific types using the appropriate setXXX methods, instead of the methods used for binding standard Java types, may offer some performance advantage. This section covers the following topics:
■ ■

Input Data Binding Method setFixedCHAR for Binding CHAR Data into WHERE Clauses

Input Data Binding
There are three way to bind data for input:
■ ■ ■

Direct binding where the data itself is placed in a bind buffer Stream binding where the data is streamed LOB binding where a temporary lob is created, the data placed in the LOB using the LOB APIs, and the bytes of the LOB locator are placed in the bind buffer

The three kinds of binding have some differences in performance and have an impact on batching. Direct binding is fast and batching is fine. Stream binding is slower, may require multiple round trips, and turns batching off. LOB binding is very slow and requires many round trips. Batching works, but might be a bad idea. They also have different size limits, depending on the type of the SQL statement. For SQL parameters, the length of standard parameter types, such as RAW and VARCHAR2, is fixed by the size of the target column. For PL/SQL parameters, the size is limited to a fixed number of bytes, which is 32766. In Oracle Database 10g release 2 (10.2), certain changes were made to the setString, setCharacterStream, setAsciiStream, setBytes, and setBinaryStream methods of PreparedStatement. The original behavior of these APIs were:
■ ■ ■ ■ ■

setString: Direct bind of characters setCharacterStream: Stream bind of characters setAsciiStream: Stream bind of bytes setBytes: Direct bind of bytes setBinaryStream: Stream bind of bytes

Starting from Oracle Database 10g release 2 (10.2), automatic switching between binding modes, based on the data size and on the type of the SQL statement is provided. setBytes and setBinaryStream For SQL, direct bind is used for size up to 2000 and stream bind for larger. For PL/SQL direct bind is used for size up to 32766 and LOB bind is used for larger. setString, setCharacterStream, and setAsciiStream For SQL, direct bind is used up to 32766 Java characters and stream bind is used for larger. This is independent of character set. For PL/SQL, you must be careful about the byte size of the character data in the database character set or the national character set depending on the setting of the form of use parameter. Direct bind is used for data where the byte length is less than 32766 and LOB bind is used for larger.

11-12 Oracle Database JDBC Developer's Guide and Reference

Comparison of Oracle get and set Methods to Standard JDBC

For fixed length character sets, multiply the length of the Java character data by the fixed character size in bytes and compare that to the restrictive values. For variable length character sets, there are three cases based on the Java character length, as follows:

If character length is less than 32766 divided by the maximum character size, then direct bind is used. If character length is greater than 32766 divided by the minimum character size, then LOB bind is used. If character length is in between and if the actual length of the converted bytes is less than 32766, then direct bind is used, else LOB bind is used. When a PL/SQL procedure is embedded in a SQL statement, the binding action is different. Refer to "Data Interface for LOBs" on page 14-10 for more information.
Note:

The server-side internal driver has the following additional limitations:

setString, setCharacterStream, and setASCIIStream APIs are not supported for SQL CLOB columns when the data size in characters is over 4000 bytes setBytes and setBinaryStream APIs are not supported for SQL BLOB columns when the data size is over 2000 bytes
Important: Do not use these APIs with the server-side internal

driver, without careful checking of the datasize in client code.
See Also: JDBC Release Notes for further discussion and possible workarounds

Method setFixedCHAR for Binding CHAR Data into WHERE Clauses
CHAR data in the database is padded to the column width. This leads to a limitation in using the setCHAR method to bind character data into the WHERE clause of a SELECT statement. The character data in the WHERE clause must also be padded to the column width to produce a match in the SELECT statement. This is especially troublesome if you do not know the column width. To remedy this, Oracle has added the setFixedCHAR method to the OraclePreparedStatement class. This method runs a non-padded comparison.
Note:

Remember to cast your prepared statement object to OraclePreparedStatement to use the setFixedCHAR method. There is no need to use setFixedCHAR for an INSERT statement. The database always automatically pads the data to the column width as it inserts it.

Accessing and Manipulating Oracle Data 11-13

((OraclePreparedStatement)pstmt).. System. "JDBC"). System. while (rs. rs.getMetaData(). rs = null.getColumnCount().println("Num of columns = " + numColumns). i<numColumns.setFixedCHAR(1. // Pad it to 10 bytes runQuery (pstmt). "JDBC").Using Result Set Metadata Extensions Example The following example demonstrates the difference between the setCHAR and setFixedCHAR methods. // This will print "No of rows are 1" void runQuery (PreparedStatement ps) { // Run the Query ResultSet rs = pstmt. null).getInt(1)).getColumnType (i + 1) ). pstmt.println("No of rows are " + rs. } Using Result Set Metadata Extensions The oracle. for (int i=0. */ PreparedStatement pstmt = conn.getColumnName (i+1)). System.close().print (" Type=" + orsmd. insert into my_table values ('JDBC'). "EMP". int numColumns = orsmd.getTables("".print ("Column Name=" + orsmd. while (rset.getMetaData().setCHAR(1. runQuery (pstmt). /* Schema is : create table my_table (col1 char(10)).out. i++) { System.out. // Set the Bind Value // This will print " No of rows are 0" CHAR ch = new CHAR("JDBC ". ch).out. // This will print "No of rows are 1" ((OraclePreparedStatement)pstmt). runQuery (pstmt). "SCOTT".out. The following code snippet uses several of the methods in the OracleResultSetMetadata interface to retrieve the number of columns from the EMP table and the numerical type and SQL type name of each column: DatabaseMetaData dbmd = conn. null).next()) { OracleResultSetMetaData orsmd = ((OracleResultSet)rset).jdbc.OracleResultSetMetaData interface is JDBC 2.out.println (" Type Name=" + orsmd.getColumnTypeName (i + 1)). } } 11-14 Oracle Database JDBC Developer's Guide and Reference .0-compliant but does not implement the getSchemaName and getTableName methods because Oracle Database does not make this feasible.setString (1.executeQuery ().prepareStatement ("select count(*) from my_table where col1 = ?").next()) System. ResultSet rset = dbmd.

You can use the following types of variables with this clause: ■ ■ Host variable Indicator variable PL/SQL Blocks The basic unit in PL/SQL is a block.Using SQL CALL and CALL INTO Statements The program returns the following output: Num of Column Column Column Column Column columns = 5 Name=TABLE_CAT Type=12 Type Name=VARCHAR2 Name=TABLE_SCHEM Type=12 Type Name=VARCHAR2 Name=TABLE_NAME Type=12 Type Name=VARCHAR2 Name=TABLE_TYPE Type=12 Type Name=VARCHAR2 Name=TABLE_REMARKS Type=12 Type Name=VARCHAR2 Using SQL CALL and CALL INTO Statements You can use the CALL statement to execute a routine from within SQL. You can execute a routine in two ways: ■ ■ By issuing a call to the routine itself by name or by using the routine_clause By using an object_access_expression inside the type of an expression You can specify one or more arguments to the routine. if the routine takes arguments. or mixed notation for argument. CALL INTO Statement The INTO clause applies only to calls to functions. Note: A routine is a procedure or a function that is standalone or is defined within a type or package. You must have EXECUTE privilege on the standalone routine or on the type or package in which the routine is defined. and an exception-handling part. You get the following advantages by using PL/SQL blocks in your application: ■ ■ ■ ■ ■ Better performance Higher productivity Full portability Tight integration with Oracle Tight security Accessing and Manipulating Oracle Data 11-15 . Refer to the "Oracle Database SQL Language Reference" for more information about using the CALL statement. A PL/SQL block has three parts: a declarative part. You can use positional. named. All PL/SQL programs are made up of blocks. an executable part. which can be nested within each other.

Using SQL CALL and CALL INTO Statements 11-16 Oracle Database JDBC Developer's Guide and Reference .

and corresponds to the getUnicodeStream method The getBinaryStream. and corresponds to the getAsciiStream method ■ Unicode Used for Unicode bytes with the UTF-16 encoding. This chapter covers the following topics: ■ ■ ■ ■ ■ ■ ■ Streaming LONG or LONG RAW Columns Streaming CHAR. The drivers support all stream conversions: binary. or RAW Columns Streaming LOBs and External Files Data Streaming and Multiple Columns Streaming and Row Prefetching Closing a Stream Notes and Precautions on Streams Overview of Java Streams Oracle JDBC drivers support the manipulation of data streams in either direction between server and client. "Working with LOBs and BFILEs" Java Streams in JDBC 12-1 . ASCII. Data streams enable you to read LONG column data of up to 2 gigabytes (GB). and getUnicodeStream methods return the bytes of data in an InputStream object. Following is a brief description of each type of stream: ■ Binary Used for RAW bytes of data. and Unicode. VARCHAR. See Also: Chapter 14. getAsciiStream. Methods associated with streams let you read the data incrementally.12 Java Streams in JDBC This chapter describes how the Oracle Java Database Connectivity (JDBC) drivers handle Java streams for several data types. and corresponds to the getBinaryStream method ■ ASCII Used for ASCII bytes in ISO-Latin-1 encoding.

As an alternative. VARCHAR. you get a stream of Unicode characters in the UTF-16 encoding. Oracle recommends that you convert existing LONG columns to LOB columns. A call to getAsciiStream converts the RAW data to hexadecimal and returns the ASCII representation. Note: Do not create tables with LONG columns. and BLOB. or RAW Columns Streaming LOBs and External Files Data Streaming and Multiple Columns Closing a Stream Notes and Precautions on Streams LONG RAW Data Conversions A call to getBinaryStream returns RAW data. a call to getAsciiStream returns meaningless information. the JDBC driver transfers these columns to the client in streaming mode. LOB columns are subject to far fewer restrictions than LONG columns. the drivers assume that the underlying data in the database uses an US7ASCII or WE8ISO8859P1 character set. there are two possible cases: 12-2 Oracle Database JDBC Developer's Guide and Reference . If the database is not using an US7ASCII or WE8ISO8859P1 character set. the data of the LONG column is waiting to be read. Use large object (LOB) columns. In this case. When you get LONG data with getUnicodeStream. Note: Oracle recommends avoiding LONG and LONG RAW columns. you can get the column as a Java InputStream object and use the read method of the InputStream object. A call to getUnicodeStream converts the RAW data to hexadecimal and returns the Unicode characters. you can get the data as a String or byte array. CLOB. instead. If the assumption is true. the driver will do the streaming for you. To access the data in a LONG column. LONG Data Conversions When you get LONG data with getAsciiStream. This applies to all underlying database character sets that Oracle supports. Use LOB instead. This section covers the following topics: ■ ■ ■ ■ ■ ■ Streaming LONG or LONG RAW Columns Streaming CHAR. You can get LONG and LONG RAW data with any of the three stream types. LONG columns are supported only for backward compatibility. After a call to executeQuery or next. The driver performs conversions for you.Streaming LONG or LONG RAW Columns Streaming LONG or LONG RAW Columns When a query selects one or more LONG or LONG RAW columns. NCLOB. When you get LONG data with getBinaryStream. depending on the character set of the database and the driver. then the drivers return bytes corresponding to ASCII characters.

then a call to getBinaryStream returns UTF-8. then the call returns a US7ASCII stream of bytes. insert into streamexample values ('LESLIE'. GIFDATA long raw). If the driver is JDBC Thin and the database character set is not US7ASCII or WE8ISO8859P1. "Globalization Support" and "Data Streaming and Multiple Columns" on page 12-7 ■ Note: Receiving LONG or LONG RAW columns as a stream requires you to pay special attention to the order in which you retrieve columns from the database. unchanged data AsciiStream Bytes representing characters in ISO-Latin-1 (WE8ISO8859P1) encoding UnicodeStream Bytes representing characters in Unicode UTF-16 encoding LONG RAW ASCII representation of hexadecimal bytes Unicode representation of hexadecimal bytes Streaming Example for LONG RAW Data One of the features of a getXXXStream method is that it enables you to fetch data incrementally.SQL code: create table streamexample (NAME varchar2 (256). the driver fetches the data incrementally. If the client character set is US7ASCII or WE8ISO8859P1. '00010203040506070809'). If the server-side character set is US7ASCII or WE8ISO8859P1. The following Java code snippet writes the data from the LONG RAW column into a file called leslie. The first version uses the getBinaryStream method to obtain LONG RAW data. Tip: Chapter 19. This section contains two examples of getting a stream of binary data.Streaming LONG or LONG RAW Columns ■ If the driver is JDBC OCI and the client character set is not US7ASCII or WE8ISO8859P1. The following code creates the table that stores a column of LONG RAW data associated with the name LESLIE: -. and the second version uses the getBytes method. In this case. The bytes can represent characters in US7ASCII or WE8ISO8859P1 if the database character set is US7ASCII or WE8ISO8859P1. then a call to getBinaryStream returns UTF-8.gif: ResultSet rset = stmt. Getting a LONG RAW Data Column with getBinaryStream This example writes the contents of a LONG RAW column to a file on the local file system. then the call returns a US7ASCII stream of bytes.executeQuery ("select GIFDATA from streamexample where NAME='LESLIE'"). Table 12–1 Data type LONG LONG and LONG RAW Data Conversions BinaryStream Bytes representing characters in Unicode UTF-8. getBytes fetches all the data in one call. In contrast. Table 12–1 summarizes LONG and LONG RAW data conversions for each stream type. // get first row Java Streams in JDBC 12-3 .

} catch (Exception e) { String err = e. file = new FileOutputStream ("leslie. } } Because a LONG RAW column can contain up to 2 gigabytes of data. try { FileOutputStream file = null.next()) { // Get the GIF data as a stream from Oracle to the client byte[] bytes = rset2.write(chunk).println(err).close(). Getting a LONG RAW Data Column with getBytes This example gets the content of the GIFDATA column with getBytes instead of getBinaryStream.next()) { // Get the GIF data as a stream from Oracle to the client InputStream gif_data = rset. } catch (Exception e) { String err = e. while ((chunk = gif_data. file.Streaming LONG or LONG RAW Columns if (rset.close(). the getBytes example can use much more memory than the getBinaryStream example. } } In this example. In this case.write(bytes). file = new FileOutputStream ("leslie2. The code snippet is as follows: ResultSet rset2 = stmt. try { FileOutputStream file = null. the InputStream object returned by the call to getBinaryStream reads the data directly from the database connection.toString().read()) != -1) file.executeQuery ("select GIFDATA from streamexample where NAME='LESLIE'").println(err).getBytes(1). } finally { if file != null() file. int chunk. System.gif").toString().getBinaryStream (1).out. the driver fetches all the data in one call and stores it in a byte array. } finally { if file != null() file. System. Use 12-4 Oracle Database JDBC Developer's Guide and Reference .gif").out. // get first row if (rset2.

the Statement object stmt is cast to OracleStatement and the column containing LONG RAW data is redefined to be of the type VARBINARAY. VARCHAR. In addition. Using the example from the previous section. using defineColumnType saves the OCI and KPRB drivers a database round-trip when running the query. The code snippet is as follows: //cast the statement stmt to an OracleStatement oracle.getBytes(1).defineColumnType(1. However.jdbc. If you try to get a CHAR.jdbc. then executeQuery will fail. //redefine the LONG column at index position 1 to VARBINARY ostmt.OracleStatement)stmt.jdbc. or RAW column as a LONGVARCHAR or LONGVARBINARY. If you do not declare the types of the columns. these JDBC drivers must request the data types of the column types. or RAW Columns streams if you do not know the maximum size of the data in your LONG or LONG RAW columns. In the case of these data types. then you must declare the types of the columns in the query. The JDBC Thin driver derives no benefit from defineColumnType. or RAW column as a data stream without redefining the column type. For example. // Do a query to get the images named 'LESLIE' ResultSet rset = ostmt. then you can get the column as a stream. you must cast the Statement object to oracle. Without defineColumnType. Streaming CHAR. it is returned in a byte array. because these columns are usually short. As an added benefit.Streaming CHAR. then you may want to avoid returning the data incrementally and.executeQuery ("select GIFDATA from streamexample where NAME='LESLIE'"). Note that there is not much point to this. The program will behave as if the column were actually of type LONG or LONG RAW. instead. If you redefine column types with defineColumnType. if you redefine the LONG or LONG RAW column as VARCHAR or VARBINARY type. but no real streaming occurs.OracleStatement ostmt = (oracle.OracleStatement. use the defineColumnType method to redefine the type of the LONG column. the JDBC driver fully fetches the data into an in-memory buffer during a call to the executeQuery method or the next Java Streams in JDBC 12-5 . For example. To avoid streaming. VARCHAR. // The data is not streamed here rset. there may be situations where you want to avoid data streaming. VARCHAR. Avoiding Streaming for LONG or LONG RAW The JDBC driver automatically streams any LONG and LONG RAW columns. if you have a very small LONG column. Instead. VARCHAR. Types. The data is not streamed. byte [] bytes = rset. then the driver will not automatically stream the data.VARBINARY).next(). or RAW Columns If you use the defineColumnType Oracle extension to redefine a CHAR. because it always uses the minimum number of round-trips. return the data in one call. then the JDBC driver will return a Java InputStream.

CLOB. or NCLOB columns.BFILE. The locator points to the actual location of the file. is used to store a locator to a file outside the database. Streaming BLOBs. determining the length of a BLOB. The JDBC drivers can support the following types through the use of streams: ■ Binary large object (BLOB) For unstructured binary data ■ Character large object (CLOB) For character data ■ National Character large object (NCLOB) For national character data ■ Binary file (BFILE) For external files LOBs and BFILEs behave differently from the other types of streaming data described in this chapter. or NCLOB. or NCLOB into an input stream. CLOB. and closing a BFILE. Instead.Streaming LOBs and External Files method. This class provides specific functionality.sql. Instead of storing the actual data in the table. To manipulate BLOB.sql.NCLOB. CLOBs. See Also: "Reading and Writing BLOB. including reading and writing the data as a stream. CLOB. By contrast. Even when streaming. a locator is stored in the database table. See Also: "Reading BFILE Data" on page 14-16 12-6 Oracle Database JDBC Developer's Guide and Reference . and NCLOBs When a query fetches one or more BLOB.sql. The getXXXStream entry points return a stream that reads data from this buffer. or NCLOB. The actual data can be manipulated using this locator. writing from an output stream into a BFILE. use methods in the Oracle extension classes oracle. or BFILE.sql. only the necessary bits of data move across the network.BLOB. or NCLOB data from JDBC. When a query fetches one or more BFILE columns. which points to the location of the actual data. use methods in the Oracle extension class oracle. The file can be stored somewhere on the file system of the data server. This data can be accessed as a stream. CLOB. or NCLOB. a locator is stored. CLOB. all the data always moves across the network. and closing a BLOB. when streaming a LONG or LONG RAW. such as reading from the BLOB. CLOB and NCLOB Data" on page 14-5 and "Data Interface for LOBs" on page 14-10 Streaming BFILEs An external file. CLOB. External files are managed similarly. the JDBC driver transfers the file to the client as required. writing from an output stream into a BLOB. The data can be accessed as a stream To manipulate BFILE data from JDBC.CLOB and oracle. the JDBC driver transfers the data to the client. oracle. such as reading from the BFILE into an input stream. Streaming LOBs and External Files The term large object (LOB) refers to a data item that is too large to be stored directly in a database table. determining the length of a BFILE. These classes provide specific functionality.

the stream data in the LONG column is discarded and the data from only the DATE and NUMBER column is recovered: Java Streams in JDBC 12-7 . while ((chunk = is. LONGCOL. it is a good programming practice to retrieve the columns in the same order as in the SELECT statement. // Close the file file.executeQuery ("select DATECOL. // Open a file to store the gif data FileOutputStream file = new FileOutputStream ("ascii. Tip: "Streaming LOBs and External Files" on page 12-6 Bypassing Streaming Data Columns There may be situations where you want to avoid reading a column that contains streaming data. Any attempt to read a column beyond a streaming column closes the streaming column. then the contents of the columns following the stream column are not available until the stream has been read. and the stream column is no longer available once any following column is read. while rset. then call the close method of the stream object. This method discards the stream data and enables the driver to continue reading data from all the columns that contain non-streaming data and follow the column containing streaming data.close(). } The incoming data for each row has the following shape: <a date><the characters of the long column><a number> As you process each row of the result set. If you do not want to read such data.Data Streaming and Multiple Columns Data Streaming and Multiple Columns If a query fetches multiple columns and one of the columns contains a data stream. //get the number column data int n = rset.getAsciiStream(2). // get the streaming data InputStream is = rset.dat"). In the following example. reading from the ascii stream and // write to the file int chunk.Date date = rset.read ()) != -1) file. // Loop. Even though you are intentionally discarding the stream.getInt(3). NUMBERCOL from TABLE"). See Also: "Streaming Data Precautions" on page 12-8 Streaming Example with Multiple Columns Consider the following code: ResultSet rset = stmt. you must complete any processing of the stream column before reading the number column.sql.getDate(1).write(chunk).next() { //get the date data java.

next() { //get the date java. the contents will be discarded when you fetch the next column. LONGCOL.close(). To recover the data from a column containing a data stream. while rset. then the database sends the entire data stream before proceeding to the next column.getDate(1). If your query fetches multiple columns. Notes and Precautions on Streams This section discusses several cautionary issues regarding the use of streams: ■ ■ ■ Streaming Data Precautions Using Streams to Avoid Limits on setBytes and setString Streaming and Row Prefetching Streaming Data Precautions This section describes some of the precautions you must take to ensure that you do not accidentally discard or lose your stream data. Two common precautions are: ■ Use the stream data after you access it.Date date = rset. // get the number column data int n = rset. it is not enough to fetch the column. Otherwise. You must immediately process the contents of the column. // access the stream data and discard it with close() InputStream is = rset. other than reading the current stream.Closing a Stream ResultSet rset = stmt. } Closing a Stream You can discard the data from a stream at any time by calling the close method. The drivers automatically discard stream data if you perform any JDBC operation that communicates with the database. 12-8 Oracle Database JDBC Developer's Guide and Reference . is. NUMBERCOL from TABLE"). See Also: "Bypassing Streaming Data Columns" on page 12-7 and "Streaming Data Precautions" on page 12-8 Note: Closing a stream has little performance effect on a LONG or LONG RAW column.getAsciiStream(2). ■ Call the stream column in the same order as in the SELECT statement. the database sends each row as a set of bytes representing the columns in the SELECT order. All of the data still move across the network and the driver can read the bits from the network.sql.getInt(3). It is a good programming practice to close the connection when you no longer need it. If one of the columns contains stream data.executeQuery ("select DATECOL.

eliminated. depending on the size of the data. then row fetch size is set back to one.getInt(3). whether the statement is SQL or PL/SQL.next() { InputStream is = rset. then you can lose the stream data. while rset.next() { int n = rset. Row fetch size is an Oracle performance enhancement that allows multiple rows of data to be retrieved with each trip to the database. // Raises an error: stream closed. There are some limitation with earlier versions of Oracle Database and in the server-side internal driver.Notes and Precautions on Streams If you do not use the order as in the SELECT statement to access data. // This discards the streaming data InputStream is = rset. then the JDBC driver first reads then discards the streaming data automatically.getAsciiStream(2). NUMBERCOL from TABLE"). if you try to access the data for the NUMBER column before reading the data from the stream data column. For example. // Get the stream int n = rset.executeQuery ("select DATECOL. then the stream data will be lost.getAsciiStream(2). then the stream still closes automatically: ResultSet rset = stmt.read(). If you try to access the LONG column later in the program. // c is -1: no more characters to read-stream closed Using Streams to Avoid Limits on setBytes and setString Starting from Oracle Database 10g.executeQuery ("select DATECOL. then the data will not be available and the driver will return a "Stream Closed" error. Any Java byte array can be passed to setBytes.getInt(3). LONGCOL. That is. This can be very inefficient if the LONG column contains a large amount of data. the size limitation on data that may be used with setBytes and setString have been reduced and. } If you get the stream but do not use it before you get the NUMBER column. and the driver used. The later point is illustrated in the following example: ResultSet rset = stmt. in certain cases. and any Java String can be passed to setString. while rset. See Also: "Data Interface for LOBs" on page 14-10 and release notes for details Streaming and Row Prefetching If the JDBC driver encounters a column containing a data stream. NUMBERCOL from TABLE"). // Discards streaming data and closes the stream } int c = is. The JDBC driver automatically switches to using setBinaryStream or setCharacterStream or to using setBytesForBlob or setStringForClob. LONGCOL. if you bypass the stream data column and access data in a column that follows it. Java Streams in JDBC 12-9 .

Notes and Precautions on Streams 12-10 Oracle Database JDBC Developer's Guide and Reference .

and employeeNumber of NUMBER type. custom object classes. Creating the Java classes for the Oracle objects Working with Oracle Object Types 13-1 . Note: In this book. Oracle provides tight integration between its Oracle object features and its JDBC functionality. or you can customize the mapping by creating custom Java type definition classes. which are Java classes that map to Oracle collections. This is as opposed to custom references classes. The following topics are covered: ■ ■ ■ ■ ■ ■ Mapping Oracle Objects Using the Default STRUCT Class for Oracle Objects Creating and Using Custom Object Classes for Oracle Objects Object-Type Inheritance Using JPublisher to Create Custom Object Classes Describing an Object Type See Also: Oracle Database Object-Relational Developer's Guide Mapping Oracle Objects Oracle object types provide support for composite data structures in the database. generic JDBC type to map to Oracle objects. weakly typed oracle. and custom collection classes. phoneNumber of CHAR type. Custom object classes can implement either a standard JDBC interface or an Oracle extension interface to read and write data. For example.sql.STRUCT class. as well as how to map to custom Java classes that implement either the JDBC standard SQLData interface or the Oracle ORAData interface.13 Working with Oracle Object Types This chapter describes the Java Database Connectivity (JDBC) support for user-defined object types. which are Java classes that map to object references. It discusses functionality of the generic. Java classes that you create to map to Oracle objects will be referred to as custom Java classes or. more specifically. You can use a standard. you can define a Person type that has the attributes name of CHAR type. JDBC materializes Oracle objects as instances of particular Java classes. Two main steps in using JDBC to access Oracle objects are: 1.

You can use the Oracle JPublisher utility to generate custom Java classes. You have the following options: ■ ■ Let JDBC materialize the object as a STRUCT object.0. Note: When you use the SQLData interface. using entries in the specified type map to determine the Java classes to use in materializing any attribute that is 13-2 Oracle Database JDBC Developer's Guide and Reference . and lists methods of the STRUCT class to give an overview of its functionality.sql.sql.STRUCT class. This imposes a set of constraints on the Java classes. then use a java. then Oracle JDBC will materialize the object as an instance of the oracle. Explicitly specify the mappings between Oracle objects and Java classes. instead of custom Java objects. because they maintain the data in SQL format.sql. For example. unless weakly typed java. as opposed to being an end-user application. in situations where you do not know the actual SQL type.ORAData interface.sql. This section covers the following topics: ■ ■ ■ ■ ■ STRUCT Class Functionality Retrieving STRUCT Objects and Attributes Creating STRUCT Objects and Descriptors Binding STRUCT Objects into Statements STRUCT Automatic Attribute Buffering STRUCT Class Functionality This section discusses standard versus Oracle-specific features of the oracle.SQLData interface or the Oracle extension oracle. introduces STRUCT descriptors. You can select data from the database into STRUCT objects and create STRUCT objects for inserting data into the database. Using STRUCT objects is more efficient and more precise in situations where you do not need the information in an application specific form.sql. STRUCT objects completely preserve data. The driver then must be able to populate instances of the custom object classes that you specify. To satisfy these constraints. This includes customizing your Java classes for object data.Struct instance and use the following standard methods: ■ getAttributes(map) This method retrieves the values of the attributes. you must use a Java type map to specify your SQL-Java mapping.sql.sql. Standard java.Struct Methods If your code must comply with standard JDBC 2. You would typically want to use STRUCT objects.Struct objects will suffice. you can define your classes to implement either the JDBC standard java.Using the Default STRUCT Class for Oracle Objects 2. Populating these classes.STRUCT class. your Java application might be a tool to manipulate arbitrary object data within the database. Using the Default STRUCT Class for Oracle Objects If you choose not to supply a custom Java class for your SQL-Java mapping for an Oracle object.

and then uses toClass Retrieving STRUCT Objects and Attributes This section discusses how to retrieve and manipulate Oracle objects and their attributes. Retrieving an Oracle Object as an oracle. then use an oracle.Struct interface and provides extended functionality beyond the JDBC 2. that is.Using the Default STRUCT Class for Oracle Objects a structured object type. The Java types for other attribute values would be the same as for a getObject call on data of the underlying SQL type.sql.STRUCT Class Methods If you want to take advantage of the extended functionality offered by Oracle-defined methods. STRUCT objects that are attributes of STRUCT objects. getObject is used to get a type_struct object from the Working with Oracle Object Types 13-3 . The STRUCT class includes the following methods in addition to standard Struct functionality: ■ getOracleAttributes Retrieves the values of the values array as oracle.sql. Oracle oracle.STRUCT Object You can retrieve an Oracle object directly into an oracle. or by using default mapping. uses toClass ■ toJdbc(map) Consults the specified type map to determine what class to map to.* objects ■ getDescriptor Returns the StructDescriptor object for the SQL type that corresponds to this STRUCT object ■ getJavaSQLConnection Returns the current connection instance ■ toJdbc Consults the default type map of the connection to determine what class to map to and.STRUCT class implements the java. except it uses the default type map for the connection.sql. ■ getSQLTypeName This method returns a Java String that represents the fully qualified name of the Oracle object type that this Struct represents. using either Oracle-specific features or JDBC 2.sql.0 standard. The oracle. it follows the same rules of conversion by using the type map.STRUCT instance. in the same way that it typically handles objects. In the following example.sql. ■ getAttributes This method is the same as the preceding getAttributes(map) method. When the JDBC driver retrieves an attribute that is an object. then.sql. Note: The JDBC driver seamlessly handles embedded objects.sql.STRUCT instance. if it is available.0 standard features.

to retrieve an Oracle object from the database as an instance of java. Another way to return the object as a STRUCT object is to cast the result set to OracleResultSet and use the Oracle extension getSTRUCT method: oracle. then use the getOracleAttributes method of the oracle.Object.Datum[] attrs = ((oracle. you can use standard JDBC functionality.sql. such as getObject.Datum[] attrs = oracleSTRUCT. you must cast the output of the method to Struct. Retrieving an Oracle Object as a java.'02-may-02'))".sql. cmd = "CREATE TYPE type_struct AS object (field1 NUMBER. cmd = "INSERT INTO struct_table VALUES (type_struct(10.Struct jdbcStruct = (java.STRUCT oracleSTRUCT=((OracleResultSet)rs).lang. Because getObject returns a java. use the standard getAttributes method: Object[] attrs = jdbcStruct.Struct Object Alternatively.STRUCT)jdbcStruct).executeQuery("SELECT * FROM struct_table").Using the Default STRUCT Class for Oracle Objects col1 column of the table struct_table. stmt.execute(cmd). stmt. java.sql.STRUCT)rs.sql. For example: ResultSet rs= stmt.sql types. as follows: oracle.STRUCT oracleSTRUCT=(oracle.sql. cmd = "CREATE TABLE struct_table (col1 type_struct)".sql.'01-apr-01'))". 13-4 Oracle Database JDBC Developer's Guide and Reference .STRUCT class. ResultSet rs= stmt.execute(cmd). oracle.sql. cmd = "INSERT INTO struct_table VALUES (type_struct(20.Struct.sql.getObject(1). Retrieving Attributes as Standard Java Types If you want to retrieve Oracle object attributes as standard Java types from a STRUCT or Struct instance.field2 DATE)". Because getObject returns an Object type.getAttributes().sql.STRUCT.getOracleAttributes(). Retrieving Attributes as oracle.getOracleAttributes().sql.Struct)rs. stmt. This example assumes that the Statement object stmt has already been created.execute(cmd). in the preceding example.execute(cmd). or: oracle. String cmd.sql.sql.getSTRUCT(1). stmt. the return is cast to oracle.executeQuery("SELECT * FROM struct_table").getObject(1).sql Types If you want to retrieve Oracle object attributes from a STRUCT or Struct instance as oracle.

Using the Default STRUCT Class for Oracle Objects Note: Oracle JDBC drivers cache array and structure descriptors. such as EMPLOYEE. The driver caches StructDescriptor objects to avoid re-creating them if the type has already been encountered. you can construct the STRUCT object.sql. However. The following code illustrates the use of the constructor that takes an Object array: .lang. attributes). structDescriptor. if it does not already exist.Object or as a java. you must: 1. Use the StructDescriptor to construct the STRUCT object. The attributes can be passed as an array of java. Before you can construct a STRUCT object. This provides enormous performance benefits.createDescriptor (sql_type_name. and an array of Java objects containing the attributes you want the STRUCT to contain. Once you have your StructDescriptor object for the Oracle object type.. connection). If a StructDescriptor object does not exist. provide the Connection object. the cached descriptor for that structure type will become stale and your application will receive a SQLException exception. This method requires you to pass in the SQL type name of the Oracle object type and a connection object. Create a StructDescriptor object for the given Oracle object type. Object[] attributes) STRUCT(Connection conn. .StructDescriptor class and describes a type of Oracle object. The following code illustrates the use of the constructor that takes a Map object: Working with Oracle Object Types 13-5 .. 2.sql. To do this.createDescriptor method. java. Steps in Creating StructDescriptor and STRUCT Objects To create a STRUCT object. as follows: StructDescriptor structdesc = StructDescriptor. A StructDescriptor is an instance of the oracle.util. Object[] attributes = {"attribute1". The following constructors of STRUCT are available: STRUCT(Connection conn. Only one StructDescriptor is necessary for each Oracle object type. and connection is the connection object. Creating STRUCT Objects and Descriptors This section describes how to create STRUCT objects. java. the StructDescriptor object.util..Map object. java.StructDescriptor structDesc. STRUCT struct = new STRUCT(connection.. it means that if you change the underlying type definition of a structure type in the database. then you can create one by calling the static StructDescriptor. The sql_type_name parameter is a Java String containing the name of the Oracle object type.sql.Map map) The structDesc parameter is the StructDescriptor object created previously and conn is your Connection object.StructDescriptor structDesc. a StructDescriptor must first exist for the given Oracle object type. null}.

By default.sql. The getAutoBuffering method returns the current auto-buffering mode.prepareStatement("text_of_prepared_statement"). or cast the statement object to an Oracle statement type and use the Oracle extension setOracleObject method.). It is advisable to enable auto-buffering in a JDBC application when the STRUCT attributes will be accessed more than once by the getAttributes and getArray methods. STRUCT mySTRUCT = new STRUCT (.put("A1". you can either use the standard setObject method (specifying the type code). structDescriptor. Binding STRUCT Objects into Statements To bind an oracle. STRUCT Automatic Attribute Buffering Oracle JDBC driver furnishes public methods to enable and disable buffering of STRUCT attributes. Types. Creating and Using Custom Object Classes for Oracle Objects If you want to create custom object classes for your Oracle objects. This data is retained so that subsequent access of this information does not require going through the data format conversion process.. STRUCT struct = new STRUCT(connection. Note: Buffering the converted attributes may cause the JDBC application to consume a significant amount of memory.. auto-buffering is disabled.. STRUCT mySTRUCT = new STRUCT (.sql. mySTRUCT..setObject(1. map). presuming the ARRAY data is able to fit into the Java Virtual Machine (JVM) memory without overflow. mySTRUCT).STRUCT class: ■ ■ public void setAutoBuffering(boolean enable) public boolean getAutoBuffering() The setAutoBuffering(boolean) method enables or disables auto-buffering. See Also: "ARRAY Automatic Element Buffering" on page 16-4 The following methods are included with the oracle.STRUCT object to a prepared statement or callable statement. For example: PreparedStatement ps= conn..setOracleObject(1.Creating and Using Custom Object Classes for Oracle Objects .STRUCT object keeps a local copy of all the converted attributes.. 13-6 Oracle Database JDBC Developer's Guide and Reference . HashMap map = new HashMap(1). ps.STRUCT)."attribute1").sql.. the oracle. or: PreparedStatement ps= conn. . ((OraclePreparedStatement)ps). When you enable auto-buffering.. map.prepareStatement("text_of_prepared_statement").). then you must define entries in the type map that specify the custom object classes that the drivers will instantiate for the corresponding Oracle objects.

You can create a ORAData object from any data type found in Oracle Database. The driver must be able to read from a custom object class and write to it. in the database that consists of two attributes: Name. if you are using the SQLData interface. for example. This could be useful. which is of the CHAR type and EmpNum. In addition. The SQLData interface is for mapping SQL objects only. To create and populate the custom classes and provide these read/write capabilities. and is able to generate classes that implement either one. enabling you to map SQL objects as well as any other SQL type for which you want to customize processing. You use the type map to specify that the EMPLOYEE object should map to a custom object class that you call JEmployee. However. assume you have an Oracle object type. but the most convenient way to create them is to use the Oracle JPublisher utility to create them for you. The ORAData interface can also be used to implement the custom reference class corresponding to the custom object class. you need to consider the advantages of ORAData and SQLData.Ref or oracle.sql. JPublisher supports the standard SQLData interface as well as the Oracle-specific ORAData interface. EMPLOYEE.Creating and Using Custom Object Classes for Oracle Objects You must also provide a way to create and populate instances of the custom object class from the Oracle object and its attribute data. The ORAData interface is more flexible. for serializing RAW data in Java. The SQLData interface is for mapping SQL objects only. You can create custom object classes yourself.sql. Working with Oracle Object Types 13-7 . although this is not necessary. You can implement either the SQLData or ORAData interface in the JEmployee class. the custom object class can provide getXXX and setXXX methods corresponding to the attributes of the Oracle object. such as java. then you can use only weak reference types in Java.REF. you can choose between the following interfaces: ■ ■ The JDBC standard SQLData interface The ORAData and ORADataFactory interfaces provided by Oracle The custom object class you create must implement one of these interfaces. As an example. See Also: "Using JPublisher to Create Custom Object Classes" on page 13-30 and "Object-Type Inheritance" on page 13-19 This section covers the following topics: ■ ■ ■ ■ ■ ■ ■ ■ ■ Relative Advantages of ORAData versus SQLData Understanding Type Maps for SQLData Implementations Creating Type Map and Defining Mappings for a SQLData Implementation Understanding the SQLData Interface Reading and Writing Data with a SQLData Implementation Understanding the ORAData Interface Reading and Writing Data with a ORAData Implementation Additional Uses for ORAData The Deprecated CustomDatum Interface Relative Advantages of ORAData versus SQLData In deciding which of the two interface implementations to use. which is of the NUMBER type.

Creating and Using Custom Object Classes for Oracle Objects Advantages of ORAData The advantages of ORAData are: ■ ■ ■ It does not require an entry in the type map for the Oracle object. The type map relates a Java class to the SQL type name of an Oracle object. When you read data from an Oracle object. by contrast. When using an ORAData implementation.util. You can obtain the corresponding Datum object from the ORAData object. This one-to-one mapping is stored in a hash table as a keyword-value pair. You can construct an ORAData from an oracle.getObject(int columnIndex).STRUCT.getObject(int columnIndex. the JDBC driver gets the SQL type name from the Java class by calling the getSQLTypeName method of the SQLData interface. the JDBC applications programmer is responsible for providing a type map. This is more efficient because it avoids unnecessary conversions to native Java types. See Also: "Creating and Using Custom Object Classes for Oracle Objects" on page 13-6 When using a SQLData implementation. It has awareness of Oracle extensions. ORAData works directly with Datum types. The actual conversion between SQL and Java is performed by the driver. which must be an instance of a class that implements the standard java. use the Oracle getORAData method instead of the standard getObject method. You can use either of the following: rs.STRUCT class by default. then you must create type map entries that specify the custom object class to use in mapping the Oracle object type to Java. the JDBC driver considers the type map to determine which Java class to use to materialize the data from the Oracle object type. then the object will map to the oracle. It provides better performance. ORAData implementations. The getObject method of the ResultSet interface has a signature that lets you specify a type map. Map map). using the toDatum method. if you do not include a type map entry. The attributes of the Java class that corresponds to an Oracle object can use either Java native types or Oracle native types to store attributes.Map interface. ■ ■ Advantages of SQLData SQLData is a JDBC standard that makes your code portable. You can either use the default type map of the connection object or a type map that you specify when you retrieve the data from the result set. have their own mapping functionality so that a type map entry is not required. Creating Type Map and Defining Mappings for a SQLData Implementation When using a SQLData implementation. which is the internal format used by the driver to hold Oracle objects. Understanding Type Maps for SQLData Implementations If you use the SQLData interface in a custom object class.sql. 13-8 Oracle Database JDBC Developer's Guide and Reference . rs. When you write data to an Oracle object.sql.

then the first call to getTypeMap returns an empty map.forName(className)). This section covers the following topics: ■ ■ ■ Adding Entries to an Existing Type Map Creating a New Type Map Materializing Object Types not Specified in the Type Map Adding Entries to an Existing Type Map When a connection instance is first established. where each key is a fully qualified SQL type name and the corresponding value is an instance of a specified Java class. but the standard java.put(sqlTypeName. Working with Oracle Object Types 13-9 . Class.getTypeMap(). then map it to a Person Java class defined as Person with this statement: myMap. The classObject is the Java class object to which you want to map the SQL type.forName method. as follows: myMap. if you have a PERSON SQL data type defined in the CORPORATE database schema.jdbc.put("CORPORATE.PERSON". Get the class object with the Class. presuming an OracleConnection instance oraconn: java.util. Hashtable and other classes used for type maps implement a put method that takes keyword-value pairs as input.util.put(sqlTypeName. The put method takes two arguments: a SQL type name string and an instance of a specified Java class that you want to map to. Note: If the type map in the OracleConnection instance has not been initialized. Use the getTypeMap method of your OracleConnection object to return the type map object of the connection. classObject). The map has an entry that maps the PERSON SQL data type in the CORPORATE database to the Person Java class. Perform the following general steps to add entries to an existing type map: 1.OracleConnection interface include a getTypeMap method. A type map is associated with a connection instance. You must populate it. For example. The standard java. myMap. Use the put method of the type map to add map entries.forName("Person")).util. The sqlTypeName is a string that represents the fully qualified name of the SQL type in the database.sql. Both return a Map object. Class.Map myMap = oraconn.Map object. For example.Hashtable class meets the requirement. 2. The getTypeMap method returns a java.Connection interface and the Oracle-specific oracle.Creating and Using Custom Object Classes for Oracle Objects You have the option of creating your own class to accomplish this. the default type map is empty.

This example uses an instance of java.sql. as specified by the SQLData interface. you must supply a type map that specifies the Oracle object types in the database and the names of the corresponding custom object classes that you will create for them. For example: oraconn. then the JDBC driver will materialize an Oracle object as an instance of the oracle.Hashtable.STRUCT class. Hashtable newMap = new Hashtable(). then the driver will materialize the embedded objects as instances of oracle. If you create a custom object class that implements SQLData. Note that if you use this interface.Dictionary and implements java.util.sql package. Create a new type map object.EMPLOYEE". Standard JDBC provides a SQLData interface and companion SQLInput and SQLOutput interfaces in the java. The SQLData interface defines methods that translate between SQL and Java for Oracle database objects. When you finish adding entries to the map. Use the put method of the type map object to add entries to the map. Understanding the SQLData Interface One of the choices in making an Oracle object and its attribute data available to Java applications is to create a custom object class that implements the SQLData interface. class.forName("Employee")). then a call to the getAttributes method will return embedded objects as instances of the specified Java classes from the type map.Map.util.util.setTypeMap(newMap). as follows: newMap. if you have an EMPLOYEE SQL type defined in the CORPORATE database. If the Oracle object type contains embedded objects and they are not present in the type map. such as for a result set getObject call that does not specify the map as input. Note: The default type map of a connection instance is used when mapping is required but no map name is specified. use the setTypeMap method of the OracleConnection object to overwrite the existing type map of the connection. then you must provide a readSQL method and a writeSQL method. For example. Creating a New Type Map Perform the following general steps to create a new type map. 1. 3. because that is how Oracle Database stores SQL names. 2.java. If the embedded objects are present in the type map.sql.STRUCT as well.Creating and Using Custom Object Classes for Oracle Objects Note: SQL type names in the type map must be all uppercase. In this example.put("CORPORATE. which extends java. then you can map it to an Employee class object defined by Employee. Materializing Object Types not Specified in the Type Map If you do not provide a type map with an appropriate entry when using a getObject call. 13-10 Oracle Database JDBC Developer's Guide and Reference . setTypeMap overwrites the original map of the oraconn connection object with newMap.

Typically. such as EMPLOYEE. The SQLOutput implementation is an output stream class. readInt. readLong. the driver would use this method as part of an OracleResultSet object getObject call. Each readXXX method converts SQL data to Java data and returns it as the result with the corresponding Java type.Creating and Using Custom Object Classes for Oracle Objects The JDBC driver calls your readSQL method to read a stream of data values from the database and populate an instance of your custom object class. You must implement readSQL as follows: public void readSQL(SQLInput stream. String sql_type_name) throws SQLException ■ The readSQL method takes as input a SQLInput stream and a string that indicates the SQL type name of the data. writeString would take as input a String attribute from your Java class. the JDBC driver calls your writeSQL method to write a sequence of data values from an instance of your custom object class to a stream that can be written to the database. ■ The readSQL method takes the data that the readXXX methods read and convert and assigns them to the appropriate fields or elements of a custom object class instance. It is not necessary to implement the SQLOutput or SQLInput objects. Similarly. readInt returns an int. SQLInput includes a readXXX method for every possible Java type that attributes of an Oracle object may be converted to. the JDBC driver creates a SQLInput stream object and populates it with data from the database. taking as input a parameter of the relevant Java type. Implementing readSQL and writeSQL Methods When you create a custom object class that implements SQLData. that is. an instance of which is passed to the readSQL method. When your Java application calls getObject. an instance of which is passed in to the writeSQL method. Understanding the SQLInput and SQLOutput Interfaces The JDBC driver includes classes that implement the SQLInput and SQLOutput interfaces. readBlob. then you must have a readString call and a readInt call in your readSQL method. The SQLInput implementation is an input stream class. such as readObject. the name of the Oracle object type. The JDBC drivers will do this for you. and so on. When the driver calls readSQL. as described here. The driver can also determine the SQL type name of the data when it reads it from the database. For example. JDBC calls these methods according to the order in which the attributes appear in the SQL definition of the Oracle object type. you must implement the readSQL and writeSQL methods. Typically. You must implement writeSQL as follows: Working with Oracle Object Types 13-11 . For example. Each writeXXX method converts Java data to SQL data. the driver would use this method as part of an OraclePreparedStatement object setObject call. readFloat. it passes in these parameters. if you are reading EMPLOYEE objects that have an employee name as a CHAR variable and an employee number as a NUMBER variable. ■ For each Java data type that maps to an attribute of the Oracle object. SQLOutput includes a writeXXX method for each of these Java types. For example. readSQL must call the appropriate readXXX method of the SQLInput stream that is passed in.

These steps assume you have already defined the Oracle object type. Note that if the type map did not have an entry for the object.sql. ■ The writeSQL method then writes the data to the SQLOutput stream by calling the writeXXX methods so that it can be sent to the database once you execute the prepared statement. if you are writing to EMPLOYEE objects that have an employee name as a CHAR variable and an employee number as a NUMBER variable. created the corresponding custom object class. When the driver calls writeSQL.next()) Employee emp = (Employee)rs. These methods must be called according to the order in which attributes appear in the SQL definition of the Oracle object type. writeSQL must call the appropriate writeXXX method of the SQLOutput stream that is passed in.lang. updated the type map to define the mapping between the Oracle object and the Java class. 1. ResultSet rs = stmt. The getObject method calls readSQL. then you must have a writeString call and a writeInt call in your writeSQL method. then getObject would return an oracle. 13-12 Oracle Database JDBC Developer's Guide and Reference . 2. if (rs.executeQuery("SELECT emp_col FROM personnel"). The getObject method returns the user-defined SQLData object because the type map contains an entry for Employee. EMP_COL. The PERSONNEL table contains one column. which. and defined a statement object stmt.getObject(1). calls readXXX from the SQLData interface.next()) STRUCT empstruct = (STRUCT)rs. Reading and Writing Data with a SQLData Implementation This section describes how to read data from an Oracle object or write data to an Oracle object if your corresponding Java class implements SQLData. if (rs.getObject(1).Creating and Using Custom Object Classes for Oracle Objects public void writeSQL(SQLOutput stream) throws SQLException ■ The writeSQL method takes as input a SQLOutput stream. This SQL type is defined in the type map to map to the Java class Employee. ■ For each Java data type that maps to an attribute of the Oracle object. For example. because the getObject method signature returns the generic java.STRUCT object. the JDBC driver creates a SQLOutput stream object. Reading SQLData Objects from a Result Set The following text summarizes the steps to read data from an Oracle object into your Java application when you choose the SQLData implementation for your custom object class. Cast the output to type STRUCT. of SQL type EMP_OBJECT. When your Java application calls setObject. Use the getObject method of your result set to populate an instance of your custom object class with data from one row of the result set. in turn. it passes in this stream parameter. Query the database to read the Oracle object into a JDBC result set.Object type.

Working with Oracle Object Types 13-13 .setInt(2. Register the SQLData object as the OUT parameter. Declare the empnumber as the input parameter to GETEMPLOYEE. ocs.Creating and Using Custom Object Classes for Oracle Objects Note: If you want to avoid using the defined type map. ocs.lang.registerOutParameter(1. then provide a getEmpName method that returns a Java String and a getEmpNum method that returns an int value. int empnumber = emp. The function returns the corresponding Employee object. If there is no type map entry. emp is a valid Employee object. For example.prepareCall("{ call addEmployee(?) }"). then getObject would return an oracle.Object class. 3. ocs.STRUCT.STRUCT. 2. even if there is a mapping entry in the type map. because the getObject method returns an instance of the generic java. The following code assumes that there is a type map entry to map the Oracle object to the Java type Employee: Employee emp = (Employee)ocs.execute(). Passing SQLData Objects to a Callable Statement as an IN Parameter Suppose you have a PL/SQL function addEmployee(?) that takes an Employee object as an IN parameter and adds it to the PERSONNEL table. To retrieve this object you do the following: 1. If you have get methods in your custom object class. Prepare an OracleCallableStatement to call the GETEMPLOYEE function. This method always returns a STRUCT object. Cast the output to the STRUCT type. 1.prepareCall("{ ? = call GETEMPLOYEE(?) }"). This is done as follows: STRUCT emp = (STRUCT)ocs. The program passes an employee number to the function. Then call them in your Java application. Then. In this example. run the statement. as follows: OracleCallableStatement ocs = (OracleCallableStatement)conn.getEmpName(). Prepare an OracleCallableStatement to call the addEmployee(?) function. then use them to read data from your object attributes. that calls a PL/SQL function GETEMPLOYEE.getObject(1). then use the getSTRUCT method.getEmpNum(). Use the getObject method to retrieve the employee object. OracleCallableStatement ocs = (OracleCallableStatement) conn.STRUCT object. as follows: String empname = emp.sql. OracleTypes. Retrieving SQLData Objects from a Callable Statement OUT Parameter Consider you have an OracleCallableStatement instance. This can be done as follows: ocs. 3. if EMPLOYEE has the attributes EmpName of type CHAR and EmpNum of type NUMBER.getObject(1). empnumber). "EMP_OBJECT"). with the type code OracleTypes.

1. Note: The JPublisher utility supports the generation of classes that implement the ORAData and ORADataFactory interfaces. This assumes conn is your connection object. ocs.setEmpNum(empnumber). 13-14 Oracle Database JDBC Developer's Guide and Reference .sql. This statement uses the emp object and the empname and empnumber variables assigned in the preceding example. using the data provided in your Java data type object. then use them to write data from Java variables in your application to attributes of your Java data type object.setEmpName(empname).setObject(1.sql. 3. Use the setObject method of the prepared statement to bind your Java data type object to the prepared statement. PreparedStatement pstmt = conn.Datum types directly. created the corresponding Java class. and updated the type map to define the mapping between the Oracle object and the Java class. Run the statement. call the statement.prepareStatement ("INSERT INTO PERSONNEL VALUES (?)"). If you have set methods in your custom object class. Use setObject to pass the emp object as an IN parameter to the callable statement. Then.ORAData and oracle. This description assumes you have already defined the Oracle object type. Prepare a statement that updates an Oracle object in a row of a database table.Creating and Using Custom Object Classes for Oracle Objects 2. emp). pstmt. emp. emp. Writing Data to an Oracle Object Using a SQLData Implementation The following text describes the steps in writing data to an Oracle object from your Java application when you choose the SQLData implementation for your custom object class. ocs. Understanding the ORAData Interface One of the choices in making an Oracle object and its attribute data available to Java applications is to create a custom object class that implements the oracle. 4. pstmt.ORADataFactory interfaces. emp). as appropriate.setObject(1. ORAData uses oracle.executeUpdate(). 2. The ORAData and ORADataFactory interfaces are supplied by Oracle and are not a part of the JDBC standard. which updates the database.sql. Understanding ORAData Features The ORAData interface has the following advantages: ■ It recognizes Oracle extensions to the JDBC.execute().

} public interface ORADataFactory { ORAData create (Datum d.Datum object and an integer indicating the corresponding SQL type code as specified in the OracleTypes class. int sql_Type_Code) throws SQLException. you can implement a getORAFactory method in your custom object class to produce the ORADataFactory instance to input to getORAData. Retrieving and Inserting Object Data The JDBC drivers provide the following methods to retrieve and insert object data as instances of ORAData. This method takes as input the column index of the data in your result set and a ORADataFactory instance. ORADataFactory specifies a create method equivalent to a constructor for your custom object class. d represents an object of type oracle. The JDBC driver uses the create method to return an instance of the custom object class to your Java application or applet. Working with Oracle Object Types 13-15 . ■ Use the standard getObject(index. ORAData custom_obj). ■ The ORAData and ORADataFactory interfaces do the following: ■ The toDatum method of the ORAData class transforms the data into an oracle. } Where conn represents the Connection object. ■ ORAData and ORADataFactory have the following definitions: public interface ORAData { Datum toDatum (OracleConnection conn) throws SQLException.sql. ORAData works directly with Datum types. You can insert object data in one of the following ways: ■ Use the following setORAData method of the Oracle-specific OraclePreparedStatement class: ops. you must have an entry in the type map that identifies the factory class to be used for the given object type and its corresponding SQL type name.sql.sql.setORAData (int bind_index. the internal format the driver uses to hold Oracle objects.getORAData (int col_index.* representation. For example. ORADataFactory factory). It provides better performance. It creates and returns an ORAData instance. The type map is not required when using Java classes that implement ORAData. In this case.Datum and sql_Type_Code represents the SQL type code of the Datum object. It takes as input an oracle.Creating and Using Custom Object Classes for Oracle Objects ■ It does not require a type map to specify the names of the Java custom classes you want to create. map) method specified by the ResultSet interface to retrieve data as instances of ORAData. You can retrieve the object data in one of the following ways: ■ Use the following getORAData method of the Oracle-specific OracleResultSet class: ors.

Note: ■ ORAData and ORADataFactory are defined as separate interfaces so that different Java classes can implement them if you wish. ■ Use the standard setObject method specified by the PreparedStatement interface.next()) Employee emp = (Employee)ors.executeQuery ("SELECT Emp_col FROM PERSONNEL"). ors is an Oracle result set.sql. 13-16 Oracle Database JDBC Developer's Guide and Reference .Creating and Using Custom Object Classes for Oracle Objects This method takes as input the parameter index of the bind variable and the name of the object containing the variable. getORAData is a method in the OracleResultSet class used to retrieve a ORAData object. 1. in its different forms. and defined a statement object stmt. You can also use this method.getORAFactory method will return a ORADataFactory to the JDBC driver. The column name is Emp_col of type Employee_object. which you can cast to your specific custom object class. returning to your Java application an instance of the Employee class populated with data from the result set. These steps assume you have already defined the Oracle object type. if (ors. you might have something like the following in your Java application: ORAData datum = ors.getORAFactory()). The following sections describe the getORAData and setORAData methods.getORAData(1. In this example.getORAData(1.ORAData object. Reading Data from an Oracle Object Using a ORAData Implementation The following text summarizes the steps in reading data from an Oracle object into your Java application. created the corresponding custom object class or had JPublisher create it for you. to insert ORAData instances without requiring a type map. Employee. Employee.*. The static Employee. ■ Reading and Writing Data with a ORAData Implementation This section describes how to read data from an Oracle object or write data to an Oracle object if your corresponding Java class implements ORAData. 2.sql. Where PERSONNEL is a one-column table. The getORAData method returns an oracle.getORAFactory()). and the EMPLOYEE is in column 1 of the result set. To continue the example of an Oracle object EMPLOYEE. casting it to an Oracle result set. These steps apply whether you implement ORAData manually or use JPublisher to produce your custom object classes. The JDBC driver will call create() from this object. To use the ORAData interface. OracleResultSet ors = (OracleResultSet)stmt. Query the database to read the Oracle object into a result set. your custom object classes must import oracle. Use the getORAData method of your Oracle result set to populate an instance of your custom object class with data from one row of the result set.

if EMPLOYEE has EmpName of type CHAR and EmpNum of type NUMBER. provide a getEmpName method that returns a Java String and a getEmpNum method that returns an integer. if the SQL type name for your object is EMPLOYEE. then use them to read data from your object attributes into Java variables in your application. which will implement ORADataFactory. map). then the corresponding Java class is Employee.Creating and Using Custom Object Classes for Oracle Objects or: if (ors. Writing Data to an Oracle Object Using a ORAData Implementation The following text summarizes the steps in writing data to an Oracle object from your Java application.getObject (1). Note: The type map is not used when you are performing database INSERT and UPDATE operations. Class.put ("EMPLOYEE". which will implement ORAData. If you have get methods in your custom object class.forName ("EmployeeFactory")). However. This example assumes that Employee is the name of your custom object class and ors is the name of your OracleResultSet object.getObject (1. Then call them in your Java application as follows: String empname = emp. Employee. you must have an entry in the type map that identifies the factory class to be used for the given object type and its corresponding SQL type name. Note: Alternatively.getEmpName(). 3. then you can use this form of getObject: Employee emp = (Employee) rs. you can fetch data using a callable statement object. int empnumber = emp. Use this statement to declare the EmployeeFactory entry for your type map: map. For example.next()) ORAData datum = ors. Then use the form of getObject where you specify the map object: Employee emp = (Employee) rs. In case you do not want to use getORAData.getEmpNum(). These steps apply whether you implement ORAData manually or use JPublisher to produce your custom object classes. Working with Oracle Object Types 13-17 .getORAFactory()). These steps assume you have already defined the Oracle object type and created the corresponding custom object class. The corresponding Factory class is EmployeeFactory. The OracleCallableStatement class also has a getORAData method.getORAData(1. If the default type map of the connection already has an entry that identifies the factory class to be used for the given object type and its corresponding SQL type name. For example. the JDBC drivers let you use the getObject method of a standard JDBC ResultSet to retrieve ORAData data.

after performing the appropriate conversions between Java and SQL types. It lets you provide a mapping between Java object types and any SQL type supported by the oracle.EmpNum = 28959). Additional Uses for ORAData The ORAData interface offers far more flexibility than the SQLData interface. emp.* types and perhaps implement customized conversions or functionality as well. emp. then use them to write data from Java variables in your application to attributes of your Java data type object. such as character fields containing URL information. The SQLData interface is designed to let you customize the mapping of only Oracle object types to Java types of your choice. emp). 3.sql. and the reverse. Note: You can use your Java data type objects as either IN or OUT bind variables.STRUCT object that can be written to the database. using the data provided in your Java data type object.setORAData(1. For example: opstmt.sql.Creating and Using Custom Object Classes for Oracle Objects 1. The ORAData interface goes beyond supporting the customization of Oracle object types to Java types. It may be useful to provide custom Java classes to wrap oracle. such as mapping a DATE field to java. The following are some possible scenarios: ■ ■ ■ Performing encryption and decryption or validation of data Performing logging of values that have been read or are being written Parsing character columns.sql package.emp). Write an Oracle prepared statement that updates an Oracle object in a row of a database table.util.Date format ■ ■ 13-18 Oracle Database JDBC Developer's Guide and Reference . The setORAData method calls the toDatum method of the custom object class instance to retrieve an oracle. If you have set methods in your custom object class. 2. Implementing the SQLData interface lets the JDBC driver populate fields of a custom Java class instance from the original SQL object data. OraclePreparedStatement opstmt = conn. opstmt. In this step you could also use the setObject method to bind the Java data type. as appropriate.prepareStatement ("UPDATE PERSONNEL SET Employee = ? WHERE Employee.setEmpName(empname). This assumes conn is your Connection object. Use the setORAData method of the Oracle prepared statement to bind your Java data type object to the prepared statement.setEmpNum(empnumber). into smaller components Mapping character strings into numeric constants Making data into more desirable Java formats.setObject(1.

Substitutability is the ability of a slot declared to hold a value of type T in addition to any subtype of type T. Upon retrieval. Oracle JDBC driver returns a Java object that represents the STUDENT_T object.RAW and calls the create method of ORADataFactory to convert the oracle. oracle.sql. which happen to be the internal formats used by the JDBC drivers.* formats. Object-Type Inheritance Object-type inheritance allows a new object type to be created by extending another object type. Object-type inheritance introduces substitutability.RAW object.toDatum method to convert the Java object to an oracle.jdbc. The subtype can add attributes and methods and overload or override methods inherited from the supertype.driver classes. formerly used to access customized objects. This section covers the following topics: ■ ■ ■ ■ Creating Subtypes Implementing Customized Classes for Subtypes Retrieving Subtype Objects Creating Subtype Objects Working with Oracle Object Types 13-19 . The new object type is then a subtype of the object type from which it extends.ORAData and oracle. A database object is returned with its most specific type without losing information.sql.CustomDatum and oracle.ORADataFactory. Support for the ORAData interfaces is also highly efficient because the conversions are designed to work using oracle.RAW object. you can simply bind it to a column of type RAW to store it.sql. if the STUDENT_T object is stored in a PERSON_T slot. For example.sql.sql. The toDatum method in ORAData would have to implement a conversion from the Java object to an oracle. Oracle recommends you use the new interfaces. which is necessary for the SQLData interface.Object-Type Inheritance ■ Customizing data representation. by using Java serialization. is not required when using Java classes that implement ORAData. use ORAData to store instances of Java objects that do not correspond to a particular SQL object type in the database in columns of SQL type RAW. the type map. data in a table column is in feet but you want it represented in meters after it is selected Serializing and deserializing Java objects ■ For example.jdbc interfaces were introduced in Oracle9i Database as an alternative to the oracle. Moreover. for example. The create method in ORADataFactory would have to implement a conversion from an object of type oracle. the JDBC driver transparently retrieves the raw bytes of data in the form of an oracle.RAW object to the desired Java class.sql. When you insert the Java object into the database.RAW to the desired Java object.sql.sql. were deprecated.sql. The subtype automatically inherits all the attributes and methods defined in the supertype. Oracle JDBC drivers handle substitutability transparently. This object is then stored in a column of type RAW in the database.CustomDatumFactory interfaces. the oracle. The driver transparently calls the ORAData. This can be done. See Also: "Understanding the ORAData Interface" on page 13-14 The Deprecated CustomDatum Interface After the oracle. for example.sql.

s..sql. .execute ("CREATE TYPE PartTimeStudent_t UNDER Student_t (numHours NUMBER)")..) . a customized Java class represents a database object type. you want to create a type inheritance hierarchy for: PERSON_T | STUDENT_T | PARTTIMESTUDENT_T The JDBC code for this can be as follows: Statement s = conn. major VARCHAR2(100))"). When you create a customized Java class for a subtype.execute ("CREATE TYPE Person_T (SSN NUMBER.Statement interface.execute ("CREATE TYPE Student_T UNDER Person_t (deptid NUMBER. they can be used as both columns of a base table as well as attributes of a object type.. address VARCHAR2(255))")... ). MEMBER PROCEDURE foo(x NUMBER). <-... STATIC FUNCTION bar(. See Also: Oracle Database Object-Relational Developer's Guide Implementing Customized Classes for Subtypes In most cases. You can use either the ORAData or SQLData solution in creating classes to map to the hierarchy of object types. CREATE TYPE T AS OBJECT (. In the following code. The most common way to create a database subtype in JDBC is to run a SQL CREATE TYPE command using the execute method of the java. . If you have a hierarchy of object types.. CREATE TYPE ST UNDER T (. For example. MEMBER PROCEDURE foo(x DATE). the foo member procedure in type ST is overloaded and the member procedure print overwrites the copy it inherits from type T.. you may want a corresponding hierarchy of Java classes. s.createStatement().Object-Type Inheritance ■ ■ ■ Sending Subtype Objects Accessing Subtype Data Fields Inheritance Metadata Methods Creating Subtypes Create custom object classes if you want to have Java classes that explicitly correspond to the Oracle object types... OVERRIDING MEMBER PROCEDURE Print(). s.overload "foo" <-.. MEMBER PROCEDURE Print(). the Java class can either mirror the database object type hierarchy or not. NOT FINAL.. This section covers the following topics: 13-20 Oracle Database JDBC Developer's Guide and Reference .override "print" Once the subtypes have been created. name VARCHAR2(30)..

Object-Type Inheritance ■ ■ ■ Use of ORAData for Type Inheritance Hierarchy Use of SQLData for Type Inheritance Hierarchy JPublisher Utility Use of ORAData for Type Inheritance Hierarchy Customized mapping where Java classes implement the oracle. Object [] attributes = { ssn. (CHAR) attributes[2]). return new STRUCT(sd.sql. } } Working with Oracle Object Types 13-21 . CHAR name. c).PERSON_T". For example. The class implementing the ORADataFactory interface contains a factory method that produces objects. this.getOracleAttributes(). attributes).java using ORAData Code for the Person. the Java classes mapping to PERSON_T and STUDENT_T are as follows: Person. public CHAR name.address = address. public NUMBER ssn.java class which implements the ORAData and ORADataFactory interfaces: class Person implements ORAData. } public Person () {} public Person(NUMBER ssn. (CHAR) attributes[1]. ORAData mapping requires the JDBC application to implement the ORAData and ORADataFactory interfaces. The hierarchy of the class implementing the ORAData interface can mirror the database object type hierarchy. ORADataFactory { static final Person _personFactory = new Person().name = name.createDescriptor("SCOTT. Object [] attributes = ((STRUCT) d). } public ORAData create(Datum d. return new Person((NUMBER) attributes[0]. public CHAR address.ssn = ssn. address }. int sqlType) throws SQLException { if (d == null) return null.ORAData interface is the recommended mapping. this. name. } public Datum toDatum(OracleConnection c) throws SQLException { StructDescriptor sd = StructDescriptor. public static ORADataFactory getORADataFactory() { return _personFactory. Each object represents a database object. c. CHAR address) { this.

(CHAR) attributes[2]. CHAR major) { super (ssn. address). For example. return new Student((NUMBER) attributes[0]. In this case. attributes).major = major. which extends the Person.executeQuery ("select person from tab1"). public NUMBER deptid. CHAR address. public static ORADataFactory getORADataFactory() { return _studentFactory. you could have declared the Student class without a superclass. } public Student () {} public Student (NUMBER ssn. } } Customized classes that implement the ORAData interface do not have to mirror the database object type hierarchy. public CHAR major. this. ORADataFactory Implementation The JDBC application uses the factory class in querying the database to return instances of Person or its subclasses.Object-Type Inheritance Student. Student would contain fields to hold the inherited attributes from PERSON_T as well as the attributes declared by STUDENT_T. Object [] attributes = ((STRUCT) d). address. deptid. (NUMBER) attributes[3].deptid = deptid. this. return new STRUCT(sd. c). NUMBER deptid.java class: class Student extends Person { static final Student _studentFactory = new Student (). while (rset. (CHAR) attributes[4]).java class. } public CustomDatum create(Datum d.createDescriptor("SCOTT. major }.getOracleAttributes().java Code for the Student.java extending Person. c. Object [] attributes = { ssn.next()) { 13-22 Oracle Database JDBC Developer's Guide and Reference . name. CHAR name. (CHAR) attributes[1]. int sqlType) throws SQLException { if (d == null) return null. name. } public Datum toDatum(OracleConnection c) throws SQLException { StructDescriptor sd = StructDescriptor. as in the following example: ResultSet rset = stmt.STUDENT_T".

else return null.getSQLTypeName (). 101. STUDENT_T. else if (s.sql. 'Peter'. as well as instances of any subtype. PersonFactory. class PersonFactory implements ORADataFactory { static final PersonFactory _factory = new PersonFactory ().java using SQLData Code for the Person. 'Scott'. 102.create(d. public static ORADataFactory getORADataFactory() { return _factory. else if (s.PERSON_T")) return Person. PERSON_T (1000.getORADataFactory()). } } The following example assumes a table tabl1. sqlType).getSQLTypeName ().equals ("SCOTT. PARTTIMESTUDENT_T (1002. the Java classes mapping to PERSON_T and STUDENT_T are as follows: Person. In the following example.getORADataFactory (). such as the following: CREATE TABLE tabl1 (idx NUMBER.getORADataFactory method returns a factory that can handle PERSON_T. public class Person implements SQLData { private String sql_type.getSQLTypeName (). student. if (s. '200 Oracle Parkway'. '300 Oracle Parkway'. Working with Oracle Object Types 13-23 . by returning person.create (d. .create(d. } A class implementing the ORADataFactory interface should be able to produce instances of the associated custom object type. the PersonFactory. '100 Oracle Parkway')). For example.getORAData (1. 'David'. INSERT INTO tabl1 VALUES (1.getORADataFactory (). The readSQL and writeSQL methods of a subclass typically call the corresponding superclass methods to read or write the superclass attributes before reading or writing the subclass attributes.SQLData interface can mirror the database object type hierarchy. or parttimestudent Java instances.PARTTIMESTUDENT_T")) return ParttimeStudent. int sqlType) throws SQLException { STRUCT s = (STRUCT) d. sqlType).equals ("SCOTT.STUDENT_T")) return Student. INSERT INTO tabl1 VALUES (2.. } public ORAData create(Datum d. and PARTTIMESTUDENT_T objects.. Use of SQLData for Type Inheritance Hierarchy The customized classes that implement the java. sqlType).*.java class. person PERSON_T). or at least all the types you expect to support. 'EE')). which implements the SQLData interface: import java. STUDENT_T (1001. 'CS')).getORADataFactory ().equals ("SCOTT.Object-Type Inheritance Object s = rset.sql. INSERT INTO tabl1 VALUES (3.

In this 13-24 Oracle Database JDBC Developer's Guide and Reference .java class.writeString (major).writeInt (ssn).readString().java class: import java.readString(). public class Student extends Person { private String sql_type. address = stream.readString().java extending Student.writeString (address).writeString (name). stream.readSQL (stream. public String address. ssn = stream. it is recommended that the customized classes. which extends the Person. typeName). mirror the database object type hierarchy. } } Although not required. you could have declared the Student class without a superclass. public String name. // write supertype // attributes stream. } public void writeSQL(SQLOutput stream) throws SQLException { stream. stream. } public String getSQLTypeName() throws SQLException { return sql_type. } public void writeSQL(SQLOutput stream) throws SQLException { super. stream. } } Student. which implement the SQLData interface. public Person () {} public String getSQLTypeName() throws SQLException { return sql_type.java Code for the Student. major = stream. } public void readSQL(SQLInput stream. } public void readSQL(SQLInput stream.readInt(). name = stream.*. String typeName) throws SQLException { super.writeInt (deptid). public String major.Object-Type Inheritance public int ssn. // read supertype attributes sql_type = typeName. String typeName) throws SQLException { sql_type = typeName. deptid = stream. For example.readInt().sql. public int deptid. public Student () { super().writeSQL (stream).

ssn = stream. deptid = stream.Object-Type Inheritance case.readInt(). public public public public public int ssn.sql. stream.java using SQLData Code for the Student. Student would contain fields to hold the inherited attributes from PERSON_T as well as the attributes declared by STUDENT_T.*. public Student () {} public String getSQLTypeName() throws SQLException { return sql_type.writeInt (ssn). } } JPublisher Utility Even though you can manually create customized classes that implement the SQLData. it is recommended that you use Oracle JPublisher to automatically generate these classes. public class Student implements SQLData { private String sql_type. String address. See Also: ■ ■ "Using JPublisher to Create Custom Object Classes" on page 13-30 Oracle Database JPublisher User's Guide Working with Oracle Object Types 13-25 . int deptid. ORAData. stream. Student.java class. String name. } public void readSQL(SQLInput stream.writeString (name).java class.readInt().writeString (major). can mirror the inheritance hierarchy. The customized classes generated by Oracle JPublisher that implement the SQLData. String major.readString(). major = stream. } public void writeSQL(SQLOutput stream) throws SQLException { stream.readString(). stream. String typeName) throws SQLException { sql_type = typeName. and ORADataFactory interfaces. stream. which does not extend the Person.readString().writeInt (deptid).writeString (address). name = stream. and ORADataFactory interfaces. address = stream. ORAData. but implements the SQLData interface directly: import java.

sql. The JDBC driver checks the type map for an entry match. Populate the connection type map with entries that specify what custom Java type corresponds to each Oracle object type. If the STRUCT class represents a subtype object in the database. if (s != null) System.PARTTIMESTUDENT_T } Using SQLData Mapping With SQLData mapping. Use the getObject method to access the SQL object values. then it contains the attributes of its supertype as well as those defined in the subtype. then the driver returns the database object as an instance of the class implementing the SQLData interface. do the following: 1. Implement the container classes that implement the SQLData interface for the desired object types. // print out the type name which // may be SCOTT. Oracle JDBC driver returns database objects in their most specific type.STUDENT_T or SCOTT.getSQLTypeName()). If one exists.Object-Type Inheritance Retrieving Subtype Objects In a typical JDBC application. 3.Map map = conn. This instance may represent an object of either the declared type or subtype of the declared type.getObject(1).println (s.PERSON_T. // Student. Using Default Mapping By default.util. To use SQLData mapping in retrieving database objects. SCOTT. while (rset. a subtype object is returned as one of the following: ■ ■ ■ A query result A PL/SQL OUT parameter A type attribute You can use either the default mapping or the SQLData mapping or the ORAData mapping to retrieve a subtype.STRUCT s = (oracle.sql. The following code shows the whole SQLData customized mapping process: // The JDBC application developer implements Person.person column can store PERSON_T. Connection conn = .STRUCT class..sql. 13-26 Oracle Database JDBC Developer's Guide and Reference .java for STUDENT_T // and ParttimeStudent.STRUCT) rset.getTypeMap ().out. STUDENT_T and PARTIMESTUDENT_T objects ResultSet rset = stmt..executeQuery ("select person from tab1"). The JDBC application can use the getSQLTypeName method of the STRUCT class to determine the SQL type of the STRUCT object. The following code shows this: // tab1.. the JDBC driver returns the database object as an instance of the class implementing the SQLData interface. a database object is returned as an instance of the oracle.java for PERSON_T.java for PARTTIMESTUDEN_T.next()) { oracle. 2. // make a JDBC connection // obtains the connection typemap java.

The following are the two ways to inform Oracle JDBC drivers: ■ The JDBC application uses the getORAData(int idx.forName ("ParttimeStudent")).put ("SCOTT.CallableStatement interfaces getAttribute method of the java.out.sql.forName ("Student")). PersonFactory. Class.ResultSet and java.REF interface ■ ■ ■ Using ORAData Mapping With ORAData mapping. ORADataFactory f) method to access database objects. The following code example demonstrates the first approach: // tab1.forName ("Person")). else if (s instanceof Student) System.next()) { // "s" is instance of Person.pritnln ("This is a PartimeStudent"). the JDBC driver returns the database object as an instance of the class implementing the ORAData interface.Struct interface getArray method of the java. The getObject method is used to access the Oracle object values.sql.person column can store both PERSON_T and STUDENT_T objects ResultSet rset = stmt.sql. Class.Object-Type Inheritance // populate the type map map.put ("SCOTT. if (s != null) { if (s instanceof Person) System. STUDENT_T and PARTTIMESTUDENT_T objects ResultSet rset = stmt. The second parameter of the getORAData method specifies an instance of the factory class that produces the customized class.executeQuery ("select person from tab1").out. } } The JDBC drivers check the connection type map for each call to the following: ■ getObject method of the java.out. else if (s instanceof ParttimeStudent) System. while (rset. The JDBC application populates the connection type map with entries that specify what custom Java type corresponds to each Oracle object type.person column can store PERSON_T. else System. if (s != null) Working with Oracle Object Types 13-27 .PERSON_T". // tab1.sql.println ("Unknown type"). The getORAData method is available in the OracleResultSet and OracleCallableStatement classes.Array interface getValue method of the oracle.println ("This is a Student").next()) { Object s = rset.PARTTIMESTUDENT_T".put ("SCOTT. map. ■ The second approach involves the use of the standard getObject method.out. Class.executeQuery ("select person from tab1").STUDENT_T".getORADataFactory()). while (rset. map. Oracle JDBC driver needs to be informed of what Java class is mapped to the Oracle object type.println ("This is a Person").sql. Student or ParttimeStudent Object s = rset.getObject(1).getORAData (1.

"500 Oracle Parkway". attrs). the JDBC application creates STRUCT objects to represent database subtype objects. All the data fields inherited from the supertype as well as all the fields defined in the subtype must have values. the JDBC application creates either SQLData.out. } } Creating Subtype Objects There are cases where JDBC applications create database subtype objects with JDBC drivers.out.. a Java object that represents a database object is sent to the databases as one of the following: ■ ■ ■ A data manipulation language (DML) bind variable A PL/SQL IN parameter An object type attribute value The Java object can be an instance of the STRUCT class or an instance of the class implementing either the SQLData or ORAData interface..out.println ("Unknown type"). These objects are sent either to the database as bind variables or are used to exchange information within the JDBC application.println ("This is a Person").PARTTIMESTUDENT".println ("This is a Student"). and data fields defined in PARTTIMESTUDENT_T. else if (s instanceof Student) System. // make a JDBC connection StructDescriptor desc = StructDescriptor. // data fields defined in // PERSON_T new Integer(102). The following code demonstrates this: Connection conn = .out.Object-Type Inheritance { if (s instanceof Person) System. With customized mapping. STRUCT s = new STRUCT (desc. 13-28 Oracle Database JDBC Developer's Guide and Reference . s is initialized with data fields inherited from PERSON_T and STUDENT_T. else if (s instanceof ParttimeStudent) System. Oracle JDBC driver will convert the Java object into the linearized format acceptable to the database SQL engine. "Scott". // data fields defined in // STUDENT_T new Integer(4) // data fields defined in // PARTTIMESTUDENT_T }. With default mapping. Sending Subtype Objects In a typical JDBC application. to represent database subtype objects. else System.or ORAData-based objects.pritnln ("This is a PartimeStudent"). Object[] attrs = { new Integer(1234). conn.createDescriptor ("SCOTT. conn). Binding a subtype object is the same as binding a standard object. depending on the approach you choose. "CS".

println ("address="+((String)attrs[2])).getObject(1).getSQLTypeName().out.next()) { oracle. Working with Oracle Object Types 13-29 .sql.equals ("SCOTT. You can determine the individual element type by referencing the corresponding attribute type in the Oracle conversion matrix. System.Datum array to hold the data fields.sql. STUDENT_T and PARTIMESTUDENT_T objects ResultSet rset = stmt.println ("ssn="+((BigDecimal)attrs[0]). as listed in Table 4–1. if (s != null) { String sqlname = s. The JDBC application needs to call one of the following access methods in the STRUCT class to access the data fields: ■ ■ Object[] getAttribute() oracle. this logic for default mapping is defined in the JDBC application itself. For example.sql. as listed in Table 4–1.executeQuery ("select person from tab1").out.person column can store PERSON_T.NUMBER object.sql.out.out.getAttribute(). where each array element represents an object attribute.0 to access object data fields. while (rset. The supertype data fields are listed first followed by the subtype data fields.println ("ssn="+((BigDecimal)attrs[0]). Object[] attrs = s. You can determine the individual element type by referencing the corresponding attribute type in the JDBC conversion matrix.PERSON") { System. The getOracleAttribute method returns an oracle. For example.intValue()).sql.out. System.sql. The following code shows the use of the getAttribute method: // tab1.intValue()).STRUCT s = (oracle. a SQL NUMBER attribute is converted to a java.println ("deptid="+((BigDecimal)attrs[3]).STRUCT class.BigDecimal object. if (sqlname.sql.sql.lang. The supertype data fields are listed first followed by the subtype data fields.math. The getOracleAttribute method returns all the attributes defined in the supertype of the object type. Each element in the oracle. a SQL NUMBER attribute is converted to an oracle.Object array.Object-Type Inheritance Accessing Subtype Data Fields While the logic to access subtype data fields is part of the customized class.intValue()). System.println ("address="+((String)attrs[2])).println ("name="+((String)attrs[1])).equals ("SCOTT. System.Datum[] getOracleAttribute() Subtype Data Fields from the getAttribute Method The getAttribute method of the java. } else if (sqlname.STRUCT) rset.out. as well as attributes defined in the subtype. The database objects are returned as instances of the oracle.out. This method returns a java.STUDENT")) { System.println ("name="+((String)attrs[1])).Struct interface is used in JDBC 2. System.Datum array represents an attribute. The getAttribute method returns all the data fields defined in the supertype of the object type as well as data fields defined in the subtype. Subtype Data Fields from the getOracleAttribute Method The getOracleAttribute method is an Oracle extension method and is more efficient than the getAttribute method.

If you use the ORAData interface.intValue()). } else if (sqlname. as well as other kinds of custom Java classes. The StructMetaData class provides inheritance metadata methods for subtype attributes. JPublisher-generated classes include methods to convert data from SQL to Java and from Java to SQL. System.out. then JPublisher will not produce a custom reference class.sql.close ().out. as well as getter and setter methods for the object attributes.intValue()).StructMetaData classes. System.jdbc.out. This section covers the following topics: ■ ■ JPublisher Functionality JPublisher Type Mappings See Also: Oracle Database JPublisher User's Guide. JPublisher Functionality You can direct JPublisher to create custom object classes that implement either the SQLData interface or the ORAData interface.equals ("SCOTT.out. It generates a full definition for a custom Java class.println ("deptid="+((BigDecimal)attrs[3]).println ("address="+((String)attrs[2])).out.println ("name="+((String)attrs[1])).PARTTIMESTUDENT")) { System. The getMetaData method of the StructDescriptor class returns an instance of StructMetaData of the type. } else throw new Exception ("Invalid type name: "+sqlname). conn. is to use the Oracle JPublisher utility.close ().intValue()).close (). stmt.out. } } rset.println ("major="+((String)attrs[4])).Ref instances instead. System. then JPublisher will also create a custom reference class to map to object references for the Oracle object type. The inheritance metadata methods are defined in the oracle. there is a command-line option for 13-30 Oracle Database JDBC Developer's Guide and Reference .println ("numHours="+((BigDecimal)attrs[5]).StructDescriptor and oracle. If you want additional functionality. Inheritance Metadata Methods Oracle JDBC drivers provide a set of metadata methods to access inheritance properties.println ("major="+((String)attrs[4])). The StructMetaData class contains the following inheritance metadata methods: Using JPublisher to Create Custom Object Classes A convenient way to create custom object classes. When you run JPublisher. If you use the SQLData interface.sql. which you can instantiate to hold the data from an Oracle object. according to how you set the JPublisher type mappings.Using JPublisher to Create Custom Object Classes System. you can subclass the custom object class and add features as desired. System. You would use standard java.println ("ssn="+((BigDecimal)attrs[0]). System.out.

■ Large object (LOB) types This includes the SQL types. ■ Numeric types This includes anything stored in the database as the NUMBER SQL type. and collections. For a custom object. For example.sql types to map to SQL types. This section lists categories of SQL types and the mapping options available for each category. such as Working with Oracle Object Types 13-31 . ■ Object-JDBC mapping (setting objectjdbc) Is an extension of the JDBC mapping. ■ Built-in types This includes anything stored in the database as a SQL type not covered by the preceding categories.lang package. For a custom object class. JPublisher must know the subclass name. You use the JPublisher -lobtypes option to specify type-mapping for LOB types. Categories of SQL Types JPublisher categorizes SQL types into the following groups. references. Where relevant. LONG. reference. You use the JPublisher -numbertypes option to specify type-mapping for numeric types. JPublisher Type Mappings JPublisher offers various choices for how to map user-defined types and their attribute types between SQL and Java. which is incorporated into some of the functionality of the generated class. instead of subclassing it. with corresponding JPublisher options as specifies: ■ User-defined types (UDT) This includes Oracle objects. you would have to re-implement your changes. or collection class. VARCHAR2. Type-Mapping Modes JPublisher defines the following type-mapping modes. two of which apply to numeric types only: ■ JDBC mapping (setting jdbc) Uses standard default mappings between SQL types and Java native types. is not recommended. You use the JPublisher -builtintypes option to specify type-mapping for built-in types. ■ Oracle mapping (setting oracle) Uses corresponding oracle. uses a SQLData implementation. object-JDBC mapping uses numeric object types from the standard java. Note: Hand-editing the JPublisher-generated class. and RAW. If you hand-edit this class and later have to re-run JPublisher for some reason. uses a ORAData implementation. CHAR.Using JPublisher to Create Custom Object Classes specifying both a generated class name and the name of the subclass you will implement. You use the JPublisher -usertypes option to specify the type-mapping implementation for UDTs. either a standard SQLData implementation or an Oracle-specific ORAData implementation. BLOB and CLOB. For the SQL-Java mapping to work properly.

then it will be mapped according to the -usertypes setting. This is appropriate if you are dealing with large numbers but do not want to map to the oracle. A setting of -usertypes=jdbc instructs JPublisher to create a SQLData implementation for the custom object class. The SQLData interface is intended only for mapping Oracle object types. then use the -numbertypes. Mapping the Oracle object type to Java Use the JPublisher -usertypes option to determine how JPublisher will implement the custom Java class that corresponds to a Oracle object type: ■ A setting of -usertypes=oracle. If an attribute type is itself an Oracle object type. instead of primitive Java types. This will also result in JPublisher producing a ORAData implementation for the corresponding custom reference class.BigDecimal to map to all numeric attributes. such as int. ■ BigDecimal mapping (setting bigdecimal) Uses java. depending on the attribute types you have and the mappings you desire.NUMBER class. the default mapping is object-JDBC.Using JPublisher to Create Custom Object Classes java. Mapping Attribute Types to Java If you do not specify mappings for the attribute types of the Oracle object type. Note: Using BigDecimal mapping can significantly degrade performance. ■ The -usertypes=jdbc setting is not valid for mapping SQL collection types. Float. and double.lang. instructs JPublisher to create a ORAData implementation for the custom object class. 13-32 Oracle Database JDBC Developer's Guide and Reference . as necessary. which is the default setting.Ref or oracle. and Double.lang types are nullable. For built-in type attribute types. the default mapping is JDBC. The java.math. You must use java. If you want alternate mappings. the default mapping is Oracle.Integer.sql. -lobtypes. No custom reference class can be created. while the primitive types are not. and -builtintypes options.sql. Note: You can also use JPublisher with a -usertypes=oracle setting in creating ORAData implementations to map SQL collection types.REF for the reference type.sql. then JPublisher uses the following defaults: ■ ■ ■ For numeric attribute types. float. For LOB attribute types.

Describing an Object Type Important: Be aware that if you specify an SQLData implementation for the custom object class and want the code to be portable. bigdecimal oracle. jdbc oracle. The following method is also supported by StructMetaData: String getOracleColumnClassName(int column) throws SQLException Working with Oracle Object Types 13-33 .ResultSetMetaData interface specifies support for result set metadata.sql. a class that supports structured object metadata in the same way that the standard java. The signature of the StructDescriptor class getMetaData method is the same as the signature specified for getMetaData in the standard ResultSet interface. but for LOB types you must specify -lobtypes=jdbc.sql. Table 13–1 SQL Type Category UDT types numeric types LOB types built-in types JPublisher SQL Type Categories. such as attribute names and types. Summary of SQL Type Categories and Mapping Settings Table 13–1 summarizes JPublisher categories for SQL types.jdbc. and Defaults JPublisher Mapping Option -usertypes -numbertypes -lobtypes -builtintypes Mapping Settings oracle. jdbc oracle. objectjdbc. then you must be sure to use portable mappings for the attribute types. the mapping settings relevant for each category. jdbc Default oracle objectjdbc oracle jdbc Describing an Object Type Oracle JDBC includes functionality to retrieve information about a structured object type regarding its attribute names and types. this method actually returns an instance of oracle.StructMetaData. It returns a set of attribute information. The signature is as follows: ResultSetMetaData getMetaData() throws SQLException However. This is similar conceptually to retrieving information from a result set about its column names and types.StructDescriptor class includes functionality to retrieve metadata about a structured object type. This section covers the following topics: ■ ■ Functionality for Getting Object Metadata Steps for Retrieving Object Metadata Functionality for Getting Object Metadata The oracle. jdbc. and in fact uses an almost identical method. The defaults for numeric types and built-in types are portable. Call this method on a StructDescriptor object to get metadata about the Oracle object type that the StructDescriptor object describes. and the default settings. Supported Settings. The StructDescriptor class has a getMetaData method with the same functionality as the standard getMetaData method available in result set objects.

String type_name) throws SQLException { // get the type descriptor StructDescriptor desc = StructDescriptor. which that was returned by the getMetaData method. attr_type = md.getColumnType (i+1).getMetaData ().sql. 3.Datum subclass whose instances are manufactured if the OracleResultSet class getOracleObject method is called to retrieve the value of the specified attribute.sql. // // Print out the ADT's attribute names and types // void getAttributeInfo (Connection conn. 2. you must cast the ResultSetMetaData object. // get type metadata ResultSetMetaData md = desc. String attr_typeName. Call the getMetaData method on the StructDescriptor instance. conn).println ("Attributes of "+type_name+" :"). This includes the initial step of creating a StructDescriptor instance. Steps for Retrieving Object Metadata Use the following steps to obtain metadata about a structured object type: 1. Where you specify a value of 4 for column. for (int i=0.out.getColumnName (i+1). i<numAttrs. Example The following method shows how to retrieve information about the attributes of a structured object type. // get # of attrs of this type int numAttrs = desc. and getColumnTypeName.createDescriptor (type_name. to StructMetaData. Call the metadata getter methods. System. // temporary buffers String attr_name. For example.length (). getColumnType. int attr_type. as desired. To use the getOracleColumnClassName method. oracle. 13-34 Oracle Database JDBC Developer's Guide and Reference . Create or acquire a StructDescriptor instance that describes the relevant structured object type. you really refer to the fourth attribute of the object.NUMBER. Note: In all the preceding method signatures.Describing an Object Type This method returns the fully qualified name of the oracle. i++) { attr_name = md. repeat steps 1 through 3. Note: If one of the structured object attributes is itself a structured object. getColumnName. column is something of a misnomer.

// recursive calls to print out nested object metadata getAttributeInfo (conn.out.STRUCT) { attr_typeName = md. // drill down nested object if (attrType == OracleTypes. } } } Working with Oracle Object Types 13-35 .Describing an Object Type System.println (" index"+(i+1)+" name="+attr_name+" type="+attr_type).getColumnTypeName (i+1). attr_typeName).

Describing an Object Type 13-36 Oracle Database JDBC Developer's Guide and Reference .

and NCLOB data.* classes to access and manipulate large object (LOB) and binary file (BFILE) locators and data.sql. Working with LOBs and BFILEs 14-1 . ■ ■ Oracle Extensions for LOBs and BFILEs LOBs are stored in a way that optimizes space and provides efficient access. CLOB.Blob interfaces. which is used for unstructured binary data.CLOB and oracle.0 java.sql. which is used for character data.14 Working with LOBs and BFILEs This chapter describes how to use Java Database Connectivity (JDBC) and the oracle. which is outside the table.0 interface. the Oracle JDBC drivers support the JDBC 3. CLOB.NClob interface.sql. the maximum size of a LOB was 232 bytes.0 java. The Java LOB application programming interface (API) has not changed. the Oracle JDBC drivers support the JDBC 4. character large object (CLOB). You should port your application to the standard JDBC 3. which is used for national character data. This chapter contains the following sections: ■ ■ ■ ■ ■ ■ ■ Oracle Extensions for LOBs and BFILEs Working with BLOBs. BLOB. In Oracle Database 10g.BLOB in earlier Oracle Database releases are no longer necessary and are deprecated. and NCLOB data is accessed and referenced by using a locator that is stored in the database table and points to the BLOB.sql.sql.sql. Prior to Oracle Database 10g. Certain Oracle extensions made in oracle. The JDBC drivers provide support for three types of LOB: binary large object (BLOB). CLOBs and NCLOBs Data Interface for LOBs Working With Temporary LOBs Using Open and Close With LOBs Working with BFILEs Oracle SecureFiles Notes: ■ In Oracle Database 11g. and the maximum size is limited to the size of available physical storage. This restriction has been removed since Oracle Database 10g. and national character large object (NCLOB).Clob and java.

CLOB oracle. CLOB. CLOB or NCLOB Column Accessing and Manipulating BLOB. These files use reference semantics.Clob. getClob.sql. CLOB and NCLOB Locators Retrieving BLOB.sql. Then you can read or write LOB data and perform data manipulation. CLOBs. or NCLOB locators.sql. respectively. and NCLOB Locators Standard as well as Oracle-specific getter and setter methods are available for retrieving or passing LOB locators from or to the database. PhotoCDs.NClob interfaces. using LOB locators. CLOB. then use the factory methods from oracle. To work with LOB data.Working with BLOBs. CD-ROMs. and NCLOBs. or NCLOB Data Getting and Passing BLOB. without a corresponding java. not the data. and NCLOBs in Oracle Database.sql.sql. CLOB. Clob.sql. After accessing the locators. 14-2 Oracle Database JDBC Developer's Guide and Reference . The JDBC drivers support the following oracle.sql.BLOB oracle. CLOB. As with BLOB. In contrast. and NClob objects. CLOBs and NCLOBs This section describes how to read and write data to and from BLOBs. and NCLOB Locators Given a standard JDBC result set or callable statement that includes BLOB.Blob. They can also be located on tertiary storage devices. and DVDs. and BFILEs: ■ ■ ■ ■ oracle. and NCLOB Locators Reading and Writing BLOB. a BFILE is accessed and referenced by a locator which is stored in the database table and points to the BFILE data. you must first obtain a LOB locator.* classes for BLOBs.sql. and NCLOB Locators Passing BLOB. Note: If you want to create a new LOB. CLOB. NCLOBs. This section covers the following topics: ■ ■ ■ ■ Getting and Passing BLOB.CLOB. respectively. and getNClob methods. CLOB.NCLOB classes implement the java. Working with BLOBs. java. you must perform some additional steps to access the data.jdbc. CLOB and NCLOB Data Creating and Populating a BLOB. This section covers the following topics: ■ ■ Retrieving BLOB.Blob. Instances of these classes contain only the locators for these data types.BLOB. and java. such as hard disks.OracleConnection interface.NCLOB oracle.sql. you can access the locators by using standard getter methods.sql.sql interface. CLOBs. and oracle. CLOB. BFILE is an Oracle extension. CLOBs and NCLOBs BFILEs are large binary data objects stored in operating system files outside of database tablespaces.BFILE The oracle. You can use the standard getBlob.sql. which return java. oracle.sql.

sql. (.. java.sql. and java.) } The output is cast to java. a column for a CLOB locator..Blob)rs.sql.sql. CLOBs and NCLOBs Note: All the standard and Oracle-specific getter methods discussed here take either an int column index or a String column name as input. java.sql.sql..CLOB. ■ Example: Getting BLOB.sql.sql. You can also use the getOracleObject method. Working with LOBs and BFILEs 14-3 . ResultSet rs = stmt.Blob blob = (java.sql. you can cast the output to oracle. oracle. (.sql.process.NClob nclob = (java.Clob clob = (java. you can rewrite the preceding code to get the LOB locators as: // Get LOB locators into Java container classes.) Example: Getting a CLOB Locator from a Callable Statement The callable statement methods for retrieving LOBs are identical to the result set methods.NCLOB to take advantage of extended functionality offered by the oracle.sql. as follows: ■ You can use getBLOB. then you can use Oracle extensions.Working with BLOBs.executeQuery ("SELECT blob_col.Clob.getObject(3).sql.Datum object. CLOB. select the LOB locators into a standard result set.prepareCall("{? = call func()}").sql.CLOB clob = (CLOB)rs. clob_col. respectively.sql.. and a column for a NCLOB locator. oracle.* classes.getObject(2). This example assumes that you have already created the Statement object. and NCLOB objects.CLOB as the type code of the output parameter. getCLOB. while (rs.getObject(3). nclob_col.sql. stmt. As an alternative.NCLOB nclob = (NCLOB)rs. which return oracle.sql.getObject(1). oracle. nclob_col FROM lob_table").. and NCLOB Locators from a Result Set Assume the database has a table called lob_table with a column for a BLOB locator. then get the LOB data into appropriate Java classes: // Select LOB locator into standard result set. java.BLOB blob = (BLOB)rs.getObject(1).Clob)rs. and cast the output appropriately.BLOB. ocs..process.NClob)rs.sql.. then set up the callable statement as in the following example. clob_col. OracleCallableStatement ocs = (OracleCallableStatement)conn. blob_col. For example. oracle. This example registers OracleTypes. If you retrieve or cast the result set or the callable statement to OracleResultSet or OracleCallableStatement. First. and getNCLOB. CLOB. and oracle. that calls a function func that has a CLOB output parameter.Blob. if you have an OracleCallableStatement instance. For example.sql.NClob.getObject(2).. which returns an oracle. java.BLOB.next()) { // Get LOB locators into Java container classes.

CLOB clob = ocs. 14-4 Oracle Database JDBC Developer's Guide and Reference . CLOB and NCLOB Locators Given a standard JDBC prepared statement or callable statement. ocs. ■ Example: Passing a BLOB Locator to a Prepared Statement If you have an OraclePreparedStatement object ops and a BLOB named my_blob.prepareCall("{call proc(?))}"). CLOBs and NCLOBs ocs.sql.execute(). which take oracle. then you can use Oracle extensions as follows: ■ Use setBLOB.getCLOB(1).prepareStatement ("INSERT INTO blob_table VALUES(?)"). which simply specifies an oracle. Note: If you pass a BLOB to a PL/SQL procedure. my_blob).sql.execute(). and setNClob.BLOB.execute().CLOB). Use the setOracleObject method.Datum input.setBLOB(1. then you will receive a SQLException exception. ops.execute().7. OracleTypes. CLOB and NCLOB locators as input. oracle. These methods are defined as follows: public void setBlob(int index. Given an Oracle-specific OraclePreparedStatement or OracleCallableStatement. then input the NCLOB to the stored procedure proc as follows: OracleCallableStatement ocs = (OracleCallableStatement)conn. Example: Passing a CLOB Locator to a Callable Statement If you have an OracleCallableStatement object ocs and a CLOB named my_clob.prepareCall("{call proc(?))}"). my_clob).registerOutParameter(1. setCLOB. you can use standard setter methods to pass LOB locators. Example: Passing an NCLOB Locator to a Callable Statement If you have an OracleCallableStatement object ocs and an NCLOB named my_nclob. Clob value). ocs. NClob value). ocs. If you pass a BLOB that exceeds this limit. public void setNClob(int index. public void setClob(int index.setClob(1. ocs. then write the BLOB to the database as follows: OraclePreparedStatement ops = (OraclePreparedStatement)conn. respectively.Working with BLOBs. my_nclob).sql. Blob value). ocs. ops. Passing BLOB.setNClob(1. then input the CLOB to the stored procedure proc as follows: OracleCallableStatement ocs = (OracleCallableStatement)conn. then the BLOB must be no bigger than 32K .

Reader object. use one of the overloaded write methods to update the LOB data and use the close method when you finish. This returns a java. use the getAsciiStream or getCharacterStream method of an java.OutputStream object to be written back to the BLOB.Working with BLOBs. and closing a LOB. Unlike LONG and LONG RAW data.OutputStream object.CLOB.BLOB. As with any InputStream or Reader object. Also.sql.sql. As with any InputStream object. The getCharacterStream method returns a Unicode input stream in a java.io. java. you must disable auto-commit mode.String. Working with LOBs and BFILEs 14-5 . use one of the overloaded read methods to read the LOB data and use the close method when you finish. CLOB and NCLOB Data Once you have a LOB locator. use the setAsciiStream or setCharacterStream method of an java. and java.sql. ■ To read from an NCLOB. writing from an output stream into a LOB.NCLOB object to retrieve the entire NCLOB as an input stream.InputStream object. you can use JDBC methods to read and write the LOB data. use the methods in the java. use the getAsciiStream or getCharacterStream method of an java. as appropriate. use one of the overloaded read methods to read the LOB data and use the close method when you finish. This returns a java. You can also use the getSubString method of java. you can access the LOB data at any time during the life of the connection. As with any InputStream or Reader object. These classes provide functionality such as reading from the LOB into an input stream. use one of the overloaded read methods to read the LOB data and use the close method when you finish.sql. the application must acquire a write lock on the LOB object.io.sql. ■ To write to a CLOB. use one of the overloaded write methods to update the LOB data and use the flush and close methods when you finish.lang.InputStream object.BLOB object to retrieve the entire BLOB as an input stream. determining the length of a LOB. The setAsciiStream method returns an ASCII output stream in a java. The getAsciiStream method returns an ASCII input stream in a java.io. One way to accomplish this is through a SELECT FOR UPDATE. ■ To write to a BLOB. you can use these methods: ■ To read from a BLOB. LOB data is materialized as a Java array or stream.sql.sql.BLOB object to retrieve the BLOB as an output stream. use the setBinaryStream method of an java.Reader object. The getAsciiStream method returns an ASCII input stream in a java. ■ To read from a CLOB.CLOB object to retrieve a subset of the CLOB as a character string of type java.CLOB object to retrieve the CLOB as an output stream to be written back to the CLOB.Writer object.io.CLOB object to retrieve the entire CLOB as an input stream. As with any Stream or Writer object. The setCharacterStream method returns a Unicode output stream in a java.sql.io. To read and write the LOB data.io.io.sql. The getCharacterStream method returns a Unicode input stream in a java. To read and write LOB data.io.NCLOB class.InputStream object. Notes: To write LOB data. As with any OutputStream object. CLOBs and NCLOBs Reading and Writing BLOB. use the getBinaryStream method of an java.

you must commit the transaction for the changes to be permanent. returning the number of bytes read. ■ To write to an NCLOB. 10). int bytes_read = byte_stream.lang. even if the transaction is rolled back.sql.io. The following example uses the getBinaryStream method to read BLOB data through a byte stream and then reads the byte stream into a byte array.. The entire LOB is not fetched all at once. byte [] byte_array = new byte [10]. The getBinaryStream method provides access to the BLOB data through a binary stream.Writer object. Example: Reading CLOB Data The following example uses the getCharacterStream method to read CLOB data into a Unicode character stream. Once you write to them the changes are permanent. The setCharacterStream method returns a Unicode output stream in a java. unless the external file system does something else.BLOB class to read BLOB data.getCharacterStream(1L).NCLOB object to retrieve a subset of the NCLOB as a character string of type java. When writing to or reading from a CLOB or an NCLOB. as well. as well. // Read CLOB data from CLOB locator into Reader char stream. It then reads the character stream into a character array.Working with BLOBs.io. CLOBs and BLOBs are transaction controlled. The setAsciiStream method returns an ASCII output stream in a java. use one of the overloaded write methods to update the LOB data and use the flush and close methods when you finish. InputStream byte_stream = my_blob. char [] char_array = new char [10]. you need to call close or flush to ensure all changes are written. After writing to either. use the setAsciiStream or setCharacterStream method of an oracle.sql. When reading a LOB using any of the getXXX methods described in the section. 0. However.sql.read(byte_array). . ■ ■ Example: Reading BLOB Data Use the getBinaryStream method of the oracle.String. 14-6 Oracle Database JDBC Developer's Guide and Reference . the returned stream fetches blocks of data from the database needed. returning the number of characters read.getBinaryStream(1L).read (char_array. BFILEs are not transaction controlled.NCLOB object to retrieve the NCLOB as an output stream to be written back to the NCLOB. which makes it practical to read very large LOBs. Reader char_stream = my_clob. int chars_read = char_stream. As with any Stream or Writer object..OutputStream object. You do not need to run an UPDATE to write the data. the JDBC drivers perform all character set conversions for you. // Read BLOB data from BLOB locator. Notes: ■ The stream write methods described in this section write directly to the database when you write to the output stream. CLOBs and NCLOBs You can also use the getSubString method of java.

'2'.Writer writer.read (char_array. // read data into a character array char[] data = {'0'.. The setCharacterStream method returns a Unicode output stream. The setAsciiStream method returns an ASCII output stream.'6'. java.io.. java.setCharacterStream(). The following example reads a vector of data into a character array. Working with LOBs and BFILEs 14-7 . // Read NCLOB data from NCLOB locator into Input ASCII character stream Inputstream asciiChar_stream = my_nclob. Example: Writing BLOB Data Use the setBinaryOutputStream method of an oracle. // write the array of binary data to a Blob outstream = ((BLOB)my_blob).. Example: Reading NCLOB Data The following example uses the getCharacterStream method to read NCLOB data into a Unicode character stream. writer. 7. then uses the setCharacterStream method to write the array of character data to a CLOB.. 2.sql. 4..OutputStream outstream. char [] char_array = new char [10].close(). 9}. writer.'5'. 10). byte[] asciiChar_array = new byte[10]. as well.read(asciiChar_array. // write the array of character data to a Clob writer = ((CLOB)my_clob). The following example reads a vector of data into a byte array. Example: Writing CLOB Data Use the setCharacterStream method or the setAsciiStream method to write data to a CLOB. 3..'3'. 8. int chars_read = char_stream.10).. as well.write(data).write(data).'4'. CLOBs and NCLOBs . 5. . 6. writer.getAsciiStream(1L).flush()..io.setBinaryOutputStream(1L). then uses the setBinaryOutputStream method to write an array of character data to a BLOB. It then reads the ASCII stream into a byte array. // read data into a byte array byte[] data = {0. It then reads the character stream into a character array.NCLOB class to read NCLOB data through an ASCII character stream.'7'.0.getCharacterStream(1L).'8'.Working with BLOBs. . The next example uses the getAsciiStream method of the oracle. 1.'9'}. returning the number of bytes read. 0. // Read NCLOB data from NCLOB locator into Reader char stream. Reader char_stream = my_nclob.'1'.BLOB object to write BLOB data.sql. returning the number of characters read. int asciiChar_read = asciiChar_stream. outstream. .

Writer writer. CLOB or NCLOB Column Create and populate aBLOB.jdbc. The next example reads a vector of data into a byte array.'7'.'5'.'9'}. out.'2'. out.. writer. or NCLOB locator in your application with a Java new statement..write(data). .setAsciiStream().'3'.OutputStream out. CLOB.io. Example: Writing NCLOB Data Use the setCharacterStream method or the setAsciiStream method to write data to an NCLOB.'6'.Working with BLOBs.io.flush(). CLOB. You cannot construct a new BLOB.'1'.'4'.'6'. writer.close().'7'. CLOBs and NCLOBs The next example reads a vector of data into a byte array. // read data into a byte array byte[] data = {'0'. // write the array of ascii data to a CLOB out = clob.'9'}.setAsciiStream().'2'.'8'. The setCharacterStream method returns a Unicode output stream. out. java. out. and then select it into your application or use the factory methods from oracle.write(data). writer. or NCLOB column in a table by using SQL statements. You must create the locator through a SQL operation.'2'.flush(). then uses the setCharacterStream method to write the array of character data to an NCLOB.write(data). The following example reads a vector of data into a character array.'5'. then uses the setAsciiStream method to write the array of ASCII data to an NCLOB.OracleConnection interface. java. // write the array of ascii data to a NClob out = nclob. // read data into a byte array byte[] data = {'0'. out.'5'.'4'. Note: 14-8 Oracle Database JDBC Developer's Guide and Reference .'1'.'8'. then uses the setAsciiStream method to write the array of ASCII data to a CLOB.'6'.OutputStream out. java. // write the array of character data to an NClob writer = ((NCLOB)my_nclob). out.close().'1'.'8'. Creating and Populating a BLOB. The setAsciiStream method returns an ASCII output stream.'3'.flush().'7'.'3'.'4'.close().setCharacterStream(). // read data into a character array char[] data = {'0'.io.'9'}.

System. In this example. The following example writes the john. CLOB. This value will be used later to ensure that the entire file is read into the BLOB. CLOB. CLOBs and NCLOBs Create a BLOB. Working with LOBs and BFILEs 14-9 . Begin by using SQL statements to create the BLOB entry in the table. rset. The following example code creates a BLOB column in a new table. then print the length of the file. These steps assume that you have already created your Connection object conn and Statement object stmt. The table my_blob_table is the table that was created in the previous section. This includes creating the LOB entry in the table. int size = blob.length()). CLOB. run the SQL CREATE TABLE statement.getBLOB(2). int length = -1. CLOB. FileInputStream instream = new FileInputStream(binaryFile). or NCLOB column in a table with the SQL CREATE TABLE statement.gif file to a BLOB: 1. Next.setBinaryStream(1L). CLOB. then create the buffer byte array. create a FileInputStream object to read the contents of the file. Declare a file handler for the john.execute ("INSERT INTO my_blob_table VALUES ('row1'.getBufferSize(). or NCLOB Column in a New Table To create a BLOB. empty_blob())"). File binaryFile = new File("john. This example assumes that you have already created your Connection object conn and Statement object stmt: String cmd = "CREATE TABLE my_blob_table (x VARCHAR2 (30). BLOB blob. or NCLOB column in a new table.gif file. then populate the LOB. ResultSet rset = stmt. and an OutputStream object to retrieve the BLOB as a stream. and then copying the data into the LOB. or NCLOB Column in a New Table This example demonstrates how to populate a BLOB. You must disable auto-commit mode.gif"). cmd = "SELECT * FROM my_blob_table WHERE X='row1' FOR UPDATE".next().execute (cmd). stmt. and the BLOB column stores the locator of the BLOB data. Get the BLOB locator from the table. c BLOB)". or NCLOB column by reading data from a stream. Note: 3.out. BLOB blob = ((OracleResultSet)rset). obtaining the LOB locator. Creating a BLOB. Populating a BLOB. Use the empty_blob function to create the BLOB locator.executeQuery(cmd). the VARCHAR2 column designates a row number. such as 1 or 2. 2. Call getBufferSize to retrieve the ideal buffer size to use in writing to the BLOB.println("john. byte[] buffer = new byte[size]. stmt. OutputStream outstream = blob. 4.Working with BLOBs.gif length = " + binaryFile.

getString(1). CLOB.what we are really doing here // is getting the blob locator into a result set BLOB blob. CLOB. After you select the locators.write(buffer. // Get the blob data . you can manipulate the data.BLOB.Blob and java.Data Interface for LOBs 5. you first must select their locators from a result set or from a callable statement. you can access and manipulate the data to which it points. Data Interface for LOBs The data interface for LOBs provides a streamlined mechanism for writing and reading the entire LOB contents. length). Once your data is in the BLOB.commit(). close the input and output streams and commit the changes. oracle. The result of the data manipulation is to print the length of the BLOB in bytes. It does not provide the random access capability or access beyond 2147483648 elements as do the standard java. It uses the SQL SELECT statement to select the BLOB locator from the table my_blob_table into a result set. or NCLOB data. It is simpler to code and faster in many cases. or NCLOB locator in a table. blob = ((OracleResultSet)rset).executeQuery (cmd).close(). // Select the blob .BFILE. To access and manipulate the data.sql format String index = ((OracleResultSet)rset). you can retrieve the BLOB. and oracle. // get the length of the blob int length = blob.println("blob length" + length). or NCLOB. oracle. length). cmd = "SELECT * FROM my_blob_table". length). while ((length = instream. // print the length of the blob System.sql. ResultSet rset = stmt. CLOB.read(buffer)) != -1) outstream. Accessing and Manipulating BLOB.CLOB.sql. After retrieving the BLOB. 14-10 Oracle Database JDBC Developer's Guide and Reference . you can manipulate it however you want. 0. CLOB. CLOB. conn. outstream.Clob interfaces and the Oracle extensions.sql. This example is a continuation of the example in the previous section.cast to OracleResult set to // retrieve the data in oracle. // read the blob into a byte array // then print the blob from the array byte bytes[] = blob.sql.sql. instream.length().getBytes(1.close(). blob. or NCLOB data.getBLOB(2). then use the write method to write it to the BLOB. Use the read method to read the file to the byte array buffer.out.printBytes(bytes. or NCLOB Data Once you have your BLOB. When you finish.

?). Another impact is that the automatic switching may result in additional server-side parsing to adapt to the change in the parameter type. Now. When data is greater Working with LOBs and BFILEs 14-11 .NCHAR. and setAsciiStream methods of PreparedStatement are extended for BLOB and CLOB parameters. The setBytesForBlob and setStringForClob methods create temporary LOBs. The limitation does not apply for PL/SQL statements. which is that array sizes are limited to positive Java int or 2147483648 elements. the setBytes.Data Interface for LOBs Input In Oracle Database 11g release 1 (11. which formerly got ORA-17157 errors for attempts to use setString for String values larger than 32766 characters. However. c INTO clob_tab VALUES(?. Setting this property causes the standard setString method to switch to setStringForClob method for large data. or Types. which is the standard. such as an INSERT statement. as follows: BEGIN INSERT id. This property is no longer used or needed.NCLOB.LONGNVARCHAR. which are automatically freed when the statement is executed or closed before execution. END. This will have impact on some programs. There is a simple workaround for an INSERT statement. when a PL/SQL procedure or function is embedded in a SQL statement. For the JDBC Oracle Call Interface (OCI) and Thin drivers there is no limitation on the size of the byte array or String and no limit on the length specified for the stream functions except the limits imposed by the Java language. setBinaryStream. Types.NVARCHAR. which is to wrap it in a PL/SQL block. depending on the type of the target parameter an error may occur while the application is executed or the operation may succeed. Oracle Database 10g release 1 (10. Types. setCharacterStream. the target data type must be specified as Types. For the server-side internal driver there is currently a limitation of 4000 bytes for operations on SQL statements. setString. If the setObject method is used . You must bear in mind the following automatic switching of the input mode for large data: ■ For SQL statements: – – setBytes switches to setBinaryStream for data larger than 2000 bytes setString switches to setCharacterStream for data larger than 32766 characters ■ PL/SQL statements – – – setBytes switches to setBinaryStream for data larger than 2000 bytes and to setBytesForBlob for data larger that 32766 bytes setString switches to setStringForClob for string data larger than 32766 bytes in the database character set setNClob or setObject is used for large national character set type data.1). This would result in a performance effect if the data sizes vary above and below the limit for repeated executions of the statement. data less than 4 KB is bound as String. Switching to the stream modes will effect batching as well.1) has the SetBigStringTryClob connection property.

For any IN and OUT parameter. This operates entirely on the client-side and will work with any supported version of the database. the driver binds the data as a String as for any SQL statement. Size Limitations Please be aware of the effect on the performance of the Java memory management system due to creation of very large byte array or String.CLOB on the second. Consider that you have an IN OUT CLOB parameter of a stored procedure and you wish to use setString for setting the value for this parameter. BFILE.7 and later. You can also create a callable statement. if you have: CREATE PROCEDURE clob_proc( c IN OUT CLOB ). getCharacterStream. Another workaround is to use a container block to make the call. 14-12 Oracle Database JDBC Developer's Guide and Reference . That is. use defineColumnType(nn. Output The getBytes. Please read the information provided by your Java virtual machine (JVM) vendor about the impact of very large data elements on memory management. getBinaryStream. then you could use setString for the input parameter and register the OUT parameter as Types. and BFILE columns or OUT parameters.LONGVARBINARY) or defineColumnType(nn. or CLOB data can be read and written using the same streaming mechanism as for LONG RAW and LONG data. This technique is limited to Oracle Database 10g release 1 (10. then. the binds must be of the same type. CLOB. A better solution is to change the stored procedure to have separate IN and OUT parameters. This will throw an error. clob_proc( c_temp).Data Interface for LOBs than 4KB. getSting. change it to: CREATE PROCEDURE clob_proc( c_in IN CLOB. and consider using the stream interfaces instead. if it is known that neither the input nor output data will ever be larger than 32766 bytes. CallableSatement and IN OUT Parameter It is a PL/SQL requirement that the Java types used as input and output for an IN OUT parameter must be the same. The clob_proc procedure can be wrapped with a Java string to use for the prepareCall statement. c_out OUT CLOB ). BEGIN c_temp := ?. This produces a direct stream on the data as if it were a LONG RAW or LONG column. and getAsciiStream methods of ResultSet and CallableStatement are extended to work with BLOB. The workaround is to use setClob or setCharacterStream instead of setString or setStringForClob. To read. Oracle Database 8. that is.1) and later. as follows: "DECLARE c_temp. Types.1.Types. END.LONGVARCHAR) on the column. ? := c_temp.VARCHAR and use getString for the output parameter. These methods will work for any LOB of length less than 2147483648. For example. The automatic switching of types done by the extensions described in this chapter may cause problems with this. BLOB. The automatic switching of the input mode will cause problems unless you are sure of the data sizes." In either case you may use setString on the first parameter and registerOutParameter with Types.

You can insert temporary LOBs into a table. Also invoke freeTemporary to free the temporary LOBs.jdbc. Free any temporary LOBs before ending the session or call.FORM_NCHAR. the storage used by the temporary LOB will not be reclaimed. short form). CLOB.Working With Temporary LOBs Working With Temporary LOBs You can use temporary LOBs to store transient data. int duration). The duration must be either DURATION_SESSION or DURATION_CALL as defined in the oracle.5 You create temporary national character large objects (NCLOBs) using a variant of the createTemporary method. For example. else it returns false. This method is defined in both the oracle. Frequent failure to free temporary LOBs will result in filling up temporary table space with unavailable LOB storage. If you do not. ■ Creating Temporary NCLOBs in JDK 1. which ever is appropriate.BLOB or oracle.sql. if the LOB data is relatively small so that the overhead of copying the data is less than the cost of a database round trip to retrieve the empty locator. The data is stored in temporary table space rather than regular table space.createTemporary (Connection conn. Notes: ■ Failure to free a temporary LOB will result in the storage used by that LOB in the database being unavailable.CLOB class. a permanent copy of the LOB is created and stored.OraclePreparedStatement. In Java stored procedures. The form argument specifies whether the created LOB is a CLOB or an NCLOB. You free a temporary LOB with the freeTemporary method.sql. int duration. then the method creates an NCLOB. boolean. DURATION_SESSION is appropriate. You can test whether a LOB is temporary by calling the isTemporary method. If form equals oracle. int). int duration). When you do this. use getClob or getBlob instead of getString or getBytes. Inserting a temporary LOB may be preferable for some situations. When fetching data from a ReultSet with columns that are temporary LOBs. then the space the LOB consumes in temporary table space will not be reclaimed. you can use either DURATION_SESSION or DURATION_CALL.sql. boolean isCached. then the isTemporary method returns true. boolean isCached. You create a temporary LOB with the static method createTemporary(Connection. public static BLOB createTemporary(Connection conn.BLOB and oracle. Otherwise. In client applications. If form equals Working with LOBs and BFILEs 14-13 . Remember that the data is initially stored in the temporary table space on the server and then moved into permanent storage. You can free a temporary LOB by calling the freeTemporary method. boolean cache. If the LOB was created by calling the createTemporary method. You should free temporary LOBs after you no longer need them. public static CLOB createTemporary(Connection conn.CLOB classes.sql.

you might design your application so that domain indexes are not be updated until you call the close method. This section covers the following topics: ■ ■ ■ ■ Getting and Passing BFILE Locators Reading BFILE Data Creating and Populating a BFILE Column Accessing and Manipulating BFILE Data 14-14 Oracle Database JDBC Developer's Guide and Reference . You open a LOB by calling the open or open(int) method.sql. using file locators.jdbc.CLOB classes.sql. but the triggers for domain indexing are not fixed. You can see if a LOB is open or closed by calling the isOpen method. When you close the LOB. thereby firing any triggers on a domain index. the trigger on domain indexes will be fired at the Close call.Using Open and Close With LOBs oracle. any triggers associated with the LOB will fire. close the LOB by calling the close method. Hence. Working with BFILEs This section describes how to read data to BFILEs.Connection interface to create an NCLOB. then the method creates a CLOB. as defined in the oracle. If you open the LOB with MODE_READONLY. all the changes made to the LOB and non-LOB data in the transaction are committed. any attempt to write to the LOB will result in a SQL exception. then triggers will not be fired for each LOB modification. You can use the standard factory method of java. If you wrap your LOB operations inside the Open/Close call operation.0 supports NCLOBs directly. but the transaction is successfully committed. the value of the argument must be either MODE_READONLY or MODE_READWRITE. Note that in this case. If you do not wrap LOB operations inside an Open/Close call operation. this means that any domain indexes on the LOB will not be valid in-between the Open/Close calls. However. If you open the LOB by calling the open(int) method. For example. any domain indexes on the LOB will become updated as soon as LOB modifications are made. You may choose to open and close them for performance reasons. Instead.sql.6 JDBC 4. domain LOB indexes are always valid and may be used at any time.BLOB and oracle. Using Open and Close With LOBs You do not have to open and close your LOBs. Therefore.FORM_CHAR.OraclePreparedStatement. Creating Temporary NCLOBs in JDK 1. You may then read and write the LOB without any triggers associated with that LOB firing. Note: An error occurs if you commit the transaction before closing all LOBs that were opened by the transaction. The openness of the open LOBs is discarded. then each modification to the LOB will implicitly open and close the LOB. When you are done accessing the LOB.

next()) { oracle. ■ Example: Getting a BFILE locator from a Result Set Assume that the database has a table called bfile_table with a single column for the BFILE locator bfile_col.sql. The following code example sets up the callable statement. you can access the locators by using the standard result set getObject method.Object. OracleTypes.sql.registerOutParameter(1.BFILE my_bfile = ((OracleResultSet)rs). you can use getObject to return the BFILE locator. because getObject returns a java.sql. If using getObject or getOracleObject. Retrieving BFILE Locators Given a standard JDBC result set or callable statement object that includes BFILE locators. while (rs.BFILE. registers the output parameter as OracleTypes. Notes: ■ In the OracleResultSet and OracleCallableStatement classes. For example: oracle. There is no java. ocs. as necessary.execute().getObject(1).BFILE object. then you can use getBFILE to get the BFILE locator. oracle.sql.BFILE. If you cast the result set to OracleResultSet.BFILE).sql. You can also access the locators by casting your result set to OracleResultSet or your callable statement to OracleCallableStatement and using the getOracleObject or getBFILE method.prepareCall("{? = call func()}").getBFILE(1). Select the BFILE locator into a standard result set. getBFILE and getBfile both return oracle. Working with LOBs and BFILEs 14-15 . runs the statement.lang.sql interface for BFILEs. } Note that as an alternative. In this case. This example assumes that you have already created your Statement object stmt.getBFILE(1). as follows: // Select the BFILE locator into a result set ResultSet rs = stmt. remember to cast the output.BFILE my_bfile = (BFILE)rs.executeQuery("SELECT bfile_col FROM bfile_table"). cast the results to BFILE.Working with BFILEs Getting and Passing BFILE Locators Getter and setter methods are available for retrieving or passing BFILE locators from or to the database. This method returns an oracle. and retrieves the BFILE locator: OracleCallableStatement ocs = (OracleCallableStatement)conn.BFILE bfile = ocs. Example: Getting a BFILE Locator from a Callable Statement Assume you have an OracleCallableStatement object ocs that calls a function func that has a BFILE output parameter. ocs.

BFILE class to open a BFILE. OracleCallableStatement cstmt = (OracleCallableStatement)conn. as follows: OraclePreparedStatement ops = (OraclePreparedStatement)conn.prepareCall ("begin ? := myGetFileLength (?). return cstmt. bfile). } Reading BFILE Data To read BFILE data. use the closeFile method of the BFILE class. The first column is a string. ops. Cast the statement to OraclePreparedStatement or OracleCallableStatement. However. as follows: ■ ■ Use the openFile method of the oracle.BFILE object. use one of the overloaded read methods to read the file data and use the close method when you finish. In this case.sql. ops. you must first get the BFILE locator. To read from a BFILE. end.BFILE methods fileExists() and isFileOpen() to determine whether the BFILE exists and if it is open.setBFILE(2.execute().registerOutParameter (1. and you have an OraclePreparedStatement object ops to insert data into a table. For example. Write the BFILE to the database. These methods take the parameter index and an oracle. the BFILE locator is passed to the myGetFileLength procedure.sql. bfile.io.sql.InputStream object. As with any InputStream object. you can do one of the following: ■ ■ Use the standard setObject method.").setString(1.?)").sql. the second column is a BFILE. cstmt. When you are done. you can call a number of methods on the BFILE without opening it. which returns the BFILE length as a numeric value.getLong (1). ops. You can get the locator from either a callable statement or a result set. try { cstmt. bfile). Once you obtain the locator. Types. BFILE data is through a Java stream. use the getBinaryStream method of an oracle.Working with BFILEs Passing BFILE Locators To pass a BFILE locator to a prepared statement or callable statement. and you have a valid oracle.prepareStatement ("INSERT INTO my_bfile_table VALUES (?. if you want to read and manipulate the data.execute ().sql.BFILE object as input.NUMERIC). you can use the oracle. cstmt. Example: Passing a BFILE Locator to a Prepared Statement Assume you want to insert a BFILE locator into a table. 14-16 Oracle Database JDBC Developer's Guide and Reference . Example: Passing a BFILE Locator to a Callable Statement Passing a BFILE locator to a callable statement is similar to passing it to a prepared statement. then you must open and close the BFILE.BFILE object to access the file as an input stream.setBFILE (2. This returns a java. and use the setOracleObject or setBFILE method."one").

getBinaryStream(). 'file1. // Read BFILE data from a BFILE locator Inputstream in = bfile. In this example. the directory alias is test_dir and the BFILE resides in the /home/work directory. ■ Example: Reading BFILE Data The following example uses the getBinaryStream method of an oracle. cmd = "CREATE DIRECTORY test_dir AS '/home/work'". They reside in the OS (operating system) File System and can be written to only using OS tools and commands.execute (cmd). However. stmt. cmd ="INSERT INTO my_bfile_table VALUES ('one'. To specify the location of the BFILE. stmt.execute (cmd). use the SQL CREATE DIRECTORY. Creating and Populating a BFILE Column This section discusses how to create a BFILE column in a table with SQL operations and specify the location where the BFILE resides. To populate the BFILE column. bfilename(test_dir.execute (cmd). Working with LOBs and BFILEs 14-17 . In this example.AS statement to specify an alias for the directory where the BFILE resides.BFILE object to read BFILE data into a byte stream and then read the byte stream into a byte array. and specify the location of the BFILE. the name of the table is my_bfile_table.read(byte_array).sql. In this example. Use the SQL CREATE TABLE statement to create a table containing a BFILE column. use the bfilename function to specify the directory alias and the name of the BFILE file. Those are created only externally. String cmd. byte[] byte_array = new byte{10}. b bfile)".VALUES statement to populate the VARCHAR2 and BFILE fields. Populating a BFILE Column Use the SQL INSERT INTO.. stmt.. create a BFILE column in a table. bfilename(test_dir. the VARCHAR2 column designates a row number and the BFILE column stores the locator of the BFILE data. you cannot create an OS file that a BFILE would refer to. Creating a BFILE Column in a New Table To work with BFILE data. // Create a table containing a BFILE field cmd = "CREATE TABLE my_bfile_table (x varchar2 (30). int byte_read = in. You can create a BFILE. The BFILE column is populated with the locator to the BFILE data. The example assumes that the BFILE has already been opened. cmd ="INSERT INTO my_bfile_table VALUES ('two'. The examples in this section assume that you have already created your Connection object conn and Statement object stmt.Working with BFILEs Notes: ■ BFILEs are read-only.data'))"...

getBFILE (2). the prepared statement must be cast to OraclePreparedStatement: OraclePreparedStatement ops = (OraclePreparedStatement)conn.data is loaded into the BFILE column on row one. Here. rs. do not require you to open the BFILE. 14-18 Oracle Database JDBC Developer's Guide and Reference . create your prepared statement. Once you have the BFILE locators available in a table. insert the row number into the table and null as a place holder for the BFILE locator. cmd ="INSERT INTO my_bfile_table VALUES ('three'.getDirAlias()). Later in your program. insert the BFILE locator into the table by using a prepared statement. you may want to create the row for the row number and BFILE locator now. such as getDirAlias and getName. The result set is cast to OracleResultSet so that oracle. stmt. Note that because this example uses the setBFILE method to identify the BFILE. you must first select its locator from a result set or a callable statement. do require you to open the BFILE.sql. you do not have to open the bfile println("getDirAlias() = " + bfile.next(). three is inserted into the row number column and null is inserted as the place holder. bfile).executeQuery (cmd).prepareStatement (UPDATE my_bfile_table SET b=? WHERE x = 'three'). ops. getting the locator of the BFILE from row two of a table into a result set.setBFILE(1. and the locator of the BFILE jdbcTest.Working with BFILEs 'jdbcTest.next ()) BFILE bfile = ((OracleResultSet)rset).BFILE bfile = ((OracleResultSet)rs).execute(cmd). you can access and manipulate the BFILE data. // select the bfile locator cmd = "SELECT * FROM my_bfile_table WHERE x = 'two'".data'))". the name of the directory alias is test_dir.sql. you must close the BFILE.execute(). stmt. Then.data is loaded into the bfile column on row two. ops. // for these methods. Several of the methods applied to the BFILE.getBFILE(1). The locator of the BFILE file1. When you finish manipulating the BFILE data. In this example. if (rset. In this case. Methods that manipulate the BFILE data.execute (cmd). Accessing and Manipulating BFILE Data Once you have the BFILE locator in a table. such as reading. null)". oracle. To access and manipulate the data. First get a valid BFILE locator into the bfile object: rs = stmt.executeQuery("SELECT b FROM my_bfile_table WHERE x='two'"). Now row two and row three contain the same BFILE. getting the length. rset = stmt. but wait until later to insert the locator. you can access and manipulate the data to which it points. and displaying. The following code continues the example from the preceding section. As an alternative.* methods can be used on it.

read prefetching. in. int length . LOB data path optimization includes logical cache above storage layer. println("isFileOpen() = " + bfile. SecureFile encryption introduces a new encryption facility that allows for random reads and writes of the encrypted data. System.getName()). and vectored IO. i<length. Close it. provide the following capabilities: ■ ■ SecureFile compression enables users to compress data to save disk space. High performance space management.getBinaryStream(). See Also: Oracle Database SecureFiles and Large Objects Developer's Guide Working with LOBs and BFILEs 14-19 . // get the BFILE data as a binary stream InputStream in = bfile. Oracle SecureFiles In Oracle Database 11g Release 1 (11. // read the bfile data in 6-byte chunks byte[] buf = new byte[6]. for (int i=0. while ((length = in. // we are done working with the BFILE.out. Close it. new caching modes. The new setLobOptions and getLobOptions APIs are described in the PL/SQL Packages and Types Reference. bfile.read(buf)) != -1) { // append and display the bfile data in 6-byte chunks StringBuffer sb = new StringBuffer(length).fileExists()).openFile(). and may be accessed from JDBC through callable statements.close().isFileOpen()). Oracle SecureFiles.1).closeFile().append( (char)buf[i] ). Deduplication enables Oracle database to automatically detect duplicate LOB data and conserve space by storing only one copy of data. a completely redesigned storage for LOBs. } // we are done working with the input stream.println(sb.Oracle SecureFiles println("getName() = " + bfile. ■ ■ ■ These features are implemented in the database and are transparenly available to JDBC programs through the existing APIs. // now open the bfile to get the data bfile. i++) sb. println("fileExists() = " + bfile.toString()).

Oracle SecureFiles 14-20 Oracle Database JDBC Developer's Guide and Reference .

For example. not the object itself. The following topics are discussed: ■ ■ ■ ■ ■ Oracle Extensions for Object References Overview of Object Reference Functionality Retrieving and Passing an Object Reference Accessing and Updating Object Values Through an Object Reference Custom Reference Classes with JPublisher Oracle Extensions for Object References Oracle supports the use of references to database objects. When you select an object reference in Oracle JDBC. an object reference (REF) is strongly typed. Custom Java classes used for object references are referred to as custom reference classes and must implement the oracle. Oracle JDBC provides support for object references as: ■ ■ ■ ■ Columns in a SELECT clause IN or OUT bind variables Attributes in an Oracle object Elements in a collection type object In SQL. Custom reference classes include this same functionality.sql.Ref interface. This can help you find coding errors during compilation that might not otherwise be discovered until run time. which is strongly typed.sql.sql.15 Using Oracle Object References This chapter describes Oracle extensions to standard Java Database Connectivity (JDBC) that let you access and manipulate object references. The REF class includes functionality to get and set underlying object attribute values. The oracle. a reference to an EMPLOYEE object would be defined as an EMPLOYEE REF. and get the SQL base type name of the underlying object. Using Oracle Object References 15-1 . be aware that you are retrieving only a pointer to an object.ORAData interface. and pass an updated REF instance back to the database through a prepared statement or callable statement object. or a java.Ref instance for portability. as well as having the advantage of being strongly typed. You can retrieve a REF instance through a result set or callable statement object.sql. You have the choice of materializing the reference as a weakly typed oracle. or materializing it as an instance of a custom Java class that you have created in advance.REF class implements the standard java. not just a REF.REF instance.sql.

Overview of Object Reference Functionality Note: ■ If you are using the oracle. then you can only use weak Java types for references. even though arrays.REF class methods to retrieve the SQL object type name and retrieve and pass the underlying object data: ■ getBaseTypeName 15-2 Oracle Database JDBC Developer's Guide and Reference . ■ ■ Overview of Object Reference Functionality To access and update object data through an object reference.sql. These methods take as input a String parameter name or int parameter index as well as an oracle. The SQLData interface is for mapping SQL object types only. These methods take as input a String column name or int column index.sql. You can also use the getObject method. This section covers the following topics: ■ ■ Object Reference Getter and Setter Methods Key REF Class Methods Object Reference Getter and Setter Methods You can use the result set. you must obtain the reference instance through a result set or callable statement and then pass it back as a bind variable in a prepared statement or callable statement. are structured types.sql. like objects.sql. callable statement. Key REF Class Methods You can use the following oracle. REF objects can be retrieved either as oracle. You cannot have a reference to an array.Ref instance.sql. You can also use the setObject method.Ref instances. You can create and retrieve REF objects in your JDBC application only by running SQL statements. then you will presumably use ORAData for corresponding custom reference classes as well.sql. There is no JDBC-specific functionality for creating and retrieving REF objects. Prepared and Callable Statement Setter Methods The OraclePreparedStatement and OracleCallableStatement classes support setREF and setRef methods to take REF objects as bind variables and pass them to the database. and prepared statement methods to retrieve and pass object references.ORAData interface for custom object classes.REF instances or java. It is the reference instance that contains the functionality to access and update object attributes.SQLData interface for custom object classes. if you are using the standard java.REF instance or a java.sql. Result Set and Callable Statement Getter Methods The OracleResultSet and OracleCallableStatement classes support getREF and getRef methods to retrieve REF objects as output parameters. However.

col3 REF ADDRESS). To retrieve an object reference. Retrieving and Passing an Object Reference This section discusses JDBC functionality for retrieving and passing object references. Using Oracle Object References 15-3 . It takes an instance of the object type. allowing you to update its attribute values. ■ getValue Retrieves the referenced object from the database. 2. It covers the following topics: ■ ■ ■ Retrieving an Object Reference from a Result Set Retrieving an Object Reference from a Callable Statement Passing an Object Reference to a Prepared Statement Retrieving an Object Reference from a Result Set To demonstrate how to retrieve object references. create table PEOPLE (col1 VARCHAR2(30). house_no NUMBER).executeQuery("SELECT col3 FROM PEOPLE"). enabling you to access its attribute values. col2 NUMBER. the following example first defines an Oracle object type ADDRESS. This method is an Oracle extension. ■ setValue Sets the referenced object in the database. Cast the output to Address. and a column containing a reference to an ADDRESS object. 3. 4. Let Address be the Java custom class corresponding to the SQL object type ADDRESS. Add the correspondence between the Java class Address and the SQL type ADDRESS to your type map. You can use the default type map of the database connection object. is as follows: ResultSet rs = stmt.Retrieving and Passing an Object Reference Retrieves the fully qualified SQL structured type name of the referenced object. This is a standard method specified by the java. except the step of adding Address to the type map. This method is an Oracle extension. follow these general steps: 1. 5. The ADDRESS object type has two attributes: a street name and a house number. The code for the preceding steps. Use a standard SQL SELECT statement to retrieve the reference from a database table REF column. a column for numeric data. which is then referenced in the PEOPLE table: create type ADDRESS as object (street_name VARCHAR2(30).Ref interface.sql. The PEOPLE database table is defined earlier in this section. as input. Use the getValue method to retrieve the contents of the Address reference. Use getREF to get the address reference from the result set into a REF object. It optionally takes a type map object. The PEOPLE table has three columns: a column for character data. either a STRUCT instance or an instance of a custom object class.

if the OUT parameter is a reference to an ADDRESS object. using getREF enables you to avoid casting the output. } Note: In the preceding code. int sql_type.getObject(1). rowid). Cast your callable statement to OracleCallableStatement. Address a = (Address) ref. String sql_type_name). Register the OUT parameter with the following form of the registerOutParameter method: ocs. For example.setREF (1.prepareCall("{? = call func()}").prepareStatement ("update PEOPLE set ADDR_REF = ? where ROWID = ?"). as follows: ocs. For example: REF ref = (REF)rs. stmt is a previously defined statement object. Use either the setObject method or the setREF method of a prepared statement object.setROWID (2. ((OraclePreparedStatement)pstmt).Retrieving and Passing an Object Reference while (rs.next()) { REF ref = ((OracleResultSet)rs). 2. There are no performance advantages in using getObject instead of getREF. 15-4 Oracle Database JDBC Developer's Guide and Reference . As with other SQL types. Passing an Object Reference to a Prepared Statement Pass an object reference to a prepared statement in the same way as you would pass any other SQL type. as follows: OracleCallableStatement ocs = (OracleCallableStatement)conn. Note that this would require you to cast the output. as follows: PreparedStatement pstmt = conn. you could retrieve the reference with the getObject method of your result set.registerOutParameter (int param_index. The sql_type_name is the name of the structured object type that this reference is used for. 3. ((OraclePreparedStatement)pstmt). Run the call. Retrieving an Object Reference from a Callable Statement To retrieve an object reference as an OUT parameter in PL/SQL blocks.execute().getREF(1). then ADDRESS is the sql_type_name that should be passed in.getValue(). Use a prepared statement to update an address reference based on ROWID. you must register the bind type for your OUT parameter. however. param_index is the parameter index and sql_type is the SQL type code. addr_ref). 1.

The ORAData implementation will be used if the JPublisher -usertypes mapping option is set to oracle. If you use JPublisher to generate a custom object class to map to an Oracle object and you specify that JPublisher use a ORAData implementation. but it is also possible to access Oracle object references through custom Java classes or. you can create a Java Address object that corresponds to the database ADDRESS object.executeQuery("SELECT col3 FROM PEOPLE").ORADataFactory interface. For example.REF class.Custom Reference Classes with JPublisher Accessing and Updating Object Values Through an Object Reference You can use the REF object setValue method to update the value of an object in the database through an object reference. you can use the code in "Retrieving and Passing an Object Reference" on page 15-3. which is an alternative for custom object classes. It must provide a way to refer to the object data. to retrieve the reference to a database ADDRESS object. more specifically. Here. is not intended for custom reference classes.next()) { REF ref = rs.sql. A custom reference class must satisfy three requirements: ■ It must implement the oracle. For example. the setValue method updates the database ADDRESS object immediately.sql.sql. Address a = (Address)ref. must implement the oracle. or a companion class.sql. Custom reference classes offer all the functionality described earlier in this chapter. custom reference classes. as follows: Address addr = new Address(. if (rs. Using Oracle Object References 15-5 .ORAData interface.REF attribute. if you accidentally assign some other kind of object reference into an EmployeeRef variable. as well as the advantage of being strongly typed. Using EmployeeRef instances instead of generic oracle. then JPublisher will also generate a custom reference class that implements ORAData and ORADataFactory and includes an oracle. It. Use the setValue method of the REF class to set the value of the database object. which is the default. Note that the standard JDBC SQLData interface. then JPublisher can generate an Employee custom object class and an EmployeeRef custom reference class.getValue(). you must first retrieve the reference to the database object and create a Java object that corresponds to the database object. but the most convenient way to produce them is through the Oracle JPublisher utility. Custom Reference Classes with JPublisher This chapter primarily describes the functionality of the oracle. Custom reference classes are strongly typed.REF instances makes it easier to catch errors during compilation instead of at run time.getREF(1).. JPublisher accomplishes this by using an oracle.REF attribute. To do this. ■ ■ You can create custom reference classes yourself. as follows: ResultSet rs = stmt.. ref. } Then.sql. For example.).sql.setValue(addr). if you define an Oracle object EMPLOYEE. for creating instances of the custom reference class.

For this reason. In this case. then JPublisher will not generate a custom reference class.Custom Reference Classes with JPublisher Be aware that the standard SQLData interface supports only SQL object mappings.Ref instances or oracle. if you instruct JPublisher to implement the standard SQLData interface in creating a custom object class.sql.REF instances to map to your object references. See Also: ■ ■ "Using JPublisher to Create Custom Object Classes" on page 13-30 Oracle Database JPublisher User's Guide 15-6 Oracle Database JDBC Developer's Guide and Reference . your only option is to use standard java.sql.

where you specify a SQL type name to describe a type of collection. collection is more appropriate on the database side and array is more appropriate on the JDBC application side. JDBC enables you to use arrays as any of the following: ■ ■ ■ ■ Columns in a SELECT clause IN or OUT bind variables Attributes in an Oracle object Elements of other arrays This section covers the following topics: ■ ■ ■ Choices in Materializing Collections Creating Collections Creating Multilevel Collection Types Choices in Materializing Collections In your application. maps to an array in Java. or materializing it as an instance of a custom Java class that you have created in advance. either a variable array (VARRAY) or a nested table in the database. The terms collection and array are sometimes used interchangeably. which map to Java arrays.16 Working with Oracle Collections This chapter describes Oracle extensions to standard Java Database Connectivity (JDBC) that let you access and manipulate Oracle collections.0 arrays are used to materialize Oracle collections in Java. Custom Java classes used for collections are referred to as custom collection Working with Oracle Collections 16-1 . Oracle supports only named collections. However. The following topics are discussed: ■ ■ ■ ■ ■ ■ Oracle Extensions for Collections Overview of Collection Functionality ARRAY Performance Extension Methods Creating and Using Arrays Using a Type Map to Map Array Elements Custom Collection Classes with JPublisher Oracle Extensions for Collections An Oracle collection.ARRAY class. you have the choice of materializing a collection as an instance of the oracle. which is weakly typed.sql. which is strongly typed. and their data. JDBC 2.

However. They also have the advantage of being strongly typed.sql. the custom class or a companion class must implement oracle. and the type of that column is a built-in type or an object type. and respond by taking the appropriate actions. If the table is an object type.ORAData interface. retrieve a subset of the array elements. as with the ARRAY class. You must specify a maximum size when you declare the VARRAY type. There is no difference in the code between accessing VARRAYs and accessing nested tables. You can create a nested table as follows: CREATE TYPE myNumList AS TABLE OF integer. This statement identifies myNumList as a SQL type name that defines the table type used for the nested tables of the type INTEGER. In addition.ORADataFactory. all of the same data type. see "Custom Collection Classes with JPublisher" on page 16-13.Oracle Extensions for Collections classes. Each element has an index. A custom collection class must implement the Oracle oracle. It has an ordered set of data elements.sql. The number of elements in a VARRAY is the size of the VARRAY. enable you to retrieve all or part of the array and get the SQL base type name. which can help you find coding errors during compilation that might not otherwise be discovered until run time. A SQL type name is assigned to a collection when you create it using the SQL CREATE TYPE statement: CREATE TYPE <sql_type_name> AS <datatype>. Custom collection classes. A VARRAY is an array of varying size. A nested table is an unordered set of data elements.ARRAY class implements the standard java. and all the elements are of the same data type. you cannot write to the array.SQLData interface is for mapping SQL object types only.sql. and retrieve the SQL base type name of the array elements. The database stores a nested table in a separate table which has a single column. The ARRAY class includes functionality to retrieve the array as a whole. 16-2 Oracle Database JDBC Developer's Guide and Reference . Creating Collections Because Oracle supports only named collections. ARRAY class methods can determine if they are being applied to a VARRAY or nested table.sql. then it can also be viewed as a multi-column table. with individually accessible elements.sql. but categories of types. custom collection classes produced by JPublisher offer the feature of being writable. For example: CREATE TYPE myNumType AS VARRAY(10) OF NUMBER. Furthermore.Array interface. you must declare a particular VARRAY type name or nested table type name. which is a number corresponding to the position of the element in the VARRAY. with a column for each attribute of the object type. Note: See Also: For more information about custom collection classes. The standard java. because there are no setter methods. VARRAY and nested table are not types themselves. This statement defines myNumType as a SQL type name that describes a VARRAY of NUMBER values that can contain no more than 10 elements. The oracle.

ARRAY class. they can be used as both columns of a base table as well as attributes of a object type... ARRAY Performance Extension Methods This section discusses the following topics: ■ Accessing oracle.Statement class.Array interface.execute("CREATE second_level AS TABLE OF first_level"). The oracle. Prepared and Callable Statement Setter Methods The OraclePreparedStatement and OracleCallableStatement classes support setARRAY and setArray methods to take updated ARRAY objects as bind variables and pass them to the database. The following code creates a one-level nested table.sql. // make a database // connection Statement stmt = conn. These methods take as input a String parameter name or int parameter index as well as an oracle.createStatement(). // create a // two-levels nested table .. These methods take as input a String column name or int column index. You can also use the getObject method. provides the necessary functionality to access and update the data of an Oracle collection.execute("CREATE TYPE first_level AS TABLE OF NUMBER").ARRAY instance or a java. Overview of Collection Functionality You can obtain collection data in an array instance through a result set or callable statement and pass it back as a bind variable in a prepared statement or callable statement. Result Set and Callable Statement Getter Methods The OracleResultSet and OracleCallableStatement classes support getARRAY and getArray methods to retrieve ARRAY objects as output parameters. and a two. callable statement.sql. // release the // resource conn. first_level.ARRAY instances or java. // open a database // cursor stmt. either as oracle.ARRAY Elements as Arrays of Java Primitive Types Working with Oracle Collections 16-3 .Array instances. // close the // database connection Once the multilevel collection types have been created.close(). You can also use the setObject method. // other operations here stmt.sql. This section covers Array Getter and Setter Methods.sql.sql. which implements the standard java.ARRAY Performance Extension Methods Creating Multilevel Collection Types The most common way to create a new multilevel collection type in JDBC is to pass the SQL CREATE TYPE statement to the execute method of the java..sql.levels nested table. Use the following result set. and prepared statement methods to retrieve and pass collections as Java arrays.sql. // create a nested // table of number stmt.sql.close(). second_level: Connection conn = .Array instance..

ARRAY Automatic Element Buffering Oracle JDBC driver provides public methods to enable and disable buffering of ARRAY contents.ARRAY class are restricted to numeric collections.sql. These methods allow you to access collection elements more efficiently than accessing them as Datum instances and then converting each Datum instance to its Java primitive value.ARRAY Performance Extension Methods ■ ■ ARRAY Automatic Element Buffering ARRAY Automatic Indexing Accessing oracle.ARRAY class: ■ ■ setAutoBuffering getAutoBuffering It is advisable to enable auto-buffering in a JDBC application when the ARRAY elements will be accessed more than once by the getAttributes and getArray methods. Note: These specialized methods of the oracle.ARRAY Elements as Arrays of Java Primitive Types The oracle. The following methods are included with the oracle.sql. where XXX is a Java primitive type. the oracle. The oracle.ARRAY class contains methods that return array elements as Java primitive types. This data is retained so that a second access of this information does not require going through the data format conversion process. presuming the ARRAY data is able to fit into the Java Virtual Machine (JVM) memory without overflow. auto-indexing is not enabled.ARRAY class contains the following methods to support automatic array-indexing: ■ ■ setAutoIndexing setAutoIndexing By default. ARRAY Automatic Indexing If an array is in auto-indexing mode.sql. When you enable auto-buffering.sql. Each method using the second signature returns a slice of the collection containing the number of elements specified by count. enable auto-indexing for ARRAY objects if random access of array elements may occur through the getArray and getResultSet methods. Important: Buffering the converted elements may cause the JDBC application to consume a significant amount of memory. starting at the index location. then the array object maintains an index table to hasten array element access. For a JDBC application. Each method using the first signature returns collection elements as an XXX[].sql.ARRAY object keeps a local copy of all the converted elements. 16-4 Oracle Database JDBC Developer's Guide and Reference .sql.

typeName is the name of the SQL type of the created object and elements is the elements of the created object. including the following topics. int[]. Create a collection with the CREATE TYPE statement as follows: CREATE TYPE elements AS varray(22) OF NUMBER(5.lang.jdbc.0 method createArrayOf method of java. ■ ■ ■ Creating ARRAY Objects Retrieving an Array and Its Elements Passing Arrays to Statement Objects Creating ARRAY Objects Note: Oracle JDBC does not support the JDBC 4. while all Oracle array types are named. 2. where xxx is the name of a Java class.Creating and Using Arrays Creating and Using Arrays This section discusses how to create array objects and how to retrieve and pass collections as array objects.sql. elements).jdbc. This section covers the following topics: ■ ■ Steps in Creating ARRAY Objects Creating Multilevel Collections Steps in Creating ARRAY Objects Starting from Oracle Database 11g Release 1 (11. For example.lang. The factory method for creating arrays has been defined as follows: public ARRAY createARRAY(java.OracleConnection. This section describes how to create ARRAY objects.createARRAY(sql_type_name. Working with Oracle Collections 16-5 . This method only allows anonymous array types. Use the Oracle specific method createArray of oracle. Construct the ARRAY object by passing the Java string specifying the user-defined SQL type name of the array and a Java object containing the individual elements you want the array to contain.Connection interface.String typeName. For example. An array of Java objects. Perform the following to create an array: 1.OracleConnection interface to create an array object.jdbc. The two possibilities for the contents of elements are: ■ ■ An array of Java primitives.Object elements)throws SQLException where. ARRAY array = oracle.OracleConnection instead.java.2).1). Integer[]. such as xxx[]. you can use the createArray factory method of oracle.

jdbc. then you can get the data with the standard getObject method specified by the java. the elements can be either an array of oracle. 2}}. and then how to retrieve the elements from the ARRAY instance.sql. If you want to avoid casting the result set. {{2}.Creating and Using Arrays Creating Multilevel Collections As with single-level collections. and then send the instance to the database.sql. you can retrieve the data using one of these three overloaded methods of the oracle. while to create a multilevel collection.ARRAY. {{3}. 3}}. The same createArray factory method you use to create single-level collections.Datum Array Accessing Multilevel Collection Elements Retrieving the Array You can retrieve a SQL array from a result set by casting the result set to OracleResultSet and using the getARRAY method.ARRAY class: ■ ■ ■ getArray getOracleArray getResultSet Oracle also provides methods that enable you to retrieve all the elements of an array.sql.sql. {2.ARRAY object. To create a single-level collection.sql. the JDBC application can create an oracle. or a subset. Retrieving an Array and Its Elements This section first discusses how to retrieve an ARRAY instance as a whole from a result set. The following code shows how to create collection types with a nested Java array: // prepare the multi level collection elements as a nested Java array int[][][] elements = { {{1}. {1. {3. // create the ARRAY using the factory method ARRAY array = oracle. 4}} }.createARRAY(sql_type_name. elements).OracleConnection. which returns an oracle.sql. the elements are a one dimensional Java array.ARRAY[] elements or a nested Java array or the combinations. 16-6 Oracle Database JDBC Developer's Guide and Reference . This section covers the following topics: ■ ■ ■ ■ ■ ■ ■ Retrieving the Array Data Retrieval Methods Comparing the Data Retrieval Methods Retrieving Elements of a Structured Object Array According to a Type Map Retrieving a Subset of Array Elements Retrieving Array Elements into an oracle.ResultSet interface and cast the output to oracle. can be used to create multilevel collections as well. Data Retrieval Methods Once you have an ARRAY object.sql.ARRAY instance to represent a multilevel collection.

The elements are of the oracle. another version of the method.sql. The non-character data inside the instance of a Datum class or any of its subclass remains in raw SQL format. The result set contains one row for each array element. getResultSet(map).count) method to get a subset of the array elements. The ResultSet object returned by the method initially points at the first row of data.sql.count) method to retrieve a subset of the array elements.sql. Oracle provides versions of these three methods that enable you to specify a type map so that you can choose how to map the objects to Java. with two columns in each row. the index reflects only the return order of the elements in the particular query. then the use by that method of oracle. If you do not want to use the default type map of the connection. In the case of VARRAYs. Oracle also provides a getArray(index. Nested tables can have an unlimited number of elements. Oracle also provides a getOracleArray(index.count. getArray The getArray method is a standard JDBC method that returns the array elements as a java. The getOracleArray method retrieves the element values of the array into a Datum[] array. You get the contents of the nested table by using the next method and the appropriate getXXX method. In contrast. Comparing the Data Retrieval Methods If you use getOracleArray to return the array elements. which you can cast as appropriate. Working with Oracle Collections 16-7 . Oracle recommends using getResultSet when getting data from nested tables. For an array of structured objects. The first column stores the index into the array for that element.count) and getResultSet(index. The getResultSet method uses the default type map of the connection to determine the mapping between the SQL type of the Oracle object and its corresponding Java data type. enables you to specify an alternate type map. this method will use oracle. getOracleArray The getOracleArray method is an Oracle-specific extension that is not specified in the standard Array interface. and the second column stores the element value.Creating and Using Arrays Note: In case you are working with an array of structured objects.Datum instances avoids the expense of data conversion from SQL to Java. The elements are converted to the Java types corresponding to the SQL type of the data in the original array. getArray returns the entire contents of the nested table at one time.map) methods to retrieve a subset of the array elements. In the case of nested tables.STRUCT instances for the elements. Oracle also provides the getResultSet(index. getResultSet The getResultSet method returns a result set that contains elements of the array designated by the ARRAY object.lang. which are by definition unordered. the index represents the position of the element in the array.Object.* data type corresponding to the SQL type of the data in the original array.

then the Oracle objects in the array will be mapped to their corresponding Java data types according to the default mapping. getResultSet.getArray().BigDecimal. If there are entries in the type map corresponding to the Oracle objects in the array. the result set contains one row for each array element. for each element. If the type map does not contain an entry for a particular Oracle object. Because Oracle JDBC maps numeric SQL data to BigDecimal by default. then the element is returned as an oracle. This is because these methods use the default type map of the connection to determine the mapping. Retrieving Elements of a Structured Object Array According to a Type Map By default. The first column stores the index into the array and the second column stores the element value. the index into the array for the element and the element value. then getArray returns an array of elements of this Java type. because the SQL NUMBER data type maps to Java BigDecimal.Object. Note: Using BigDecimal is a resource-intensive operation in Java. Here intArray is an oracle. then each object in the array is mapped to the corresponding Java type specified in the type map. The return type of the getArray method is java.util.ARRAY. See Also: "Using a Type Map to Map Array Elements" on page 16-12 Retrieving a Subset of Array Elements If you do not want to retrieve the entire contents of an array. Therefore. then you can use the getArray(map) or getResultSet(map) method to specify a type map that contains alternate mappings.sql. if you are working with an array whose elements are structured objects. pass in an index and a count to indicate 16-8 Oracle Database JDBC Developer's Guide and Reference . the result must be cast before it can be used. then the JDBC driver returns a ResultSet object that contains.getArray(map). using getArray may impact performance. However. corresponding to a VARRAY of type NUMBER. and you use getArray or getResultSet. then you can use signatures of getArray.getResultSet(). For example: Object[] object = (Object[])objArray.sql.STRUCT object. with two columns in each row. Where objArray is an oracle.Map object. and is not recommended for numeric collections. if you do not want default behavior. and getOracleArray that let you retrieve a subset.math. The values array contains an array of elements of type java. The getResultSet(map) method behaves similarly to the getArray(map) method. by default.ARRAY object and map is a java.lang. If the elements of an array are of a SQL type that maps to a Java type.sql. For example: ResultSet rset = intArray. according to Oracle JDBC drivers. In this case. To retrieve a subset of the array.Creating and Using Arrays If you use getResultSet to return an array of primitive data types. BigDecimal[] values = (BigDecimal[]) intArray.

map). an array with the SQL type name NUM_ARRAY is created to store a VARRAY of NUMBER data.sql.getResultSet(index.getArray(index. As previously described.sql.execute ("CREATE TABLE varray_table (col1 num_varray)"). ResultSet rset = arr. stmt. count. getARRAY is applied to it to retrieve the array data into my_array.getResultSet(index. ResultSet rs = stmt. you can specify a type map or use the default type map for your connection to convert to Java types.getARRAY(1). A similar example using getOracleArray is: Datum[] arr = arr.ARRAY object.println ("Array is of type " + array. arr is an oracle.sql. In the example. BigDecimal.execute ("CREATE TYPE num_varray AS VARRAY(10) OF NUMBER(12. 2)").ARRAY object. Retrieving Array Elements into an oracle. Similar examples using getResultSet are: ResultSet rset = arr. ARRAY my_array = ((OracleResultSet)rs). count).sql. Because my_array is of type oracle. count). For example: Datum arraydata[] = arr. Where arr is an oracle. and map is a java. the individual values of the array are cast to BigDecimal and printed to standard output.execute ("INSERT INTO varray_table VALUES (num_varray(100.ARRAY. Before you can use the elements. The program then prints the contents of the array. stmt. map).sql. // return the SQL type names.Datum[] array. the elements of my_array are of the type. Working with Oracle Collections 16-9 . The elements of the returned array will be of the oracle. index is type long.executeQuery("SELECT * FROM varray_table"). The NUM_ARRAY is in turn stored in a table VARRAY_TABLE. Because the contents of NUM_ARRAY are of the SQL data type NUMBER. Note: There is no performance advantage in retrieving a subset of an array.sql. integer codes.getOracleArray(index.getOracleArray(). 200))"). In the for loop.Datum Array Use getOracleArray to return an oracle.Creating and Using Arrays where in the array you want to start and how many elements you want to retrieve. stmt. // and lengths of the columns System. The following example assumes that a connection object conn and a statement object stmt have already been created. count).* type that correspond to the SQL data type of the elements of the original array. as opposed to the entire array. they must first be cast to BigDecimal.util. The result set is cast to OracleResultSet.Map object. count. count is type int. A query selects the contents of the VARRAY_TABLE.getArray(index. Object object = arr. which is an oracle.getSQLTypeName()).out. you can apply the methods getSQLTypeName and getBaseType to it to return the name of the SQL type of each element in the array and its integer code. For example: Object object = arr.sql.ARRAY object.

ResultSet rset = stmt. The getResultSet method returns a ResultSet object that wraps the multilevel collection elements.executeQuery ("select col2 from tab2 where idx=1"). The getOracleArray method returns a Datum array that holds the collection elements in Datum format. 16-10 Oracle Database JDBC Developer's Guide and Reference ..out. // make a JDBC connection Statement stmt = conn.println(">> index " + rset. For multilevel collections. Notice the use of the parameter indexes in the getInt method to retrieve the element index and the element value.intValue()). For multilevel collections. These methods are: ■ ■ ■ getArray method getOracleArray method getResultSet method The getArray method returns a Java array that holds the collection elements.createStatement (). The array element type is determined by the collection element type and the JDBC default conversion matrix.getBaseType()).ARRAY elements.getArray(). } Note that if you use getResultSet to obtain the array. System.sql. i<values.. ResultSet rset = my_array.getInt(1)+" = " + rset. i++) { BigDecimal out_value = (BigDecimal) values[i]. The JDBC drivers extend these methods to support multilevel collections. the getArray method returns a java.println ("Array is of length " + array.println ("Array element is of type code " + array. } Accessing Multilevel Collection Elements The oracle. For example.length()). getARRAY. while (rset. and getResultSet methods: Connection conn = .next()) { // The first column contains the element index and the // second column contains the element value System.BigDecimal array for collection of SQL NUMBER. or getArray method of the ResultSet class to access the collection elements as instances of oracle. to access collection elements. the getArray and getOracleArray methods both return a Java array of oracle. which are overloaded. for (int i=0. then you must would first get the result set object. System. getArray.ARRAY. and then use the next method to iterate through it..sql.getResultSet(). while (rset.out.getInt(2)).math.ARRAY class provides three methods.getObject (1). the JDBC applications use the getObject.out.Creating and Using Arrays System.length.sql.println(">> index " + i + " = " + out_value.out. // get Array elements BigDecimal[] values = (BigDecimal[]) my_array. The following code shows how to use the getOracleArray.next()) { ARRAY varray3 = (ARRAY) rset.

you can use arrays as either IN or OUT bind variables.ARRAY object you constructed previously.createARRAY(sql_type_name. Run the prepared statement.Object containing a Java array of the elements. Datum[] varray2Elems = varray2.close (). (OraclePreparedStatement)stmt. parameterIndex is the parameter index and array is the oracle. // access array elements of "varray2" for (int j=0. ResultSet varray1Elems = varray1. i++) { ARRAY varray2 = (ARRAY) varray3Elems[i]. Working with Oracle Collections 16-11 . ARRAY array = oracle.Creating and Using Arrays Object varrayElems = varray3. j++) { ARRAY varray1 = (ARRAY) varray2Elems[j].next()) System.lang.getInt(2)).getOracleArray(). j<varray2Elems.getArray (1). Create a java.jdbc.length. // access array elements of "varray3" Datum[] varray3Elems = (Datum[]) varrayElems. 2. } } } rset.sql. Cast your prepared statement to OraclePreparedStatement. i<varray3Elems.length. and use setARRAY to pass the array to the prepared statement.setARRAY(parameterIndex. // access array elements of "varray1" while (varray1Elems. Define the array that you want to pass to the prepared statement as an oracle.getResultSet().OracleConnection.ARRAY object. Note: 1. array).sql.close (). Passing an Array to a Prepared Statement Pass an array to a prepared statement as follows.PreparedStatement object containing the SQL statement to be run.sql. 3. elements). sql_type_name is a Java string specifying the user-defined SQL type name of the array and elements is a java. 4. for (int i=0.println ("idx="+varray1Elems.out. Passing Arrays to Statement Objects This section discusses how to pass arrays to prepared statement objects or callable statement objects. conn.close (). stmt.getInt(1)+" value="+varray1Elems.

sql. 124)))"). sql_type is the SQL type code.execute("CREATE TYPE EMPLOYEE_LIST AS TABLE OF EMPLOYEE"). stmt. string sql_type_name). 3. as follows: OracleCallableStatement ocs = (OracleCallableStatement)conn. 4. then you can use a type map to associate the objects in the array with the corresponding Java class. int sql_type.STRUCT object.Using a Type Map to Map Array Elements Passing an Array to a Callable Statement To retrieve a collection as an OUT parameter in PL/SQL blocks. stmt. or if the type map does not contain an entry for a particular Oracle object. The example begins by defining an EMPLOYEE object that has a name attribute and employee number attribute. The following example illustrates how you can use a type map to map the elements of an array to a custom Java object class.execute("CREATE TABLE EMPLOYEE_TABLE (DeptName VARCHAR2(20). EMPLOYEE('Scott Tiger'. 123).ARRAY.execute("INSERT INTO EMPLOYEE_TABLE VALUES ("SALES". then each element is returned as an oracle. 1. If you want to retrieve all the employees belonging to the SALES department into an array of instances of the custom object class EmployeeObj. In the EMPLOYEE_TABLE. param_index is the parameter index. Using a Type Map to Map Array Elements If your array contains Oracle objects. Cast your callable statement to OracleCallableStatement. If you want the type map to determine the mapping between the Oracle objects in the array and their associated Java classes. Register the OUT parameter with the following form of the registerOutParameter method: ocs.getARRAY(1). stmt. perform the following to register the bind type for your OUT parameter. the employees are stored in the form of EMPLOYEE_LIST tables.registerOutParameter (int param_index. 16-12 Oracle Database JDBC Developer's Guide and Reference . EMPLOYEE_LIST (EMPLOYEE('Susan Smith'. Employees EMPLOYEE_LIST) NESTED TABLE Employees STORE AS ntable1"). then you must add an entry to the type map to specify mapping between the EMPLOYEE SQL type and the EmployeeObj custom object class. and sql_type_name is the name of the array type. 2. as follows: ocs. stmt.ARRAY array = ocs.prepareCall("{? = call func()}").execute("CREATE TYPE EMPLOYEE AS OBJECT (EmpName VARCHAR2(50).execute(). the sql_type is OracleTypes. If you do not specify a type map. as follows: oracle.EmpNo INTEGER))"). Then an EMPLOYEE_TABLE is created to store the names of departments within a corporation and the employees associated with each department. Run the call. the array is a nested table. In this case. Get the value. In this case. then you must add an appropriate entry to the map.sql. EMPLOYEE_LIST is a nested table type of EMPLOYEE objects.

Custom Collection Classes with JPublisher To do this. as well as the following advantages: ■ They are strongly typed. more specifically. . They can be changeable. You can create custom collection classes yourself. i<employees. create a loop to assign each of the EMPLOYEE SQL objects to the EmployeeObj Java object emp. call the getArray method of the employeeArray array object.sql. first create your statement and result set objects. map. } Custom Collection Classes with JPublisher This chapter primarily describes the functionality of the oracle. allow you to get and set individual elements using the getElement and setElement methods.getARRAY(1)..ARRAY class. Cast the result set to OracleResultSet so you can use the getARRAY method to retrieve the EMPLOYEE_LIST into an ARRAY object (employeeArray in the following example). // Retrieve array elements Object[] employees = (Object[]) employeeArray. To do this. for (int i=0. Now that you have the EMPLOYEE_LIST object.put("EMPLOYEE". The EmployeeObj custom object class in this example implements the SQLData interface. get the existing type map and add an entry that maps the EMPLOYEE SQL type to the EmployeeObj Java type.getTypeMap().getArray().createStatement(). This can help you find coding errors during compilation that might not otherwise be discovered until run time. or mutable.executeQuery ("SELECT Employees FROM employee_table WHERE DeptName = 'SALES'"). retrieve the SQL EMPLOYEE objects from the EMPLOYEE_LIST.forName("EmployeeObj")). but it is also possible to access Oracle collections through custom Java classes or. but the most convenient way is to use the Oracle JPublisher utility. The getArray method returns the EMPLOYEE objects into the employees object array. unlike the ARRAY class. then select the EMPLOYEE_LIST associated with the SALES department into the result set. ■ A custom collection class must satisfy three requirements: Working with Oracle Collections 16-13 . This method returns an array of objects. custom collection classes. // Each array element is mapped to EmployeeObj object. Statement s = conn. Class.. // get the array object ARRAY employeeArray = ((OracleResultSet)rs). Custom collection classes produced by JPublisher. OracleResultSet rs = (OracleResultSet)s.length. Next. Custom collection classes generated by JPublisher offer all the functionality described earlier in this chapter. // add type map entry to map SQL type // "EMPLOYEE" to Java type "EmployeeObj" Map map = conn. i++) { EmployeeObj emp = (EmployeeObj) employees[i]. Finally.

Using MyVarray instances.sql.sql.ARRAY attribute for this purpose. you must use the ORAData implementation. then you would use standard java.sql. which is an alternative for custom object classes.jpub.ARRAY attribute. Note that the standard JDBC SQLData interface. See Also: ■ ■ "Using JPublisher to Create Custom Object Classes" on page 13-30 Oracle Database JPublisher User's Guide 16-14 Oracle Database JDBC Developer's Guide and Reference . or a companion class.sql.sql. The custom collection class will have an oracle.ORADataFactory interface.sql. You cannot use a SQLData implementation for a custom collection class. is not intended for custom collection classes.Custom Collection Classes with JPublisher ■ It must implement the oracle. ■ ■ A JPublisher-generated custom collection class implements ORAData and ORADataFactory and indirectly includes an oracle. As an example of custom collection classes being strongly typed. which is the default. if you define an Oracle collection MYVARRAY. if you accidentally assign some other kind of array into a MyVarray variable. Setting the -usertypes mapping option to jdbc is invalid.sql.sql. makes it easier to catch errors during compilation instead of at run time. then JPublisher can generate a MyVarray custom collection class. instead of generic oracle. Note: When you use JPublisher to create a custom collection class. It. If you do not use custom collection classes.ARRAY attribute. Typically it will directly or indirectly include an oracle.ARRAY instances. to map to your collections. It must have a means of storing the collection data. For example. or oracle.runtime.ORAData interface.ARRAY instances.Array instances. This will be true if the JPublisher -usertypes mapping option is set to oracle. for creating instances of the custom collection class. must implement the oracle.MutableArray attribute. The MutableArray class has an oracle.

positioning.0 Result Set This section provides an overview of JDBC 2. Specify the desired result set type and concurrency type when you create the statement object that will produce the result set. Result Set 17-1 . ■ ■ Scrollability. Updatability is determined by the concurrency type. positioning relatively or absolutely. sensitivity to changes by others. seeing changes to the database made internally or externally. Together.17 Result Set Standard Java Database Connectivity (JDBC) 2. This section covers the following topics: ■ ■ Result Set Functionality and Result Set Categories Supported in JDBC 2. and sensitivity are determined by the result set type.0 Oracle JDBC Implementation Overview for Result Set Enhancements Result Set Functionality and Result Set Categories Supported in JDBC 2. the various result set types and concurrency types provide for six different categories of result set.0 Result Set Creating Scrollable or Updatable Result Sets Positioning and Processing in Scrollable Result Sets Updating Result Sets Fetch Size Refetching Rows Seeing Database Changes Made Internally and Externally Overview of JDBC 2. and some discussion of implementation requirements for Oracle JDBC drivers. such as processing forward or backward.x include enhancements to result set functionality.0 features in Java Development Kit (JDK) 1.2. and updatability.0 Result set functionality in JDBC 2.0 result set functionality and categories. including the following topics: ■ ■ ■ ■ ■ ■ ■ Overview of JDBC 2. and updating result set data and then copying the changes to the database. This chapter discusses these features.0 includes enhancements for scrollability and positioning.

Associated with scrollability is the ability to move to any particular position in the result set. Changes made to the underlying columns values of rows in the result set are visible. but not sensitive to underlying database changes. providing a static view of the underlying data. This includes inserting new rows into the result set or deleting existing rows.0 functionality. Updatability Updatability refers to the ability to update data in a result set and then copy the changes to the database. You would need to retrieve a new result set to see changes made to the database. then you must also specify sensitivity.0 continues to support this through the forward-only result set type. A sensitive result set can see changes made to the database while the result set is open. A forward-only result set cannot be sensitive. JDBC 2. This refers to the ability of a result set to detect and reveal changes made to the underlying database from outside the result set. Under JDBC 2. Result Set Types for Scrollability and Sensitivity When you create a result set under JDBC 2. Absolute positioning enables you to move to a specified row number. Specify the scroll-insensitive type for the result set to be scrollable but not sensitive to underlying changes.0: ■ Forward-only This is a JDBC 1. you must choose a particular result set type to specify whether the result set is scrollable/positional and sensitive to underlying database changes. Positioning. scrollable/positionable result sets are also available.0 functionality. To summarize. Specify the scroll-sensitive type for the result set to be scrollable and sensitive to underlying changes. This type of result set is not scrollable.0 Result Set Scrollability. It is also sensitive to underlying database changes. not positionable. you must also specify sensitivity.0 functionality is all you desire. and Sensitivity Scrollability refers to the ability to move backward as well as forward through a result set. If you want a scrollable result set. Note: The sensitivity of a scroll-sensitive result set is affected by fetch size.Overview of JDBC 2. ■ Scroll-sensitive This type of result set is scrollable and positionable. and not sensitive. ■ Scroll-insensitive This type of result set is scrollable and positionable. providing a dynamic view of the underlying data.0. Relative positioning enables you to move a specified number of rows forward or backward from the current row. 17-2 Oracle Database JDBC Developer's Guide and Reference . the following result set types are available with JDBC 2. When creating a scrollable/positionable result set. An insensitive result set is not sensitive to changes made to the database while the result set is open. counting from either the beginning or the end of the result set. If the JDBC 1. through either relative positioning or absolute positioning.

and for updatability. It is permissible for customers to implement their own client-side caching mechanism.Overview of JDBC 2. Summary of Result Set Categories Because scrollability and sensitivity are independent of updatability. Because you cannot have multiple write locks concurrently. You can only update rows as you iterate through them with the next method. Result Set 17-3 . through use of a client-side cache. Oracle JDBC Implementation Overview for Result Set Enhancements This section discusses key aspects of the Oracle JDBC implementation of result set enhancements for scrollability. Oracle JDBC must implement scrollability in a separate layer. ■ Read-only The result set cannot be modified in any way. Concurrency Types for Updatability The concurrency type of a result set determines whether it is updatable. Although. inserts. and deletes can be performed on the result set and copied to the database. and Oracle provides an interface to use in doing so. Under JDBC 2. updates. the three result set types and two concurrency types combine for a total of six result set categories. through use of ROWIDs. as follows: ■ ■ ■ ■ ■ ■ forward-only/read-only forward-only/updatable scroll-sensitive/read-only scroll-sensitive/updatable scroll-insensitive/read-only scroll-insensitive/updatable Note: A forward-only updatable result set has no positioning functionality.0 Note: Updatability is independent of scrollability and sensitivity. the following concurrency types are available: ■ Updatable In this case. Oracle JDBC Implementation for Result Set Scrollability Because the underlying server does not support scrollable cursors. updatability in a result set is associated with concurrency in database access.0 Result Set Updatability might also require database write locks to mediate access to the underlying database. it is typical for an updatable result set to also be scrollable so that you can position it to particular rows that you want to update or delete. Result sets can optionally be updatable under JDBC 2.0.

/** * Remove all data from the cache. 17-4 Oracle Database JDBC Developer's Guide and Reference . Important: Because all rows of any scrollable result set are stored in the client-side cache. int j) throws IOException. Object value) throws IOException. Oracle JDBC Implementation for Result Set Updatability To support updatability. */ public void clear () throws IOException. */ public Object get (int i. */ public void close () throws IOException. /** * Remove the i-th row. a situation where the result set contains many rows. a forward-only updatable result set will not require a client-side cache. it also supplies an interface. many columns. OracleResultSetCache. For every query into an updatable result set. /** * Return the data stored in the i-th row and j-th column. Note: Client-side caching is not required by updatability in and of itself. Implementing a Custom Client-Side Cache for Scrollability There is some flexibility in how to implement client-side caching in support of JDBC 2. /** * Remove the data stored in i-th row and j-th column */ public void remove (int i. int j.Overview of JDBC 2. In particular. Do not specify scrollability for a large result set. or very large columns might cause the client-side Java Virtual Machine (JVM) to fail. Although Oracle JDBC provides a complete implementation.0 scrollable result sets. int j) throws IOException. that you can implement as desired: public interface OracleResultSetCache { /** * Save the data in the i-th row and j-th column. Oracle JDBC driver automatically retrieves the ROWID along with the columns you select. */ public void put (int i.0 Result Set It is important to be aware that this is accomplished by using a client-side memory cache to store rows of a scrollable result set. */ public void remove (int i) throws IOException. Oracle JDBC uses ROWID to uniquely identify database rows that appear in a result set. /** * Close the cache.

TYPE_SCROLL_INSENSITIVE ResultSet. or OracleCallableStatement object to set the caching mechanism to use your implementation. int resultSetConcurrency) PreparedStatement prepareStatement(String sql. int resultSetType. int resultSetConcurrency) ■ ■ The statement objects created will have the intelligence to produce the appropriate kind of result sets. then your application code must instantiate your class and then use the setResultSetCache method of an OracleStatement. Following is the method signature: void setResultSetCache(OracleResultSetCache cache) throws SQLException Call this method prior to running a query. OraclePreparedStatement. It covers the following topics: ■ ■ Specifying Result Set Scrollability and Updatability Result Set Limitations and Downgrade Rules Specifying Result Set Scrollability and Updatability Under JDBC 2.CONCUR_READ_ONLY ResultSet. You can specify one of the following static constant values for result set type: ■ ■ ■ ResultSet.CONCUR_UPDATABLE Result Set 17-5 . Creating Scrollable or Updatable Result Sets In using JDBC 2.TYPE_SCROLL_SENSITIVE Tip: "Oracle Implementation of Scroll-Sensitive Result Sets" on page 17-19 And you can specify one of the following static constant values for concurrency type: ■ ■ ResultSet. the Connection class has the following methods that take a result set type and a concurrency type as input: ■ Statement createStatement(int resultSetType.0.Creating Scrollable or Updatable Result Sets } If you implement this interface with your own class.0 enhancements.0 result set enhancements.TYPE_FORWARD_ONLY ResultSet. The result set produced by the query will then use your specified caching mechanism. int resultSetConcurrency) CallableStatement prepareCall(String sql. you may specify the result set type and the concurrency type when you create a generic statement or prepare a prepared statement or callable statement that will run a query. This section discusses the creation of result sets to use JDBC 2. int resultSetType.

. you can verify its result set type and concurrency type by calling the following methods on the statement object: ■ ■ int getResultSetType() throws SQLException int getResultSetConcurrency() throws SQLException Prepared Statement Object With Result Set Example 17–1 Following is an example of a prepared statement object that specifies a scroll-sensitive and updatable result set for queries run through that statement: . pstmt. The SQLWarning object will contain the reason why the requested type was not feasible.setString(1.. PreparedStatement pstmt = conn. the query must select all non-nullable columns and all columns that do not have a default value. Failure to follow these guidelines will result in the JDBC driver choosing an alternative result set type or concurrency type. However.prepareStatement ("SELECT empno. Check for warnings to verify whether you received the type of result set that you requested. there is a workaround for this. To produce an updatable result set: ■ A query can select from only a single table and cannot contain any join operations. ■ A query cannot use SELECT * . ResultSet rs = pstmt.executeQuery(). To produce a scroll-sensitive result set: ■ A query cannot use SELECT * . sal FROM emp WHERE empno = ?". Result Set Limitations The following limitations are placed on queries for enhanced result sets. Result Set Limitations and Downgrade Rules Some types of result sets are not feasible for certain kinds of queries. The actual result set type and concurrency type are determined when the statement is run. with the driver issuing a SQLWarning on the statement object if the desired result set type or concurrency type is not feasible.Creating Scrollable or Updatable Result Sets After creating a Statement. then the JDBC driver follows a set of rules to determine the best feasible types to use instead.. ■ A query must select table columns only. such as the SUM or MAX of a set of columns. In addition.TYPE_SCROLL_SENSITIVE. ■ A query can select from only a single table. PreparedStatement. there is a workaround for this. However. for inserts to be feasible.. "28959"). 17-6 Oracle Database JDBC Developer's Guide and Reference . If you specify an unfeasible result set type or concurrency type for the query you run.CONCUR_UPDATABLE). . It cannot select derived columns or aggregates. ResultSet. ResultSet. or CallableStatement object.

CONCUR_UPDATABLE are the possible values. then Oracle JDBC driver uses the following rules in choosing alternate types: ■ If the specified result set type is TYPE_SCROLL_SENSITIVE.TYPE_SCROLL_INSENSITIVE are the possible values. If the specified concurrency type is CONCUR_UPDATABLE. or ResultSet. Result Set Downgrade Rules If the specified result set type or concurrency type is not feasible. by calling methods on the result set object. ResultSet. Note: There is a simple way to determine if your query will probably produce a scroll-sensitive or updatable result set: If you can legally add a ROWID column to the query list. ■ int getConcurrency() throws SQLException This method returns an int value for the concurrency type used for the query. As a result. columns cannot be fetched in bulk and scrolled through. ■ int getType() throws SQLException This method returns an int value for the result set type used for the query. Note: ■ ■ Any manipulations of the result set type and concurrency type by the JDBC driver are independent of each other. then the JDBC driver attempts a downgrade to CONCUR_READ_ONLY. then the driver attempts a downgrade to TYPE_SCROLL_INSENSITIVE. ResultSet. ResultSet. you can verify the result set type and concurrency type that the JDBC driver actually used. as shown in the following example: SELECT t. then the driver attempts a downgrade to TYPE_FORWARD_ONLY. but the JDBC driver cannot fulfill that request. Workaround As a workaround for the SELECT * limitation.. but the JDBC driver cannot fulfill that request.* FROM TABLE t ..TYPE_SCROLL_SENSITIVE. you can use table aliases.Creating Scrollable or Updatable Result Sets Scrollable and updatable result sets cannot have any column as Stream. If the specified or downgraded result set type is TYPE_SCROLL_INSENSITIVE. When the server has to fetch a Stream column. Verifying Result Set Type and Concurrency Type After a query has been run.TYPE_FORWARD_ONLY.CONCUR_READ_ONLY or ResultSet. it reduces the fetch size to one and blocks all columns following the Stream column until the Stream column is read. Result Set 17-7 . then the query is probably suitable for either a scroll-sensitive or an updatable result set. but the JDBC driver cannot fulfill that request.

You are outside the result set bounds after a beforeFirst() call. such as an absolute(11) call if there are 10 rows. If you enter a positive number. or has no effect if there are no rows in the result set. ■ boolean first() throws SQLException Positions to the first row of the result set. Attempting to move forward beyond the last row. ■ void afterLast() throws SQLException Positions to after the last row of the result set. This is where you would typically start iterating through a result set to process it going backward. This method returns false if there are no rows in the result set. This section discusses positioning within a scrollable result set and how to process a scrollable result set backward. Any attempt to position it or to determine the current position will result in a SQLException exception. or has no effect if there are no rows in the result set. instead of forward. It covers the following sections: Positioning in a Scrollable Result Set In a scrollable result set. will position to after the last row. and to position the result set to any desired row. ■ boolean absolute(int row) throws SQLException Positions to an absolute row from either the beginning or end of the result set. There is no valid current row. There is no valid current row.Positioning and Processing in Scrollable Result Sets Positioning and Processing in Scrollable Result Sets Scrollable result sets enable you to iterate through them. you can use several result set methods to move to a desired position and to check the current position. having the same effect as an afterLast() call. and you cannot position relatively from this point. or returns false if there are no rows in the result set. and you cannot position relatively from this point. 17-8 Oracle Database JDBC Developer's Guide and Reference . Methods for Moving to a New Position The following result set methods are available for moving to a new position in a scrollable result set: ■ void beforeFirst() throws SQLException Positions to before the first row of the result set. either forward or backward. then it positions from the end. This is where you would typically start iterating through a result set to process it going forward and is the default initial position for any kind of result set. If you enter a negative number. ■ boolean last() throws SQLException Positions to the last row of the result set. then it positions from the beginning. You are outside the result set bounds after an afterLast() call. or returns false if there are no rows in the result set. Note: You cannot position a forward-only result set.

having the same effect as an afterLast() call. isFirst(). which is the default initial position. isAfterFirst(). ■ boolean isFirst() throws SQLException Returns true if the position is at the first row. The boolean methods. such as an absolute(-11) call if there are 10 rows. calling absolute(-1) is equivalent to calling last(). and isAfterLast(). Note: You cannot position relatively from before the first row. or returns false if there are no rows in the result set. all return false. Attempting to move forward beyond the last row will position to after the last row. Attempting to move backward beyond the first row will position to before the first row. ■ boolean relative(int row) throws SQLException Moves to a position relative to the current row. they do not throw an exception if there are no rows in the result set. isLast(). Attempting relative positioning from either of these positions would result in a SQLException exception. forward if you enter a positive number or backward if you enter a negative number. or returns 0 if there is no valid current row. The result set must be at a valid current row for use of the relative method. ■ boolean isAfterLast() throws SQLException Returns true if the position is after the last row. Methods for Checking the Current Position The following result set methods are available for checking the current position in a scrollable result set: ■ boolean isBeforeFirst() throws SQLException Returns true if the position is before the first row. ■ int getRow() throws SQLException Returns the row number of the current row. having the same effect as a beforeFirst() call. Note: Calling absolute(1) is equivalent to calling first(). or after the last row. ■ boolean isLast() throws SQLException Returns true if the position is at the last row.Positioning and Processing in Scrollable Result Sets Attempting to move backward beyond the first row. will position to before the first row. Also. having the same effect as a beforeFirst() call. A relative(0) call is valid but has no effect. Note: Result Set 17-9 .

For example: .getFloat("sal")). The following methods are available: ■ ■ boolean next() throws SQLException boolean previous() throws SQLException The previous() method works similarly to the next() method. for use in processing a result set..out. Attempting to use the previous() method will cause a SQLException exception. appropriately.. and false as soon as it runs out of rows. To process the entire result set going backward. using the next() method. Unlike relative positioning. but you can call the beforeFirst() method if you have moved elsewhere since the result set was created.afterLast().println(rs. you can process only with the next() method. Presetting the Fetch Direction The JDBC 2..getString("empno") + " " + rs. Backward versus Forward Processing You can process the entire result set going forward. then use the previous() method. that is. is not relevant to this example. in that it returns true as long as the new current row is valid. /* NOTE: The specified concurrency type. */ Statement stmt = conn.createStatement (ResultSet.Positioning and Processing in Scrollable Result Sets Processing a Scrollable Result Set In a scrollable result set you can iterate backward instead of forward as you process the result set. while (rs. 17-10 Oracle Database JDBC Developer's Guide and Reference .previous()) { System. This allows the JDBC driver to optimize its processing.0 standard allows the ability to pre-specify the direction. Note: In a non-scrollable result set. you can use next() from before the first row and previous() from after the last row. sal FROM emp").executeQuery("SELECT empno. which you can specify by entering the ResultSet.FETCH_FORWARD static constant value. ResultSet.. known as the fetch direction. ResultSet rs = stmt. } . The following result set methods are specified: ■ ■ void setFetchDirection(int direction) throws SQLException int getFetchDirection() throws SQLException Oracle JDBC drivers support only the forward preset value.CONCUR_UPDATABLE).TYPE_SCROLL_SENSITIVE. call afterLast(). has passed the first row. You do not have to be at a valid current row to use these methods. The default initial position in the result set is before the first row. rs. CONCUR_UPDATABLE.

the changes are made permanent with the next transaction COMMIT operation. any deleteRow method operation is run and committed immediately. After you perform an UPDATE or INSERT operation in a result set. you propagate the changes to the database in a separate step that you can skip if you want to cancel the changes. Attempting to specify them causes a SQL warning. a DELETE operation in a result set is immediately run. which do not go to a valid current row. Following is the method signature: void deleteRow() throws SQLException Note: Unlike UPDATE and INSERT operations in a result set.. and then delete that row. Result Set 17-11 .FETCH_REVERSE and ResultSet. you can change rows only as you iterate through them with the next() method. the auto-commit flag is set to true. it is typical to also make it scrollable. a DELETE operation in a result set is immediately run in the corresponding row in the database as well. Presuming the result set is also scrollable. Therefore. However. This section covers the following topics: ■ ■ ■ ■ Performing a DELETE Operation in a Result Set Performing an UPDATE Operation in a Result Set Performing an INSERT Operation in a Result Set Avoiding Update Conflicts Performing a DELETE Operation in a Result Set The result set deleteRow method will delete the current row.Updating Result Sets The values ResultSet. except beforeFirst method and afterLast method. Updating Result Sets A concurrency type of CONCUR_UPDATABLE enables you to update rows in the result set. in the database as well. Remember also that by default. which require a separate step to propagate the changes to the database. With a forward-only updatable result set. you can position to a row using any of the available positioning methods. and the settings are ignored.FETCH_UNKNOWN are not supported. This enables you to position to any row that you want to change. or insert rows into the result set. Once you call deleteRow method. Note: When using an updatable result set. but not necessarily committed. unless you override this default.. as in the following example: . delete rows from the result set.

Note: Auto-commit must be disabled to allow a ROLLBACK operation.0f). In a scrollable result set. "mystring"). This will also revert to the original values for that row in the local result set object. Call the updateRow method to copy the changes to the database or the cancelRowUpdates method to cancel the changes. and then update that row as desired. If you choose to cancel the changes before copying them to the database.updateString(1. Following are a couple of examples for a result set rs: rs. and row numbers of subsequent rows are changed accordingly. the changes are run and are made permanent with the next transaction COMMIT operation. you can position to a row using any of the available positioning methods. then call the cancelRowUpdates method instead. Important: The deleted row remains in the result set object even after it has been deleted from the database. . Positioning to a different row before calling updateRow also cancels the changes and reverts to the original values in the result set. 10000. by contrast. Note that once you call the updateRow method. a DELETE operation is evident in the local result set object. which do not go to a valid current row. The row preceding the deleted row becomes the current row. Be aware that by default. Each of these methods takes an int for the column number or a string for the column name and then an item of the appropriate data type to set the new value. rs. 2. Presuming the result set is also scrollable.. the changes are written to the transaction and cannot be canceled unless you roll back the transaction.Updating Result Sets rs. Once you call the updateRow method. rs.0. the auto-commit flag is set to true so that any operation run is committed immediately. With JDBC 2.deleteRow(). 17-12 Oracle Database JDBC Developer's Guide and Reference . except beforeFirst() and afterLast(). a result set object has an updateXXX method for each data type. Performing an UPDATE Operation in a Result Set Performing a result set UPDATE operation requires two separate steps to first update the data in the result set and then copy the changes to the database. Here are the steps for updating a row in the result set and database: 1.updateFloat(2. as with the setXXX methods previously available for updating the database directly. Call the appropriate updateXXX methods to update the data in the columns you want to change..absolute(5). The row would no longer be in the result set after the DELETE.

0f).executeQuery("SELECT empno. The tenth row is updated.absolute(10)) // (returns false if row does not exist) { rs. result set INSERT operations require separate steps to first write the data to the insert-row and then copy it to the database. Following are the steps in running a result set INSERT operation.updateString(1. Note: The result set will remember the current position prior to the moveToInsertRow call. ResultSet rs = stmt. scroll-sensitive. rs. you can call the usual getXXX methods to verify that the values have been updated correctly. Note: Result set UPDATE operations are visible in the local result set object for all result set types. As with UPDATE operations... ResultSet. if (rs.updateString(1. sal FROM emp"). } // Changes are made permanent with the next COMMIT operation. For example: rs. 10000. forward-only.. use the appropriate updateXXX methods to write data to the columns. rs. 2. sal. As with UPDATE operations. "28959").createStatement (ResultSet. Move to the insert-row by calling the result set moveToInsertRow method. rs.updateFloat(2. which is a staging area that holds the data for the inserted row until it is copied to the database. 100000. Result Set 17-13 .. and the column name. The column number is used to specify column 1. is used to specify column 2. You can specify a string for column name. For example: float myfloat = rs. "mystring").CONCUR_UPDATABLE). you can go back to it with a moveToCurrentRow call. Afterward.updateFloat("sal".0f).TYPE_SCROLL_SENSITIVE. 1. instead of an integer for column number. .Updating Result Sets Before calling updateRow. These methods take an int column index or string column name as input. Performing an INSERT Operation in a Result Set Result set INSERT operations use what is called the result set insert-row. and scroll-insensitive. Statement stmt = conn.getFloat(2). // process myfloat to see if it's appropriate . You must explicitly move to this row to write the data that will be inserted.updateRow(). Example Following is an example of a result set UPDATE operation that is also copied to the database.

// Changes will be made permanent with the next COMMIT operation. However. ResultSet rs = stmt.Updating Result Sets Important: Each column value in the insert-row is undefined until you call the updateXXX method for that column. writing the data. Statement stmt = conn.TYPE_SCROLL_SENSITIVE.createStatement (ResultSet. sal. moving to the insert-row. the insert is processed and will be made permanent with the next transaction COMMIT operation. The column number is used to specify column 1. 3. is used to specify column 2..0f)..moveToInsertRow(). and the column name. // Go back to where we came from. and then returning to what was the current row prior to going to the insert-row. sal FROM emp"). .moveToCurrentRow(). These methods take an int column index or string column name as input.. Before calling insertRow you can call the usual getXXX methods to verify that the values have been set correctly in the insert-row. rs.executeQuery("SELECT empno.. Avoiding Update Conflicts It is important to be aware of the following facts regarding updatable result sets with the JDBC drivers: ■ ■ The drivers do not enforce write locks for an updatable result set. Note: No result set type can see a row inserted by a result set INSERT operation. .insertRow(). For example: float myfloat = rs. or else attempting to copy the row into the database will result in a SQLException exception. rs... Positioning to a different row before calling insertRow cancels the insert and clears the insert-row.process myfloat to see if it's appropriate. rs. "28959"). rs. You must call this method and specify a non-null value for all non-nullable columns. Once you call insertRow. Example The following example performs a result set INSERT operation.. 100000. 17-14 Oracle Database JDBC Developer's Guide and Reference ..getFloat(2).updateFloat("sal".. ResultSet. The drivers do not check for conflicts with a result set DELETE or UPDATE operation. it is permissible to not call updateXXX for a nullable column.CONCUR_UPDATABLE). rs. . copying the data into the database. This will result in a value of null.updateString(1. Copy the changes to the database by calling the result set insertRow method..

either explicitly or implicitly. determines the number of rows that are retrieved in any subsequent trips to the database for that result set. the row-prefetch value is used as the default fetch size in a statement object. PreparedStatement. Data can be refetched. you can also set the fetch size in the result set object to override the statement fetch size that was passed to it. This includes any trips that are still required to complete the original query. This is the default Oracle row fetch size value. You can change the number of rows retrieved with each trip to the database cursor by changing the row fetch size value. then N rows are fetched with each trip to the database. either set explicitly. After you have run the query. The driver will not report any changes made by another committed transaction. Only a single write lock can be held concurrently on a data item. CallableStatement.Fetch Size A conflict will occur if you try to perform a DELETE or UPDATE operation on a row updated by another committed transaction. The result set fetch size. This will avoid conflicts. use the Oracle FOR UPDATE feature when running the query that produces the result set. Any conflicts are silently ignored and your changes will overwrite the previous changes. As long as the ROWID is valid when a driver tries to send an UPDATE or DELETE operation to the database. Setting the fetch size overrides the row-prefetch setting and affects subsequent queries run through that statement object. Setting the Fetch Size The following methods are available in all Statement.0 also enables you to specify the number of rows fetched with each database round-trip for a query. call setFetchSize on the statement object prior to running the query. JDBC 2. Oracle JDBC drivers use the ROWID to uniquely identify a row in a database table. When the statement object run a query. but will also prevent simultaneous access to the data. Fetch Size By default. when Oracle JDBC runs a query. and ResultSet objects for setting and getting the fetch size: ■ ■ void setFetchSize(int rows) throws SQLException int getFetchSize() throws SQLException To set the fetch size for a query. the operation will be run. If you set the fetch size to N. and this number is referred to as the fetch size. This will affect any Result Set 17-15 . you can call setFetchSize on the result set object to override the statement object fetch size that was passed to it. Note: Changes made to the fetch size of a statement object after a result set is produced will have no affect on that result set. In Oracle JDBC. to update a scroll-sensitive or scroll-insensitive/updatable result set. To avoid such conflicts. as well as any refetching of data into the result set. it retrieves a result set of 10 rows at a time from the database cursor. or by default equal to the statement fetch size that was passed to it. Fetch size is also used in a result set. the fetch size of the statement object is passed to the result set object produced by the query. However.

It ignores rows that have been inserted. and rows will remain in your result set even after the corresponding rows have been deleted from the database. not outside the row bounds and not at the insert-row. referred to as external changes Note: External changes are referred to as other's changes in the Sun Microsystems JDBC 2. When there is an attempt to refetch a row that has been deleted in the database. referred to as internal changes Changes made from elsewhere. it does nothing about rows that have been inserted or deleted in the database since the original query. Note: If you declare a TYPE_SCROLL_SENSITIVE Result Set based on a query with certain criteria and then externally update the row so that the column values no longer match the query criteria. Because refetching re-obtains only rows that correspond to rows already in your result set. subject to the isolation level of the enclosing transaction. 17-16 Oracle Database JDBC Developer's Guide and Reference . as well as affecting any later refetching of rows. This consists of going back to the database to re-obtain the database rows that correspond to n rows in the result set.Refetching Rows subsequent trips to the database to get more rows for the original query. Refetching Rows The result set refreshRow method is supported for some types of result sets for refetching data. the corresponding row in the result set will maintain its original values. starting with the current row. The refreshRow method is supported for the following result set categories: ■ ■ ■ scroll-sensitive/read-only scroll-sensitive/updatable scroll-insensitive/updatable Note: Scroll-sensitive result set functionality is implemented through implicit calls to refreshRow.0 specification. This lets you see the latest updates to the database that were made outside of your result set. Following is the signature of the refreshRow method: void refreshRow() throws SQLException You must be at a valid current row when you call this method. where n is the fetch size. So. or from other committed transactions. the driver behaves as if the row has been deleted from the database and the row is not retrieved by the query issued. you do not see the updates to the particular row when you call the refreshRow method. either from your own transaction outside the result set. Seeing Database Changes Made Internally and Externally This section discusses the ability of a result set to see the following: ■ ■ Its own changes.

as input. but are not visible for forward-only result sets.TYPE_SCROLL_SENSITIVE.TYPE_SCROLL_INSENSITIVE. ResultSet. However.0 DatabaseMetaData objects include the following methods to verify this: ■ ■ ■ boolean ownDeletesAreVisible(int) throws SQLException boolean ownUpdatesAreVisible(int) throws SQLException boolean ownInsertsAreVisible(int) throws SQLException Each takes a result set type. ■ ■ Internal UPDATE operations are always visible.Seeing Database Changes Made Internally and Externally This section covers the following topics: ■ ■ ■ ■ ■ Seeing Internal Changes Seeing External Changes Visibility versus Detection of External Changes Summary of Visibility of Internal and External Changes Oracle Implementation of Scroll-Sensitive Result Sets Seeing Internal Changes The ability of an updatable result set to see its own changes depends on both the result set type and the kind of change. An internal change being visible essentially means that a subsequent getXXX call will see the data changed by a preceding updateXXX call on the same data item. This is summarized as follows: ■ Internal DELETE operations are visible for scrollable result sets. Changes from external DELETE or INSERT operations are never visible. and subsequent row numbers are updated accordingly. Note: When you make an internal change that causes a trigger to run. JDBC 2. the trigger changes are effectively external changes. regardless of the result set type. regardless of the result set type. or ResultSet. and it can only see the changes from external UPDATE operations. Internal INSERT operations are never visible. if the trigger affects data in the row you are updating. ResultSet. JDBC 2. Seeing External Changes Only a scroll-sensitive result set can see external changes to the underlying database. Note: Any discussion of seeing changes from outside the enclosing transaction presumes the transaction itself has an isolation level setting that allows the changes to be visible.0 DatabaseMetaData objects include the following methods to verify this: ■ boolean othersDeletesAreVisible(int) throws SQLException Result Set 17-17 .TYPE_FORWARD_ONLY. because an implicit row refetch occurs after the update. then you will see those changes for any scrollable/updatable result set. the preceding row becomes the new current row. After you delete a row in a scrollable result set.

For example. ResultSet.0 to detect changes.TYPE_SCROLL_INSENSITIVE. there are two similar but distinct concepts with respect to visibility of the changes from your local result set: ■ ■ Visibility of changes Detection of changes A change being "visible" means that when you look at a row in the result set. Note: Explicit use of the refreshRow method is distinct from this discussion of visibility. Such changes are not detected. as input.0 DatabaseMetaData objects include the following methods to verify this: ■ ■ ■ boolean deletesAreDetected(int) throws SQLException boolean updatesAreDetected(int) throws SQLException boolean insertsAreDetected(int) throws SQLException Each takes a result set type. ResultSet. A change being "detected". ResultSet.Seeing Database Changes Made Internally and Externally ■ ■ boolean othersUpdatesAreVisible(int) throws SQLException boolean othersInsertsAreVisible(int) throws SQLException Each takes a result set type. and changes made externally to the underlying database from elsewhere in your transaction or from other committed transactions. or ResultSet. JDBC 2.TYPE_FORWARD_ONLY. that result set methods specified by JDBC 2. even though external updates are invisible to a scroll-insensitive result set. rowUpdated. It follows. Even when an Oracle result set sees new data. means that the result set is aware that this is a new value since the result set was first populated. Visibility versus Detection of External Changes Regarding changes made to the underlying database by external sources. as with an external UPDATE in a scroll-sensitive result set. ResultSet.TYPE_FORWARD_ONLY. you can see new data values from changes made by external sources to the corresponding row in the database. then.TYPE_SCROLL_SENSITIVE. will always return false. Visibility refers only to the fact that the scroll-insensitive/updatable result set would not see such changes automatically and implicitly. it has no awareness that this data has changed since the result set was populated. rowDeleted.TYPE_SCROLL_SENSITIVE. however. 17-18 Oracle Database JDBC Developer's Guide and Reference .TYPE_SCROLL_INSENSITIVE. There is no use in calling them. as input. you can explicitly refetch rows in a scroll-insensitive/updatable result set and retrieve external changes that have been made. or ResultSet. and rowInserted. Summary of Visibility of Internal and External Changes Table 17–1 summarizes the discussion in the preceding sections regarding whether a result set object in the Oracle JDBC implementation can see changes made internally through the result set itself.

They are only visible after the automatic refetches just described. and therefore no window. The result set rowDeleted. they are not detected. there are significant performance concerns. and rowInserted methods always return false. this would have a significant impact on the performance of your application. Whenever the window is redefined. when a result set is first created. the N rows in the database corresponding to the rows in the new window are automatically refetched through an implicit call to the refreshRow method. as with UPDATE operations underlying a scroll-sensitive result set. There is also a significant trade-off between sensitivity and performance. Result Set 17-19 . is distinct from the concept of visibility of external changes. ■ Oracle Implementation of Scroll-Sensitive Result Sets The Oracle implementation of scroll-sensitive result sets involves the concept of a window. The most sensitive result set is one with a fetch size of 1. once you move to a new current row outside the window. the window consists of the n rows in the result set starting with that row. where n is the fetch size being used by the result set. Consider carefully before using scroll-sensitive result sets as currently implemented. rowUpdated. Remember that even when external changes are visible.Seeing Database Changes Made Internally and Externally Table 17–1 Visibility of Internal and External Changes for Oracle JDBC Can See Can See Can See Internal Internal Internal DELETE? UPDATE? INSERT? no yes yes yes yes yes no no no Can See Can See External External DELETE? UPDATE? no no no no yes no Can See External INSERT? no no no Result Set Type forward-only scroll-sensitive scroll-insensitive Note: ■ Remember that explicit use of the refreshRow method. Note: Because this kind of refetching is not a highly efficient or optimized methodology. However. Note that there is no current row. However. which would result in the new current row being refetched every time you move between rows. the window remains unchanged as long as the current row stays within that window. with a window size that is based on the fetch size. As you move from row to row. The default position is before the first row. Once you establish a current row by moving to a specified row. you redefine the window to be the N rows starting with the new current row. which is not a valid current row. So external updates are not instantaneously visible in a scroll-sensitive result set. thereby updating the data throughout the new window. The window size affects how often rows are updated in the result set.

Seeing Database Changes Made Internally and Externally 17-20 Oracle Database JDBC Developer's Guide and Reference .

0 Javadoc at: http://java. with a standard set of properties and an event notification mechanism.sun.com/j2se/1.0/docs/api/ Java SE 6. The Java SE Javadocs provide information about the standard interfaces and base classes for JDBC RowSet implementations.com/javase/6/docs/api/ ■ ■ Note: In case of any conflict.0 Javadoc. The JSR-114 specification includes implementation details for five types of RowSet: JDBC RowSets 18-1 . the JSR-114 specification takes precedence over the JDK 5.18 JDBC RowSets This chapter contains the following sections: ■ ■ ■ ■ ■ ■ Overview of JDBC RowSets CachedRowSet JdbcRowSet WebRowSet FilteredRowSet JoinRowSet Overview of JDBC RowSets A RowSet is an object that encapsulates a set of rows from either java Database Connectivity (JDBC) result sets or tabular data sources. National Language Charactersets.sun.org/en/jsr/detail?id=114 Java SE 5.5. Standard Edition (Java SE) 5. Java SE 6. the implementation of RowSets was standardized in the JDBC RowSet Implementations Specification (JSR-114).0 through the optional packages. However. and so on.0 Javadoc at: http://java. See Also: ■ JSR-114 specification at: http://jcp. RowSets support component-based development models like JavaBeans. RowSets were introduced in JDBC 2. which is available as non-optional package since Java Platform.0 RowSets contain more APIs supporting features like RowId.0.

jar or ojdbc6.jar.1).5.rowset package.1).rowset package. for example. ojdbc5_g.0/docs/api/javax/sql/RowSet. RowSets support was not available in the server-side drivers.rowset package or specific classes and interfaces from the package for the required RowSet type.jar file. password.sql. This section covers the following topics: ■ ■ ■ ■ RowSet Properties Events and Event Listeners Command Parameters and Command Execution Traversing RowSets RowSet Properties The javax.RowSet at http://java. ■ ■ ■ To use the Oracle RowSet implementations. Oracle Database 11g Release 1 (11. starting from Oracle Database 11g Release 1 (11.com/j2se/1.jdbc. you need to import either the entire oracle.sql.2). and the query string. ojdbc5dms.2). the implementation classes were packaged in the ocrs12.jdbc. Prior to Oracle Database 11g Release 1 (11. Standard Edition (J2SE) Javadoc for javax. For client-side usage.jar file.jar.sun. the implementation classes were packaged in the ojdbc14.html 18-2 Oracle Database JDBC Developer's Guide and Reference . Note: ■ The other JAR files with different file suffix names. Prior to Oracle Database 10g release 2 (10. In Oracle Database 10g release 2 (10. For a complete list of properties and property descriptions.Overview of JDBC RowSets ■ ■ ■ ■ ■ CachedRowSet JdbcRowSet WebRowSet FilteredRowSet JoinRowSet Oracle JDBC supports all five types of RowSets through the interfaces and classes present in the oracle. The standard Oracle JDBC Java Archive (JAR) files. Example of properties are connection string.jar in the CLASSPATH environment variable. user name.RowSet interface provides a set of JavaBeans properties that can be altered to access the data in the data source through a single interface. Therefore. type of connection. RowSets support is uniform across all Oracle JDBC driver types.jdbc. and so on also contain the oracle. ojdbc5. refer to the Java2 Platform.jdbc.jar contain the oracle. See Also: "Check the Environment Variables" on page 2-3 for information about setting the CLASSPATH environment variable. you also need to include the standard Oracle JAR files like ojdbc5.rowset package.1) adds RowSets support in the server-side drivers.jar and ojdbc6. for example.

. or deleted from the RowSet. MyRowSetListener rowsetListener = new MyRowSetListener (). and salary of all the employees into the RowSet object. the URL.. which are interested in these events. The following types of events are supported by the RowSet interface: ■ cursorMoved This event is generated whenever there is a cursor movement. employee name. For example. The following code illustrates a listener implementation: public class MyRowSetListener implements RowSetListener { public void cursorMoved(RowSetEvent event) { // action on cursor movement } public void rowChanged(RowSetEvent event) { // action on change of row } JDBC RowSets 18-3 .removeRowSetListener method.. user name.setPassword("TIGER").. when the execute method is called. and SQL query are set as the RowSet properties to retrieve the employee number. Multiple listeners can be registered with the same RowSet object. .Overview of JDBC RowSets The interface provides standard accessor methods for setting and retrieving the property values. A listener can be registered using the RowSet.addRowSetListener (rowsetListener). . An application component can implement a RowSet listener to listen to these RowSet events and perform desired operations when the event occurs. rowset. when the next or previous method is called. password..setUsername("SCOTT").RowSetListener interface and register such listener objects with a RowSet object. sal FROM emp").. // adding a rowset listener rowset. rowset. Application components.setCommand("SELECT empno.sql. For example. ename. ■ rowChanged This event is generated when a row is inserted. rowset. Events and Event Listeners RowSets support JavaBeans events. The following code illustrates setting some of the RowSet properties: . rowset.addRowSetListener method and unregistered using the RowSet. must implement the standard javax. ■ rowSetChanged This event is generated when the whole RowSet is created or changed... updated. The following code illustrates the registration of a RowSet listener: .setUrl("jdbc:oracle:oci:@"). In this example.

which when processed would populate the RowSet object with actual data.RowSet interface extends the java. After the required input parameters are set.setCommand("SELECT ename..setInt(1.sql. In the following code.addRowSetListener(new oracle. The RowSet interface provides an optional way to implement a 18-4 Oracle Database JDBC Developer's Guide and Reference . next..OracleRowSetListenerAdapter () { public void rowSetChanged(RowSetEvent event) { // your action for rowSetChanged } } ). sal FROM emp WHERE empno = ?").. rowset. beforeFirst. for traversing through data in a RowSet object. afterLast. The javax.rowset. the RowSet object is filled with the employee name and salary information of the employee whose employee number is 7839. the employee number 7839 is set as the input or bind parameter for the SQL query specified in the command property of the RowSet object. The RowSet interface can be used just like a ResultSet interface for retrieving and updating data. while the remaining events are not handled by the application: . and previous.execute(). Like in regular JDBC processing. .RowSet interface also provides methods for setting input parameters to this SQL query.sql.Overview of JDBC RowSets public void rowSetChanged(RowSetEvent event) { // action on changing of rowset } }// end of class MyRowSetListener Applications that need to handle only selected events can implement only the required event handling methods by using the oracle.ResultSet interface.jdbc.sql. the SQL query can be processed to populate the RowSet object with data from the underlying data source. . which are inherited from the ResultSet interface. The following code illustrates this simple sequence: .. // setting the employee number input parameter for employee named "KING" rowset.rowset. In the preceding example.. which is an abstract class with empty implementation for all the event handling methods. 7839). The RowSet interface. When the SQL query is processed. therefore. provides cursor movement and positioning methods. this query string can take input or bind parameters... Traversing RowSets The javax. rowset. Command Parameters and Command Execution The command property of a RowSet object typically represents a SQL query string.. only the rowSetChanged event is handled. rowset.OracleRowSetListenerAdapter class.jdbc. Some of the inherited methods are absolute.

ename.ResultSet interface. /** * Make rowset updatable */ rowset. 193).setCommand("SELECT empno.getInt (1)). and printing the empno in * the reverse order as it was fetched..previous ()) System. and deleting rows are supported by the Row Set feature as they are in the Result Set feature. rowset.out. /** * Inserting a row in the 5th position of the rowset. The rows are retrieved in reverse direction using the previous method of RowSet.. while (rowset.execute().out. In the preceding code.sql. Note: The following code illustrates how to scroll through a RowSet: /** * Scrolling forward. sal FROM emp")..next ()) System. // going to the first row of the rowset rowset.. updating.. The rows are retrieved in forward direction using the next method. In the preceding code. rowset.moveToInsertRow (). and printing the empno in * the order in which it was fetched. you must call the setReadOnly(false) and acceptChanges methods.println ("empno: " +rowset.getInt (1)). rowset.setReadOnly (false). Inserting.updateInt (1. the cursor position is initialized to the position after the last row of the RowSet. JDBC RowSets 18-5 .afterLast ().absolute(5)) { rowset. All the fields and methods provided by the ResultSet interface are implemented in RowSet.beforeFirst ().Overview of JDBC RowSets scrollable and updatable result set. The Oracle implementation of ResultSet provides the scrollable and updatable properties of the java. In order to make the Row Set updatable. The following code illustrates the insertion of a row at the fifth position of a Row Set: . the cursor position is initialized to the position before the first row of the RowSet by the beforeFirst method. */ .println ("empno: " +rowset. while (rowset. */ // moving the cursor to the 5th position in the rowset if (rowset. .. The following code illustrates how to scroll through a RowSet in the reverse direction: /** * Scrolling backward. */ //going to the last row of the rowset rowset.

rowset. The oracle.CachedRowSet.updateInt (3.. an OracleCachedRowSet object is created and the connection URL. that is. user name. rowset.insertRow (). scroll.out.getInt (1)).. System. 18-6 Oracle Database JDBC Developer's Guide and Reference . "Ashok"). which is the connection URL.sql. rowset.. The changes are committed through acceptChanges method. the insertRow is called to update the RowSet. To populate a CachedRowSet object with a query. insert. a call to the absolute method with a parameter 5 takes the cursor to the fifth position of the RowSet and a call to the moveToInsertRow method creates a place for the insertion of a new row into the RowSet. 7200). It can interoperate with the reference implementation of Sun Microsystems. } . password.sql.jdbc.println("ename: " +rowset. CachedRowSet A CachedRowSet is a RowSet in which the rows are cached and the RowSet is disconnected. Username. rowset.ResultSet object to retrieve. delete.rowset.next ()) { System. properties for the RowSet object. In the following code. In the preceding code.getInt (3)). but it is optional. The OracleCachedRowSet class in the ojdbc5.. which is the query string. rowset.jar files implements the standard JSR-114 interface javax. // inserting a row in the rowset rowset. Call the execute method to populate the CachedRowSet object.getString (2)). } .println("sal: " +rowset. rowset. Instantiate OracleCachedRowSet.rowset. Password.execute().out. and the SQL query for the RowSet object is set as properties. // Synchronizing the data in RowSet with that in the database.println("empno: " +rowset. When all the columns of the row are updated. RowSet rowset = new OracleCachedRowSet(). while (rowset. . and Command.setUsername("SCOTT"). 3. The RowSet object is populated using the execute method. complete the following steps: 1. You can also set the connection type. rowset.acceptChanges ().CachedRowSet rowset. After the execute method has been processed.updateString (2. or update data. ename. sal FROM emp").setCommand("SELECT empno. the RowSet object can be used as a java.setUrl("jdbc:oracle:oci:@").. 2.OracleCachedRowSet class is the Oracle implementation of CachedRowSet.setPassword("TIGER"). System. The updateXXX methods are used to update the newly created row.jar and ojdbc6.. it does not maintain an active connection to the database. Calling execute runs the query set as a property on this RowSet. Set the Url.out.

rowset. istream.setPassword ("TIGER"). a FileOutputStream object is opened for an emp_tab. fileInputStream.populate (rset).close(). Pass the already available ResultSet object to the populate method to populate the RowSet object. A CachedRowSet object can be populated with an existing ResultSet object. ostream. a ResultSet object is obtained by running a query and the retrieved ResultSet object is passed to the populate method of the CachedRowSet object to populate the contents of the result set into the CachedRowSet. like transaction isolation or the concurrency mode of the result set.close(). because the connection or result set on which the property applies would have already been created. rowset. and the populated OracleCachedRowSet object is written to the file using JDBC RowSets 18-7 . ObjectOutputStream ostream = new ObjectOutputStream(fileOutputStream). rowset. Instantiate OracleCachedRowSet. ename.readObject(). ostream.setUrl ("jdbc:oracle:oci:@"). ObjectInputStream istream = new ObjectInputStream(fileInputStream).close(). // Executing a query to get the ResultSet object. The following code illustrates how an OracleCachedRowSet object is serialized to a file and then retrieved: // writing the serialized OracleCachedRowSet object { FileOutputStream fileOutputStream = new FileOutputStream("emp_tab. To do so.dmp"). } // reading the serialized OracleCachedRowSet object { FileInputStream fileInputStream = new FileInputStream("emp_tab.CachedRowSet OracleCachedRowSet rowset = new OracleCachedRowSet ().executeQuery (). rowset.writeObject(rowset). rowset.setUsername ("SCOTT").execute ().close(). ResultSet rset = pstmt.dmp file. rowset. using the populate method.dmp"). RowSet rowset1 = (RowSet) istream. // the obtained ResultSet object is passed to the populate method // to populate the data in the rowset object. Note: Connection properties. fileOutputStream. } In the preceding code. and the bind properties cannot be set in the case where a pre-existent ResultSet object is used to populate the CachedRowSet object. 2. In the preceding example. OracleCachedRowSet rowset = new OracleCachedRowSet (). complete the following steps: 1.setCommand ("SELECT empno. sal FROM emp").

binary large objects (BLOBs). OutputStream.getColumnCount(). . scrolling.. This architecture would be suitable for systems involving a Thin client like a Personal Digital Assistant (PDA).CachedRowSet ObjectOutputStream.getColumnName(i)). if new rows are to be inserted: ■ ■ Selects all non-nullable columns in the underlying table Selects all columns that do not have a default value 18-8 Oracle Database JDBC Developer's Guide and Reference . Once the OracleCachedRowSet class is populated. as done in Remote Method Invocation (RMI). for (int i = 1. which can be passed over the network using RMI or any other suitable architecture.. Whenever data is committed to the database.. which could be obtained without any extra server round-trip. The following code illustrates how you can obtain metadata for the RowSet: .println("Column (" + i +") " + metaData. or any environment that does not have JDBC drivers. the acceptChanges method is called. ResultSetMetaData metaData = rowset.. ++i) System. After populating the CachedRowSet object. inserting. and character large objects (CLOBs).out. it can be passed across a network or between Java Virtual Machines (JVMs). Some of the other key-features of CachedRowSet are the following: ■ ■ ■ Cloning a RowSet Creating a copy of a RowSet Creating a shared copy of a RowSet CachedRowSet Constraints All the constraints that apply to an updatable result set are applicable here. The SQL query has the following constraints: ■ ■ ■ References only a single table in the database Contains no join operations Selects the primary key of the table it references In addition. This method makes use of JDBC drivers. it can be used as a ResultSet object or any other object.getMetaData(). because OracleCachedRowSet is serializable. updating. The complete process of retrieving the data and populating it in the OracleCachedRowSet class is performed on the server and the populated RowSet is passed on to the client using suitable architectures like RMI or Enterprise Java Beans (EJB). OracleCachedRowSets also implements metadata of its own. int maxCol = metaData. which require the JVM environment to contain JDBC implementation. it can move around any JVM. OracleCachedRowSet takes care of the serialization of non-serializable form of data like InputStream. Because the OracleCachedRowSet class is serializable. and deleting on the RowSet without any connection to the database. The serialized OracleCachedRowSet object is retrieved using the FileInputStream and ObjectInputStream objects. except serialization. a SQL query should also satisfy the following conditions. i <= maxCol. Committing the data in the RowSet requires the presence of JDBC drivers. which synchronizes the data in the RowSet to that in the database. The client would be able to perform all the operations like retrieving.

out. The Oracle implementation of JdbcRowSet is oracle. recommends against using OracleCachedRowSet with queries that could potentially return a large volume of data. transaction isolation and concurrency mode of the result set.jar and ojdbc6.getInt(1)).. Connection properties like.getInt(3)). rowset. Table 18–1 The JDBC and Cached Row Sets Compared Connected Movable to Across Database JVMs Yes No No Yes Synchronization Presence of data to of JDBC database Drivers No Yes Yes No RowSet Type JDBC Cached Serializable Yes Yes JdbcRowSet is a connected RowSet.JdbcRowSet.OracleJDBCRowSet.. } . because the properties cannot be applied to the connection after retrieving the data from the same. JdbcRowSet A JdbcRowSet is a RowSet that wraps around a ResultSet object.. ename. rowset.println("sal: " + rowset. The following code illustrates how a JdbcRowSet is used: . It is a connected RowSet that provides JDBC interfaces in the form of a JavaBean interface.setCommand("SELECT empno. Oracle. The OracleJDBCRowSet class in ojdbc5.setPassword("TIGER"). A CachedRowSet does not have any connection to the database open. therefore. RowSet rowset = new OracleJDBCRowSet().rowset. rowset. System. statement.. which has a live connection to the database and all the calls on the JdbcRowSet are percolated to the mapping call in the JDBC connection. because all the data is cached in memory. rowset. while (rowset. both JdbcRowSet and CachedRowSet require JDBC drivers during population of the RowSet and while committing the changes of the RowSet.jdbc.getString(2)).rowset.jar implements the standard JSR-114 interface javax. JdbcRowSet requires the presence of JDBC drivers unlike a CachedRowSet. or result set.execute(). which does not require JDBC drivers during manipulation.setUsername("SCOTT").JdbcRowSet Note: The CachedRowSet cannot hold a large quantity of data.setUrl("java:oracle:oci:@"). cannot be set after populating the RowSet.out. System.sql.println("empno: " + rowset. rowset. Table 18–1 shows how the JdbcRowSet interface differs from CachedRowSet interface.out. JDBC RowSets 18-9 . sal FROM emp"). However.next()) { System.println("ename: " + rowset.

WebRowSet. which is initialized with the default values for an OracleCachedRowSet object.OracleCachedRowSet class. Besides the methods available in OracleCachedRowSet. which is at: http://java. the properties and metadata of the RowSet are written. Both Simple API for XML (SAX) 2.sun.io. It follows the current JSR-114 W3C XML schema for WebRowSet from Sun Microsystems. public void readXml(java.io. password.io. This class also extends the oracle.Writer writer) throws SQLException public void writeXml(ResultSet rset. and the rows are retrieved and printed by traversing through the data populated in the RowSet object. The Oracle WebRowSet implementation supports Java API for XML Processing (JAXP) 1.io. and a default OracleWebRowSetXmlWriter. The Oracle implementation of WebRowSet is oracle. public void writeXml(java. the SQL query is processed using the execute method.io.Reader reader) throws SQLException public void readXml(java.jar files.InputStream istream) throws SQLException These methods read the OracleWebRowSet object in the XML format according to its JSR-114 XML schema. java.jdbc.sql. This allows result sets to be shipped across tiers and over Internet protocols. using the supplied Reader or InsputStream object. and SQL query are set as properties of the RowSet object. both in Extensible Markup Language (XML) format and in disconnected fashion.jar and ojdbc6. java.jdbc. and write it to the supplied Writer or OutputStream object in the XML format that conforms to the JSR-114 XML schema.OutputStream ostream) throws SQLException These methods write the OracleWebRowSet object to the supplied Writer or OutputStream object in the XML format that conforms to the JSR-114 XML schema.rowset. user name.xsd 18-10 Oracle Database JDBC Developer's Guide and Reference . the connection URL. This class.io. WebRowSet A WebRowSet is an extension to CachedRowSet.rowset.0 and Document Object Model (DOM) JAXP-conforming XML parsers are supported.2. In addition to the RowSet data.com/xml/ns/jdbc/webrowset. The WebRowSet interface provides support for the production and consumption of result sets and their synchronization with the data source. a default OracleWebRowSetXmlReader. implements the standard JSR-114 interface javax. the OracleWebRowSet class provides the following methods: public OracleWebRowSet() throws SQLException This is the constructor for creating an OracleWebRowSet object. populate it with the data in the given ResultSet object. It represents a set of fetched rows or tabular data that can be passed between tiers and components in a way such that no active connections with the data source need to be maintained.OracleWebRowSet. which is in the ojdbc5.OutputStream ostream) throws SQLException These methods create an OracleWebRowSet object.Writer writer) throws SQLException public void writeXml(java.WebRowSet In the preceding example. public void writeXml(ResultSet rset.rowset.

import java.getConnection(url.0 Javadoc at: http://java.out. wset.WebRowSet See Also: ■ JSR-114 specification at: http://jcp. // Now generate the XML and write it out wset.com/j2se/1.org/en/jsr/detail?id=114 Java SE 5.5.. } System. ■ javax."oracle.SAXParserFactory This property is for a SAX parser..*.writeXml(out).. try { // Create a java. The following code illustrates the use of OracleWebRowSet for both writing and reading in XML format: import java.xml.io.xml.parsers.Writer object FileWriter out = new FileWriter("xml.println("XML output file generated.io.sql. Statement stmt = conn.) methods should set one of the following two standard JAXP system properties before calling the methods: ■ javax.*."). // Create a new OracleWebRowSet for reading from XML input OracleWebRowSet wset2 = new OracleWebRowSet().xml.println("Couldn’t construct a FileWriter").sun.rowset.SAXParserFactory".parsers.out").DocumentBuilderFactory This property is for a DOM parser.JXSAXPars erFactory").0/docs/api/ Java SE 6.createStatement()."scott".setProperty("javax. } catch (IOException exc) { System. .populate(rset). Connection conn = DriverManager.xml.jdbc.out. String url = "jdbc:oracle:oci8:@".jaxp. ResultSet rset = stmt.com/javase/6/docs/api/ ■ ■ Applications that use the readXml(.0 Javadoc at: http://java.parsers. // Use Oracle JAXP SAX parser System."tiger"). // Create an OracleWebRowSet object and populate it with the ResultSet object OracleWebRowSet wset = new OracleWebRowSet()..sun. try JDBC RowSets 18-11 .*. import oracle.executeQuery("select * from emp").

and modifying rows. public void setFilter(Predicate p) throws SQLException. Also. A new filtering criteria can be applied only if there are no reference to the OracleFilteredRowSet object. Note: The preceding code uses the Oracle SAX XML parser..FilteredRowSet { // Use the preceding output file as input FileReader fr = new FileReader("xml. only the rows that fall within the bounds of the filtering criteria will be synchronized with the data source.jar and ojdbc6. The set filtering criteria acts as a gating mechanism for all views and updates to the OracleFilteredRowSet object. The predicate also defines the criteria for inserting. which supports schema validation.println("Couldn’t construct a FileReader")..OracleFilteredRowSet.out"). This method takes a Predicate object as a parameter. Any attempt to update the OracleFilteredRowSet object. and all further views and updates must adhere to this new criteria. } . The Oracle implementation of FilteredRowSet is oracle.out.sql. This enables you to avoid the overhead of supplying a query and the processing involved.jar files implements the standard JSR-114 interface javax.rowset. // Now read XML stream from the FileReader wset2. The methods throws a SQLException exception. throws a SQLException exception. which violates the filtering criteria. The predicate set on an OracleFilteredRowSet object defines a filtering criteria that is applied to all the rows in the object to obtain the set of visible rows. FilteredRowSet A FilteredRowSet is an extension to WebRowSet that provides programmatic support for filtering its content. The filtering criteria set on an OracleFilteredRowSet object can be modified by applying a new Predicate object.rowset. The OracleFilteredRowSet class in the ojdbc5. The Predicate object defines the filtering criteria to be applied on the OracleFilteredRowSet object. The OracleFilteredRowSet class defines the following new methods: public Predicate getFilter().jdbc. deleting. The new criteria is immediately applied on the object. 18-12 Oracle Database JDBC Developer's Guide and Reference . } catch (IOException exc) { System.FilteredRowSet.readXml(fr). This method returns a Predicate object that defines the filtering criteria active on the OracleFilteredRowSet object. Rows that fall outside of the filtering criteria set on the object cannot be modified until the filtering criteria is removed or a new filtering criteria is applied. if an attempt is made to persist the object.

col1 and col2. columnIndexes = indexes... for (int i = 0. The code retrieves those rows from the table that have value of col1 between 50 and 100 and value of col2 between 100 and 200. OracleFilteredRowSet ofrs = new OracleFilteredRowSet().length. ofrs..next()) {. high = hi..getInt(columnIndexes[i]).. ofrs. JoinRowSet A JoinRowSet is an extension to WebRowSet that consists of related data from different RowSets. The predicate defining the filtering criteria is as follows: public class PredicateImpl implements Predicate { private int low[]. 200}. } return result.100) and col2 in (100. i < columnIndexes.execute(). i++) { int columnValue = rs... int indexes[] = {1. public PredicateImpl(int[] lo.. ofrs. indexes)).200) while (ofrs. if (columnValue < low[i] || columnValue > high[i]) result = false.setCommand("select col1. high. Assume a table. with two NUMBER columns.) methods simply return true } The predicate defined in the preceding code is used for filtering content in an OracleFilteredRowSet object. } // the other two evaluate(.. } public boolean evaluate(RowSet rs) { boolean result = true.setPredicate(new PredicateImpl(low. // set other properties on ofrs like usr/pwd . . int[] hi. 100}. int low[] = {50.. int high[] = {100. test_table. There is no standard way to establish a SQL JOIN between JDBC RowSets 18-13 ..JoinRowSet The following code example illustrates the use of OracleFilteredRowSet.} .. int[] indexes) { low = lo. as follows: . private int high[]. // this will only get rows with col1 in (50. 2}. private int columnIndexes[]. col2 from test_table").

A match column can be specified in the following ways: ■ Using the setMatchColumn method This method is defined in the Joinable interface. can be added to a JoinRowSet object. addRowSet(RowSet rowSet. supportsLeftOuterJoin().rowset.sql. that is. supportsFullJoin(). OracleJoinRowSet provides the following methods: public public public public public void void void void void addRowSet(Joinable joinable) throws SQLException. String as[]) throws SQLException. int i) throws SQLException. 18-14 Oracle Database JDBC Developer's Guide and Reference .jar and ojdbc6.rowset. These methods are used to add a RowSet object to the OracleJoinRowSet object. String s) throws SQLException. int an[]) throws SQLException. This class. which implement the Joinable interface. implements the standard JSR-114 interface javax. which need to be set as match column. This method returns a String array containing the names of the RowSet objects that are added to the OracleJoinRowSet object. All five types of RowSet support the Joinable interface. public public public public public boolean boolean boolean boolean boolean supportsCrossJoin(). supportsRightOuterJoin(). addRowSet(RowSet rowSet. The method returns a java.Collection object that contains the RowSet objects. addRowSet(RowSet arowSet[]. This method can also be used to reset the match column at any time.OracleJoinRowSet class. This method retrieves the RowSet objects added to the OracleJoinRowSet object. In addition to the inherited methods. the match columns. which is in the ojdbc5.jdbc. The Oracle implementation of JoinRowSet is the oracle. The Joinable interface provides methods for specifying the columns based on which the JOIN will be performed. You can pass one or more RowSet objects to be added to the OracleJoinRowSet object. public String[] getRowSetNames() throws SQLException. These four methods can be used to set or reset a match column at the time a RowSet object is being added to a JoinRowSet object. public Collection getRowSets() throws SQLException. Four of the five implementations of this method take a match column as a parameter. provided they can be related in a SQL JOIN.JoinRowSet disconnected RowSets without connecting to the data source.jar files. ■ Using the addRowSet method This is an overloaded method in JoinRowSet. addRowSet(RowSet arowSet[]. supportsInnerJoin(). These methods return a boolean value indicating whether the OracleJoinRowSet object supports the corresponding JOIN type. A JoinRowSet addresses this issue. You can also pass names or indexes of one or more columns.util. public void setJoinType(int i) throws SQLException. Any number of RowSet objects.JoinRowSet. It is the only method that can be used to set the match column before a RowSet object is added to a JoinRowSet object.

" + "person's name = " + ojrs.getString(3)).addRowSet(ocrsPerson.. while (ojrs. This method creates a CachedRowSet object containing the data in the OracleJoinRowSet object.execute(). and a Person table with a NUMBER column Person_id and a VARCHAR2 column Name. public int getJoinType() throws SQLException. It takes an integer constant as defined in the javax.addRowSet(ocrsOrder).execute(). //use addRowSet() to set match column ocrsPerson. Assume that there are two tables. public CachedRowSet toCachedRowSet() throws SQLException.getInt(1) + ".sql.. ocrsOrder. This method throws a SQLException exception.JoinRowSet This method is used to set the JOIN type on the OracleJoinRowSet object. // Join on person_id column ocrsOrder.setCommand("select person_id.beforeFirst(). . // Creating the JoinRowSet OracleJoinRowSet ojrs = new OracleJoinRowSet(). .setCommand("select order_id. This method returns a String containing the SQL-like description of the WHERE clause used in the OracleJoinRowSet object. // RowSet holding data from table Person OracleCachedRowSet ocrsPerson = new OracleCachedRowSet(). whose data come from two different tables. The following code illustrates how OracleJoinRowSet is used to perform an inner join on two RowSets. // now we can go the JoinRowSet as usual ojrs.setMatchColumn(2).JoinRowSet interface that specifies the JOIN type.rowset. // RowSet holding data from table Order OracleCachedRowSet ocrsOrder = new OracleCachedRowSet(). an Order table with two NUMBER columns Order_id and Person_id. .. .out. // Join on person_id column.println("order id = " + ojrs. ocrsPerson. ojrs. The resulting RowSet contains data as if they were the result of an inner join on these two tables.. This methods throws a SQLException exception.. JDBC RowSets 18-15 .next()) System. person_id from order").. 1)..getInt(2) + ". ... in another way ojrs. public String getWhereClause() throws SQLException. name from person"). // do not set match column on this RowSet using setMatchColumn().. This method returns an integer value that indicates the JOIN type set on the OracleJoinRowSet object. " + "person id = " + ojrs. ocrsOrder... .

JoinRowSet 18-16 Oracle Database JDBC Developer's Guide and Reference .

the NLS_LANG variable is no longer part of the JDBC globalization mechanism. The JDBC server-side internal driver provides complete globalization support and does not require any globalization extension files. LONGVARCHAR.jar. You should use these methods when using JSE 6 or later. formerly known as National Language Support (NLS). ojdbc5.0 includes methods for reading and writing national character set values. setting it has no effect. Globalization Support 19-1 . This chapter contains the following sections: ■ ■ ■ Providing Globalization Support NCHAR. VARCHAR.6 See Also: ■ ■ ■ "Oracle Character Data Types Support" on page 4-10 Oracle Database Globalization Support Guide Oracle Database Reference Note: ■ Starting from Oracle Database 10g. The JDBC driver does not check NLS environment. then the driver provides the support to perform the conversions between the database character set and the client character set. NCLOB and the defaultNChar Property in JDK 1. JDBC 4.5 New Methods for National Character Set Type Data in JDK 1.jar and ojdbc6. NVARCHAR2. Globalization support enables you retrieve data or insert data into a database in any character set that Oracle supports. ■ ■ Providing Globalization Support The basic Java Archive (JAR) files. contain all the necessary classes to provide complete globalization support for: ■ Oracle character sets for CHAR. So. or CLOB data that is not being retrieved or inserted as a data member of an Oracle object or collection type.19 Globalization Support The Oracle Java Database Connectivity (JDBC) drivers provide globalization support. If the clients and the server use different character sets.

that includes the JA16SJIS and JA16EUC character sets. then a file with the name jdbc_orai18n_cs. WE8MSWIN1252.11.jar in the CLASSPATH environment variable of your application.jar. 19-2 Oracle Database JDBC Developer's Guide and Reference . If the custom JAR/ZIP file exists.jar -custom-charsets-jar custom_orai18n_ja.. It is certified that all supported character sets can be specified with the command. However. Compressing orai18n. the command that displays the information and the displayed information is as follows: $ java -jar jdbc_orai18n_cs.. and UTF8.jar is created in the current working directory.jar using the built-in customization tool.jar file contains many important character set and globalization support files. then the file will not be updated or removed. If any invalid or unsupported character set name is specified in the command. This file is now obsolete. The custom character set JAR/ZIP does not accept any command.zip. Also. Note: Previous releases depended on the nls_charset12. WE8ISO8859P1.jar -charset JA16SJIS JA16EUC The output of the command is as follows: Added Character set : JA16SJIS Added Character set : JA16EUC If you do not specify a file name for your custom JAR/ZIP file. you must include orai18n. WE8DEC. custom_orai18n_ja. then no output JAR/ZIP file will be created.Providing Globalization Support ■ CHAR or VARCHAR data members of object and collection for the character sets US7ASCII.] For example. it prints the version information and the command that was used to generate the JAR/ZIP file. for your custom JAR/ZIP file.X Release This custom character set jar/zip file was created with the following command: java -jar orai18n.jar -charset WE8ISO8859P15 The limitation to the number of character sets that can be specified depends on that of the shell or command prompt of the operating system. For example.X.jar The orai18n.X. To use any other character sets in CHAR or VARCHAR data members of objects or collections.jar -custom-charsets-jar jdbc_orai18n_cs.jar Oracle Globalization Development Kit . you cannot specify a name that starts with orai18n. as follows: java -jar orai18n. then issue the following command: $ java -jar orai18n.1. you have jdbc_orai18n_cs.zip file.jar -custom-charsets-jar [jar/zip_filename] -charset characterset_name [characterset_name . if you want to create a custom character set file. You can reduce the size of orai18n.

FORM_NCHAR).jdbc. pstmt. The default value of defaultNChar is false. then you need to perform the following so that JDBC supports the custom character set: After creating the . then you can also specify defaultNChar as a connection property and access NCHAR. the oracle.?.jar into the classpath environment variable while executing the JDBC code that connects to the database with the custom character set.5 Note: 1.jdbc. since Oracle Database 10g. If you are using a custom character set.prepareStatement("insert into TEST values(?.nlb files as part of the process of creating a custom character set. pstmt.?)").setString(1. refer to Oracle Database Globalization Support Guide. For example: PreparedStatement pstmt = conn.glb files for the newly created character set and also for the lx0boot.FORM_CHAR) for columns that do not need national-language characters. create . pstmt.nlt file using the following command: java -classpath $ORACLE_HOME/jlib/orai18n-tools.setString(3. then JDBC treats all character columns as being national-language. For example: PreparedStatement pstmt = conn. If the value of defaultNChar is false. pstmt.prepareStatement("insert into TEST values(?. then specify the following at the command-line: java -Doracle. OraclePreparedStatement. myUnicodeString2). myUnicodeString1). OraclePreparedStatement.setFormOfUse(3. // NVARCHAR2 column If you want to set the value of defaultNChar to true. Add the generated files and $ORACLE_HOME/jlib/orai18n-mappings. NVARCHAR2. OraclePreparedStatement. OraclePreparedeStatement.?)"). then you must call the setFormOfUse(<column_Index>.nlt and . NVARCHAR2. OraclePreparedStatement.setFormOfUse(1.setString(2.FORM_CHAR).FORM_NCHAR). NVARCHAR2.FORM_NCHAR) method for those columns that specifically need national-language characters. // NCHAR column pstmt. NCLOB and the defaultNChar Property in JDK 1.setFormOfUse(2. For more information about creating a custom character set.jdbc.jar Ginstall <nlt file> 2. then you should call the setFormOfUse(<column_Index>.NCHAR.OraclePreparedStatement interface treats the data type of all the columns in the same way as they are encoded in the database character set.5 By default.defaultNChar system property to true. NCHAR.defaultNChar=true myApplication If you prefer. NCLOB and the defaultNChar Property in JDK 1. pstmt. if you set the value of oracle. or NCLOB data. If the value of defaultNChar is true. // CHAR column Globalization Support 19-3 .?. However. myString).

NCLOB.2) JDBC driver is connected to an Oracle Database 10g release 1 (10.') are converted to Unicode literals (u'.6 Note: ■ Always use java. If an Oracle Database 10g release 2 (10.') are not converted and any character that is not representable in the database character set gets corrupted.NCHAR. If an Oracle Database 10g release 2 (10. All Unicode characters that are not representable in the database character set get corrupted. then NCHAR literals (n'. The JDBC specification uses the String class to represent NCHAR. but if the setObject method is used. and the NClob class to represent NCLOB values. then all NCHAR literals (n'.') containing Unicode characters that are not representable in the database character set. SQL strings are converted to the database character set. LONGVARCHAR... VARCHAR. To retrieve a national character value. JDBC drivers do not support any NCHAR literal (n'. and LONGNVARCHAR data. This is done automatically to prevent data corruption. and CLOB types.String for character data instead of oracle.1) or earlier database server.NVARCHAR. You can also use the setObject method to access national character set types.2) JDBC driver is connected to an Oracle Database 10g release 2 (10..') and all non-ASCII characters are converted to their corresponding Unicode escape sequence. then the target data type must be specified as Types.0 introduces support for the following four additional SQL types to access the national character set types: ■ ■ ■ ■ NCHAR NVARCHAR LONGNVARCHAR NCLOB These types are similar to the CHAR. ■ ■ New Methods for National Character Set Type Data in JDK 1.6 JDBC 4. Types.lang.LONGNVARCHAR.2) database server.New Methods for National Character Set Type Data in JDK 1.. ■ Note: ■ In Oracle Database. an application calls one of the following methods: ■ ■ ■ getNString getNClob getNCharacterStream 19-4 Oracle Database JDBC Developer's Guide and Reference .CHAR.sql.. or Types.. CHAR is provided only for backward compatibility.1) and earlier releases. Therefore you need to keep in mind the following: In Oracle Database 10g release 1 (10. NVARCHAR. except that the values are encoded using the national character set... Types.

Globalization Support 19-5 .NCLOB. or Types. So.6.LONGNVARCHAR. ■ ■ ■ ■ setNString setNCharacterStream setNClob setObject Tip: If the setObject method is used. Types.New Methods for National Character Set Type Data in JDK 1.6 ■ getObject To specify a value for a parameter marker of national character type.NVARCHAR. But this practice is discouraged because this method will be deprecated in future release.NCHAR. an application calls one of the following methods: Note: You can use the setFormOfUse method to specify a national character value in JDK 1. Types. then the target data type must be specified as Types. Oracle recommends you to use the methods disucssed in this section.

6 19-6 Oracle Database JDBC Developer's Guide and Reference .New Methods for National Character Set Type Data in JDK 1.

and Oracle Call Interface (OCI) connection pooling.Part V Performance and Scalability This part consists of chapters that discuss the Oracle Java Database Connectivity (JDBC) features that enhance performance. "Implicit Connection Caching" Chapter 22. such as Statement caching. "Performance Extensions" Chapter 24. "Statement and Result Set Caching" Chapter 21. such as update batching and row prefetching. "Oracle Advanced Queuing" . run-time connection load balancing. It also includes a chapter that provides information about Oracle performance extensions. Part V contains the following chapters: ■ ■ ■ ■ ■ ■ Chapter 20. "Run-Time Connection Load Balancing" Chapter 23. implicit connection caching. "OCI Connection Pooling" Chapter 25.

.

0.1). The previous API is now deprecated. This chapter contains the following sections: ■ ■ ■ ■ About Statement Caching Using Statement Caching Reusing Statements Objects Result Set Caching Note: In Oracle9i Database 9.0. So. Starting from JDBC 3. Oracle JDBC provides a new Statement cache interface and implementation. JDBC standards define a statement-caching interface. not using the Statement cache will have a negative impact on performance. Oracle JDBC drivers are designed on the assumption that the implicit Statement cache is enabled.0 and later Releases. About Statement Caching Statement caching improves performance by caching executable statements that are used repeatedly. such as in a loop or in a method that is called repeatedly. Statement and Result Set Caching 20-1 . an Oracle Java Database Connectivity (JDBC) extension.20 Statement and Result Set Caching This chapter describes the benefits and use of Statement caching. replacing the application programming interface (API) supported in Oracle9i Database release 1 (9. Statement caching can do the following: ■ ■ ■ Prevent the overhead of repeated cursor creation Prevent repeated statement parsing and creation Reuse data structures in the client This section covers the following topics: ■ ■ ■ Basics of Statement Caching Implicit Statement Caching Explicit Statement Caching Note: Oracle strongly recommends you use the implicit Statement cache.2.

which are created with a SQL string. Each type of Statement cache can be enabled or disabled independent of the other. because implicit Statement caching uses a SQL string as a key and plain statements are created without a SQL string. the JDBC driver automatically searches the cache for a matching statement. although metadata is saved for performance reasons. a statement object is cached when you call the close method. The scrollable type of result sets produced by the statement must be the same. implicit Statement caching applies only to the OraclePreparedStatement and OracleCallableStatement objects. forward-only or scrollable. that is.About Statement Caching Basics of Statement Caching Applications use the Statement cache to cache statements associated with a particular physical connection. 20-2 Oracle Database JDBC Developer's Guide and Reference . If a match is found during the cache search. You can have either. that is. If a match is not found. prepared or callable. then this will throw an exception. while metadata is saved. You cannot use implicit Statement caching with OracleStatement. Note: The JDBC driver does not clear metadata. the statement. multiple caches can exist if you enable Statement caching for multiple physical connections. A statement that comes from the implicit cache appears as if it were newly created. If you try to enable Statement caching on a logical connection held by a connection cache. it has no semantic impact. along with its cursor and state are cached when you call the close method of the statement object. Therefore. When you enable Statement caching on a connection cache. the logical connections benefit from the Statement caching that is enabled on the underlying physical connection. JDBC automatically caches the prepared or callable statement when you call the close method of this statement object. neither. the state and data information are automatically reinitialized and reset to default values. The cache is associated with an OracleConnection object. When you enable Statement caching. The prepared and callable statements are cached and retrieved using standard connection object and statement object methods. Because each physical connection has its own cache. Statements are removed from the cache to conform to the maximum size using a Least Recently Used (LRU) algorithm. Both types of Statement caching share a single cache per connection. or both in effect. When a cached OraclePreparedStatement or OracleCallableStatement object is retrieved. Implicit Statement Caching When you enable implicit Statement caching. In either case. then a new statement is created and returned. Plain statements are not implicitly cached. The match criteria are the following: ■ ■ ■ The SQL string in the statement must be identical to one in the cache. OracleConnection includes methods to enable Statement caching. The statement type must be the same. then the cached statement is returned. When you create an OraclePreparedStatement or OracleCallableStatement. However. There are two types of Statement caching: implicit and explicit.

if the JDBC driver cannot find a statement in cache. you use specialized Oracle WithKey methods to cache and retrieve statement objects. See Also: "Disabling Implicit Statement Caching for a Particular Statement" on page 20-6 Explicit Statement Caching Explicit Statement caching enables you to cache and retrieve selected prepared and callable statements. ■ Returning statements During implicit Statement caching. in the case of explicit Statement caching. In contrast. whenever you call prepareStatement or prepareCall. you take no special action to retrieve statements from a cache. then it will return a null value. explicit Statement caching requires you to provide a Java String. Instead. However. Table 20–1 compares the different methods employed in implicit and explicit Statement caching.Using Statement Caching You can prevent a particular statement from being implicitly cached. However. you must be cautious when using this type of caching. Note: Plain statements cannot be cached. because explicit Statement caching saves all three types of information for reuse and you may not be aware of what data and state are retained from prior use of the statements. it has a performance edge over implicit Statement caching. Explicit Statement caching relies on a key. ■ Providing key Implicit Statement caching uses the SQL string of a prepared or callable statement as the key. requiring no action on your part. if the JDBC driver cannot find a matching statement in cache. Implicit and explicit Statement caching can be differentiated on the following points: ■ Retrieving statements In the case of implicit Statement caching. an arbitrary Java String that you provide. Because explicit Statement caching retains statement data and state as well as metadata. during explicit Statement caching. However. which it uses as the key. Table 20–1 Comparing Methods Used in Statement Caching Insert Into Cache close closeWithKey Retrieve From Cache prepareStatement prepareCall getStatementWithKey getCallWithKey Allocate Implicit Explicit prepareStatement prepareCall createStatement prepareStatement prepareCall Using Statement Caching This section discusses the following topics: Statement and Result Set Caching 20-3 . JDBC automatically checks the cache for a matching statement and returns it if found. which retains only metadata. then it will automatically create one.

An argument of 0 specifies no caching.getStatementCacheSize()).println("Stmt Cache size is " + ((OracleConnection)conn). which returns true if implicit caching is enabled. You can have either. Enabling Implicit Statement Caching Enable implicit Statement caching in one of the following two ways: ■ ■ Call setImplicitCachingEnabled(true) on the connection Call OracleDataSource. call OracleConnection. An argument of 0 specifies no caching.out. you also need to call OracleConnection. use the getStatementCacheSize method in the following way: System. You set ImplicitCachingEnabled by calling OracleDataSource. The following code specifies a cache size of ten statements: ((OracleConnection)conn). false otherwise. The argument you supply is the maximum number of statements in the cache. implicit and explicit Statement caching can be enabled or disabled independent of one other.setStatementCacheSize(10). To determine whether implicit caching is enabled.setStatementCacheSize method on the physical connection. Disabling Implicit Statement Caching Disable implicit Statement caching by calling setImplicitCachingEnabled(false) on the connection or by setting the ImplicitCachingEnabled property to false. or both in effect. neither. The argument you supply is the maximum number of statements in the cache. Enable explicit Statement caching by calling setExplicitCachingEnabled(true) on the connection. 20-4 Oracle Database JDBC Developer's Guide and Reference .setImplicitCachingEnabled(true) In addition to calling one of these methods. To check the cache size. Note: Enabling Statement caching enables both implicit and explicit Statement caching.Using Statement Caching ■ ■ ■ ■ Enabling and Disabling Statement Caching Closing a Cached Statement Using Implicit Statement Caching Using Explicit Statement Caching Enabling and Disabling Statement Caching When using the OracleConnection API.setStatementCacheSize on the physical connection. For setting the cache size. Enabling Explicit Statement Caching To enable explicit Statement caching you must first set the Statement cache size. call getImplicitCachingEnabled.getConnection with the ImplicitCachingEnabled property set to true.

The statement is physically closed automatically under one of following three conditions: ■ ■ When the associated connection is closed When the cache reaches its size limit and the least recently used statement object is preempted from cache by the LRU algorithm If you call the close method on a statement for which Statement caching is disabled ■ Using Implicit Statement Caching Once you enable implicit Statement caching. 2. Note: ■ You enable implicit and explicit caching for a particular physical connection independently. false otherwise. which returns true if explicit caching is enabled. Statement and Result Set Caching 20-5 . Implicit and explicit Statement caching share the same cache. Allocate a statement using one of the standard methods.close(). ■ Call the close method of the statement object stmt. Closing a Cached Statement Perform the following to close a Satement and assure that it is not returned to the cache: ■ Disable caching for that statement stmt. The following example disables explicit Statement caching: ((OracleConnection)conn). call getExplicitCachingEnabled. Enable implicit Statement caching. Physically Closing a Cached Statement With implicit Statement caching enabled. Implicit Statement caching includes the following steps: 1. by default. you cannot physically close statements manually. Therefore. Remember this when you set the statement cache size. ■ Disabling Explicit Statement Caching Disable explicit Statement caching by calling setExplicitCachingEnabled(false). all prepared and callable statements are automatically cached.Using Statement Caching To determine whether explicit caching is enabled. it is possible to do Statement caching both implicitly and explicitly during the same session.setDisableStatementCaching(true).setExplicitCachingEnabled(false). The close method of a statement object caches the statement instead of closing it. Disabling caching or closing the cache purges the cache.

close (). Note: If you are using JSE 6. The following code disables implicit Statement caching for pstmt: PreparedStatement pstmt = conn. Retrieve the implicitly cached statement by calling the appropriate standard prepare method. To prevent a particular callable or prepared statement from being implicitly cached.Using Statement Caching 3.prepareStatement ("UPDATE emp SET ename = ? WHERE rowid = ?"). Use the following to check whether the Statement object is poolable: Statement. When you call the close method on an OraclePreparedStatement or OracleCallableStatement object. by default. Allocating a Statement for Implicit Caching To allocate a statement for implicit Statement caching. call the close method of the statement object. all callable and prepared statements of that connection are automatically cached. depending on the statement type. 5.setPoolable(false). the JDBC driver automatically puts this statement in cache. Retrieving an Implicitly Cached Statement To retrieve an implicitly cached statement. unless you have disabled caching for this statement.close(). You can manage cache space by calling the setDisableStatementCaching method on any infrequently used statement.isPoolable(). Disable implicit Statement caching for any particular statement you do not want to cache. Implicitly Caching a Statement To cache an allocated statement.0 method setPoolable: PreparedStatement. use the setDisableStatementCaching method of the statement object. The following code caches the pstmt statement: pstmt. 4. The following code retrieves pstmt from cache using the prepareStatement method: 20-6 Oracle Database JDBC Developer's Guide and Reference . Disabling Implicit Statement Caching for a Particular Statement With implicit Statement caching enabled for a connection.prepareStatement("SELECT 1 from DUAL"). Cache the statement using the close method. ((OraclePreparedStatement)pstmt). then you can disable Statement caching by using the standard JDBC 4. The following code allocates a new statement object called pstmt: PreparedStatement pstmt = conn. pstmt. This is an optional step.setDisableStmtCaching(true). use either the prepareStatement or prepareCall method as you would typically. call either the prepareStatement or prepareCall method.

The closeWithKey method caches a statement as is. Explicitly cache the statement by closing it with a key. The following code allocates a new statement object called pstmt: PreparedStatement pstmt = conn. it is re-cached with its key. Re-cache an open. Retrieving an Explicitly Cached Statement To recall an explicitly cached statement. 4.Using Statement Caching pstmt = conn. Retrieve the explicitly cached statement by calling the appropriate Oracle WithKey method. Allocating a Statement for Explicit Caching To allocate a statement for explicit Statement caching. and metadata are retained and not cleared. or prepareCall method as you would typically. Each time a cached statement is closed. Table 20–2 Method prepareStatement Methods Used in Statement Allocation and Implicit Statement Caching Functionality for Implicit Statement Caching Performs a cache search that either finds and returns the desired cached OraclePreparedStatement object or allocates a new OraclePreparedStatement object if a match is not found Performs a cache search that either finds and returns the desired cached OracleCallableStatement object or allocates a new OracleCallableStatement object if a match is not found prepareCall Using Explicit Statement Caching A prepared or callable statement can be explicitly cached when you enable explicit Statement caching. state. Explicitly Caching a Statement To explicitly cache an allocated statement. Explicit Statement caching includes the following steps: 1. Enable explicit Statement caching. prepareStatement. The key is an arbitrary Java String that you provide. 5.prepareStatement ("UPDATE emp SET ename = ? WHERE rowid = ?"). call the closeWithKey method of the statement object. call either the getStatementWithKey or getCallWithKey methods depending on the statement type. Statement and Result Set Caching 20-7 .closeWithKey ("mykey"). explicitly cached statement by closing it again with the closeWithKey method. specifying the appropriate key. The following code caches the pstmt statement with the key "mykey": ((OraclePreparedStatement)pstmt). specifying a key. using the closeWithKey method.prepareStatement ("UPDATE emp SET ename = ? WHERE rowid = ?"). Table 20–2 describes the methods used to allocate statements and retrieve implicitly cached statements. use either the createStatement. 3. This means the data. Allocate a statement using one of the standard methods. 2.

If you call the creationState method on the pstmt statement object. This information is as it was when the statement was last closed. If the return value is true. Important: When you retrieve an explicitly cached statement.getStatementWithKey ("mykey"). then the application knows that the PreparedStatement object is being pooled. and metadata. The JDBC driver does not verify the type of statement it is returning. This section covers the following topics: ■ ■ Using a Pooled Statement Closing a Pooled Statement Using a Pooled Statement An application can find out whether a data source supports statement pooling by calling the isPoolable method from the Statement interface. Reusing of pooled statement should be completely transparent to the application. Table 20–3 Method getStatementWithKey getCallWithKey Methods Used to Retrieve Explicitly Cached Statements Functionality for Explicit Statement Caching Specifies the key needed to retrieve a prepared statement from cache Specifies the key needed to retrieve a callable statement from cache Reusing Statements Objects The JDBC 3.0 specification introduces the feature of statement pooling that allows an application to reuse a PreparedStatement object in the same way as it uses a Connection object. If a match is not found. if you used the prepareStatement method to allocate a statement. If a match is found. data. If an application closes a 20-8 Oracle Database JDBC Developer's Guide and Reference .Reusing Statements Objects If you retrieve a statement with a specified key. based on the specified key. that is. then the matching statement is returned along with its state. Table 20–3 describes the methods used to retrieve explicitly cached statements. The following code recalls pstmt from cache using the "mykey" key with the getStatementWithKey method. ensure that you use the method that is appropriate for your statement type when specifying the key. the application code should remain the same whether a PreparedStatement object participates in statement pooling or not. then the JDBC driver searches the cache for the statement. pstmt = ((OracleConnection)conn). For example. The application can also request a statement to be pooled or not pooled by using the setPoolable method from the Statement interface. The PreparedStatement objects can be reused by multiple logical connections in a transparent manner. then the method returns EXPLICIT. Recall that the pstmt statement object was cached with the "mykey" key. then use the getStatementWithKey method to retrieve that statement from cache. then the JDBC driver returns null.

Closing a Pooled Statement An application closes a pooled statement exactly the same way it closes a nonpooled statement. A result cache stores the results of queries shared across all sessions. The method PooledConnection. which releases the resources associated with those statements. ■ close This java.closeAll closes all of the statements open on a given physical connection.closeAll This method is called by the connection pool manager to close all of the physical statements being pooled by the PooledConnection object Result Set Caching Your applications sometime send repetitive queries to the database. Statement and Result Set Caching 20-9 . the results are retrieved directly from the cache memory.sql. This is necessary because the garbage collection mechanism is unable to detect when externally managed resources can be released.prepareStatement method in order to reuse it. Once a statement is closed. Note: An application has no direct control over how statements are pooled. This is done by the pool manager. then it closes the logical statement used by the application but does not close the physical statement being pooled.Connection interface method is called by an application. it must still call Connection. whether is it pooled or nonpooled. The following methods can close a pooled statement: ■ close This java. results of queries. query fragments.Result Set Caching PreparedStatement object. whose behavior is determined by the properties of the ConnectionPoolDataSource object that produced it. When these queries are executed repeatedly. A pool of statements is associated with a PooledConnection object. – Pooled connection This method closes the logical connection and the logical statements it returned. it is no longer available for use by the application and an attempt to reuse it causes an exception to be thrown. If the statement is being pooled.sql. and PL/SQL functions can be cached in memory. This method acts differently depending upon whether the connection using the statement is being pooled or not: – Nonpooled connection This method closes the physical connection and all statements created by that connection. The only difference visible is that an application cannot directly close a physical statement that is being pooled. To improve the response time of repetitive queries.Statement interface method is called by an application. but leaves open the underlying PooledConnection object and any associated pooled statements ■ PooledConnection.

1) provides support for server-side Result Set caching for both JDBC types. The scalability on the server is increased since it expends less CPU time. The query result set can be cached in the following ways: ■ ■ Server-side Cache Client Result Cache Server-side Cache Oracle Database 11g Release 1 (11. The client result cache transparently keeps the result set consistent with any session state or database changes that can affect the cached result sets. The server-side result cache is used to cache the results of the current queries. or PL/SQL function.1) introduces support for client result cache for JDBC OCI client. The client result cache improves performance of applications by caching query result sets in a way that subsequent query executions can access the cached result set without fetching rows from the server. A cached result is automatically invalidated whenever a database object used in its creation is successfully modified. query fragments. The cached results reside in the result cache memory portion of the SGA.Result Set Caching You must annotate a query or query fragment with a result cache hint to indicate that results are to be stored in the query result cache. This eliminates many round-trips to the server for cached results and reduces CPU usage. query fragment. This allows significant improvements in response time for frequent client SQL query executions and for fetching rows. See Also: Client Result Cache on page 6-1 20-10 Oracle Database JDBC Developer's Guide and Reference . The server-side caching can be of the following two types: ■ ■ SQL Query Result Cache PL/SQL Function Result Cache See Also: ■ Oracle Database Performance Tuning Guide for more information about SQL Query Result Cache Oracle Database PL/SQL Language Reference for more information about PL/SQL Function Result Cache ■ Client Result Cache Oracle Database 11g Release 1 (11. and PL/SQL functions in memory and then to use the cached results in future executions of the query.

based on OracleConnectionCache and OracleConnectionCacheImpl. Oracle recommends that you take advantage of the new architecture. the first connection request to the OracleDataSource transparently creates a connection cache. where you always use the default connection. After implicit caching is turned on. support for multiple users. The implicit connection cache is an improved Java Database Connectivity (JDBC) 3. An application turns the implicit connection cache on by calling setConnectionCachingEnabled(true) on an OracleDataSource. is deprecated. Implicit Connection Caching 21-1 . and the ability to request connections based on user-defined profiles. Java and Java2 Platform. Connection caching is relevant only to the client-side JDBC drivers and the server-side Thin driver.21 Implicit Connection Caching Connection caching.0-compliant connection cache implementation for DataSource. There is no need for application developers to write their own cache implementations. is a means of keeping and using the cache of physical database connections. Note: The previous cache architecture. Enterprise Edition (J2EE) applications benefit from transparent access to the cache. generally implemented in the middle tier. This chapter is divided into the following sections: ■ ■ ■ ■ ■ ■ The Implicit Connection Cache Using the Connection Cache Connection Attributes Connection Cache Properties Connection Cache Manager API Advanced Topics Note: The concept of connection caching is not relevant to the server-side internal driver. which is more powerful and offers better performance.

Each virtual machine has one distinguished instance of 21-2 Oracle Database JDBC Developer's Guide and Reference . ■ ■ OracleConnectionCacheManager The new OracleConnectionCacheManager class provides a rich set of administrative APIs that applications can use to manage the connection cache. no matter what user name and password the connection requests. applications can reclaim and reuse abandoned connections. You can think of logical connections as handles. Using these properties. and so on. including support for multiple users and the required cache properties Property-based configuration Cache properties define the behavior of the cache.The Implicit Connection Cache The Implicit Connection Cache The connection caching architecture has been redesigned so that caching is transparently integrated into the data source architecture. All connections obtained through that data source. When an application calls the OracleConnection. all connection requests are serviced from the connection cache. The supported properties set timeouts. are returned to the cache. ■ Single cache per OracleDataSource instance When connection caching is turned on. There is a one-to-one mapping between cache-enabled DataSource instances and caches. all connections obtained through the same data source are stored in a common cache. it uses the standard OracleDataSource application programming interfaces (APIs) to get connections.close method to close the logical connection. Note: Caches cannot be shared between DataSource instances. The caches always return logical connections. ■ Support for JDBC 3. The connection cache uses the concept of physical connections and logical connections. Physical connections are the actual connections returned by the database and logical connections are containers used by the cache to manipulate physical connections. the number of connections to be held in the cache. which implement the same interfaces as physical connections. When an application requests a connection from the data source. each cache-enabled OracleDataSource has exactly one cache associated with it. the physical connection is returned to the cache.0 connection cache properties.0 connection caching. the cache either returns an existing connection or creates a new connection with matching authentication information. The implicit connection cache offers the following: ■ Driver independence Both the JDBC Thin and JDBC Oracle Call Interface (OCI) drivers support the implicit connection cache. ■ Transparent access to the JDBC connection cache After an application turns implicit caching on. ■ Heterogeneous user names and passwords per cache Unlike the previous cache implementation. no matter what user name and password are used. The implicit connection cache supports all the JDBC 3. With caching enabled.

Using the Connection Cache OracleConnectionCacheManager. "Run-Time Connection Load Balancing" and Oracle Real Application Clusters Administration and Deployment Guide Using the Connection Cache This section discusses how applications use the implicit connection cache. The database listener distributes connection creation across Oracle Real Application Clusters instances that would perform the best at the time of connection creation. See Also: Oracle Real Application Clusters Administration and Deployment Guide ■ Run-time connection load balancing Run-time connection load balancing of work requests uses Service Metrics to route work requests to an Oracle Real Application Clusters instance that offers the best performance. and when a connection is requested but none is available in the cache. ■ User-defined connection attributes The implicit connection cache supports user-defined connection attributes that can be used to determine which connections are retrieved from the cache. See Also: Chapter 22. Example 21–1 provides a sample code that uses the implicit connection cache. to execute a work request. not by the caching mechanism. greatly increases the throughput and scalability. the first connection request to the OracleDataSource class transparently creates a connection cache.setConnectionCachingEnabled(true). ■ Callback mechanism The implicit connection cache provides a mechanism for users to define cache behavior when a connection is returned to the cache. It covers the following topics: ■ ■ ■ ■ ■ ■ Turning Caching On Opening a Connection Setting Connection Cache Name Setting Connection Cache Properties Closing a Connection Implicit Connection Cache Example Turning Caching On An application turns the implicit connection cache on by calling OracleDataSource. Applications manage a cache through the single OracleConnectionCacheManager instance. ■ Connect-time load balancing Implicit connection caching provides connect-time load balancing when a connection is first created by the application. when handling abandoned connections. Connection attributes can be thought of as labels whose semantics are defined by the application. After implicit caching is turned on. Selecting a connection from the cache based on service. Implicit Connection Caching 21-3 .

setUser("Scott"). When implicit connection cache is enabled. You must. such as auto-commit.close() // close datasource and clean up the cache Opening a Connection After you have turned connection caching on. // Transparently create cache and retrieve connection conn = ods.bind("MyDS". therefore. transaction status.close().Using the Connection Cache Example 21–1 Using the Implicit Connection Cache // Example to show binding of OracleDataSource to JNDI. // . The non-cache-specific getConnection methods behave in the standard manner. lookup("MyDS")..getConnection().setConnectionCachingEnabled(true). then a logical connection is returned.. // return connection to the cache // . ods. the connection returned by OracleDataSource. The getConnection method checks if there are any free physical connections in the cache that match the specified criteria. // . before putting the connection back into the cache. ods. // Retrieve DataSource from the InitialContext ods =(OracleDataSource) ctx. conn. wrapping the physical connection.. wrapped in a logical connection. then a new physical connection is created. reset all the connection states.*.pool. // Turns on caching ctx. OracleDataSource ods = new OracleDataSource().. whenever you retrieve a connection through the OracleDataSource. If no physical connection match is found.. You can set this property by calling the following method: public void synchronized setConnectionCacheName(String cacheName) throws SQLException 21-4 Oracle Database JDBC Developer's Guide and Reference . and returned. two that make no reference to the connection cache and two that specify which sort of connections the cache may return.getConnection method. the JDBC drivers check to see if a connection is available in the cache. and transaction isolation. prefetch size.jdbc. If a match is found. There are four variations on getConnection. // then using implicit connection cache import oracle. // import the pool package Context ctx = new InitialContext(ht). Note: Setting Connection Cache Name The ConnectionCacheName property of OracleDataSource is an optional property used by the Connection Cache Manager to manage a connection cache. // Set DataSource properties ods. ods). batch size..getConnection may not have the state reset.

they are set on the data source.*. such as auto-commit. before putting the connection back into the cache. and transaction isolation. then a default cache name is created using the convention DataSourceName#HexRepresentationOfNumberOfCaches. import javax. Note: ■ Applications must close connections to ensure that the connections are returned to the cache. and closing that connection in order to return it to the cache. setting its caching and data source properties. otherwise the setConnectionCacheProperties method will have no effect. retrieving a connection.Using the Connection Cache When this property is set. This ensures that any subsequent connection retrieved from the cache will have its state reset. See Also: "Connection Cache Properties" on page 21-8 Note: ■ Before setting the cache-specific properties.*. Although these properties govern the behavior of the connection cache.sql. and not on the connection or on the cache itself. you must enable caching on the data source. you must reset all the connection states. There are two variants of the close method: one with no arguments and one that takes a Connection object as argument. Example 21–2 Connection Cache Example import java.sql. batch size. the name is used to uniquely identify the cache accessed by the cache-enabled OracleDataSource. prefetch size. Note: The getConnectionCacheName() method will return the name of the connection cache only if the setConnectionCacheName method is called after the setConnectionCachingEnabled method is called. ■ Closing a Connection An application returns a connection to the cache by calling the close method. transaction status. If the property is not set.*. Setting Connection Cache Properties You can fine-tune the behavior of the implicit connection cache using the setConnectionCacheProperties method to set various connection properties. When implicit connection cache is enabled. Implicit Connection Caching 21-5 . ■ Implicit Connection Cache Example Example 21–2 demonstrates creating a data source. import java.util.

naming. javax.*.Connection Attributes import import import import . ods. Attributes are specified by the application developer and are java. oracle.executeQuery("select user from dual").setProperty("MaxLimit".setConnectionCacheProperties (prop). ods.setUser("hr"). prop. // this cache's name // We need to create a connection to create the cache Connection conn = ds.Properties name and value pairs. // set cache properties java. // be sure set to true ods.*.naming. An application can use connection attributes to supply additional semantics to identify connections.close(). This section covers the following topics: ■ ■ ■ ■ Getting Connections Setting Connection Attributes Checking Attributes of a Returned Connection Connection Attribute Example 21-6 Oracle Database JDBC Developer's Guide and Reference .jdbc.setConnectionCacheName("ImplicitCache01"). // set DataSource properties String url = "jdbc:oracle:oci8:@". Connection Attributes Each connection obtained from a data source can have user-defined attributes. oracle. javax. "10")..setConnectionCachingEnabled(true).createStatement(). ods. For instance. ods. // create a DataSource OracleDataSource ods = new OracleDataSource().pool.setURL(url).spi.close().util..setProperty("MinLimit". an application may create an attribute named connection_type and then assign it the value payroll or inventory. pass).*. ResultSet rset = stmt.jdbc. The connection cache itself enforces no restrictions on the key or value of connection attributes.util.Properties(). "2").setPassword("hr").Properties prop = new java. conn. Statement stmt = conn.getConnection(user. Note: The semantics of connection attributes are entirely application-defined. ods. prop.lang. ods. The methods that get and set connection attributes are found on the OracleConnection interface.*.

but does not have any attributes that are not part of the original list. the DataSource defaults are used. 3.Properties connAttr) Implicit Connection Caching 21-7 .util. java. If null values are passed for user and password. AttributeWeights. Note that the closest matched connection may match a subset of the original attributes.lang. If none of the existing connections matches. The new connection is created using the user name and password set on the DataSource. The connection search mechanism is similar to the basic connectionAttributes based search. using the specialized forms of the getConnection method: ■ getConnection(java. except that the connections are searched not only based on the connectionAttributes. java. Setting Connection Attributes An application sets connection attributes using the following: applyConnectionAttributes(java. If getConnection(String. see "Other Properties" on page 21-11.util. 2.Properties cachedConnectionAttributes Requests a database connection that matches the specified cachedConnectionAttributes. the cache is searched to retrieve the connection that matches the attributes. ■ getConnection(java. Attribute Matching Rules The rules for matching connectionAttributes come in two variations: ■ Basic In this variation.Properties) is called.util. ■ Advanced In this variation. If an exact match is not found and the ClosestConnectionMatch data source property is set. the attributes may be associated with weights. then a closest match may have A and B set. You must set them. then the user name and password passed as arguments are used to open the new connection.Properties cachedConnectionAttributes) Requests a database connection from the implicit connection cache that matches the specified user. The connection search mechanism as follows: 1. if the original list of attributes is A. After you have set attributes on a connection. These weights are assigned to the keys as a one-time operation and is supported as a connection cache property. but also using a set of weights that are associated with the keys on the connectionAttributes.util. password and cachedConnectionAttributes. For example. a new connection is returned. B and C. String. the connection is returned to the caller. If an exact match is found.Connection Attributes Getting Connections The first connection you retrieve has no attributes. See Also: For a discussion on connection attributes.String user. you can request the connection by specifying its attribute. then the connection with the closest match is returned.String password. java. The closest matched connection is one that has the highest number of the original attributes matched.lang. but never a D.

getConnectionAttributes(). use the getUnMatchedConnectionAttributes method. Note: If the closestConnectionMatch property has been set.util.getConnection(connAttr). } // verify whether conn contains property after apply attributes connProp = ((OracleConnection)conn).util. To do this.Connection Cache Properties No validation is done on connAttr.getUnMatchedConnectionAttributes(). listProperties (connProp). // Check to see which attributes weren't matched unmatchedProp = ((OracleConnection)conn). then the cache manager looks for close attribute matches rather than exact matches. Checking Attributes of a Returned Connection When an application requests a connection with specified attributes. connAttr. you know that you must set all the connection attributes. the connection cache creates a connection with no attributes and returns it. The connection cache cannot create a connection with the requested attributes. // retrieve connection that matches attributes Connection conn = ds. if ( unmatchedProp != null ) { // apply attributes to the connection ((OracleConnection)conn). applications should always check the attributes of a returned connection. For this reason. It covers the following topics: ■ ■ ■ ■ Limit Properties TIMEOUT Properties Other Properties Connection Property Example 21-8 Oracle Database JDBC Developer's Guide and Reference . Connection Attribute Example Example 21–3 illustrates using connection attributes. Connection Cache Properties The connection cache properties govern the characteristics of a connection cache. If the return value of this method is null. This section lists the supported connection cache properties. Applying connection attributes is cumulative. When this happens. because the Connection Cache manager is ignorant of the semantics of the attributes.Properties connAttr = new java. Each time you call applyConnectionAttributes. which returns a list of any attributes that were not matched in retrieving the connection. Example 21–3 Using Connection Attributes java.applyConnectionAttributes(connAttr). the connAttr attribute you supply is added to those previously in force. it is possible that no match will be found in the connection cache.Properties().setProperty("connection_type". "payroll").

so that the number of connections is limited only by the number of database sessions configured for the database. Default: Integer. When a cache has this property set. filling the cache in advance of need. To avoid this error. then you will get ORA-00018 error. reinitializing the cache or closing the data source automatically closes all cursors beyond the specified MaxStatementsLimit.MAX_VALUE (no limit) Note: If the number of concurrent connections exceeds the maximum number of sessions configured at the database server. you must set a value for the MaxLimit property. The default value is Integer. This value should be less than the value of the SESSIONS parameter configured for the database server. Default: 0 MaxLimit Sets the maximum number of connection instances the cache can hold.Connection Cache Properties Applications set cache properties in one of the following ways: ■ ■ ■ Using the OracleDataSource method setConnectionCacheProperties When creating a cache using OracleConnectionCacheManager When reinitializing a cache using OracleConnectionCacheManager Limit Properties These properties control the size of the cache. meaning that there is no limit enforced by the connection cache. Default: 0 Implicit Connection Caching 21-9 .MAX_VALUE. MaxStatementsLimit Sets the maximum number of statements that a connection keeps open. Default: 0 MinLimit Sets the minimum number of connections the cache maintains. creating or reinitializing the cache automatically creates the specified number of connections. When this property is set to an integer value greater than 0. InitialLimit Sets how many connections are created in the cache when it is created or reinitialized.

Therefore. when stmt. The heartbeats are set at each database execution. When InitialLimit is greater than MinLimit. When TimeToLiveTimeout expires. Default: 0 (no timeout in effect) See Also: "Use Cases for TimeToLiveTimeout and AbandonedConnectionTimeout" on page 21-14 AbandonedConnectionTimeout Sets the maximum time that a connection can remain unused before the connection is closed and returned to the cache. A connection is considered unused if it has not had SQL database activity. An idle connection is one that is not active and does not have a logical handle associated with it. InactivityTimeout Sets the maximum time a physical connection can remain idle in a connection cache.execute is called on the connection. However. the logical connection is unconditionally closed. the relevant statement handles are canceled. Default: 0 (no timeout in effect) TimeToLiveTimeout Sets the maximum time in seconds that a logical connection can remain open.Connection Cache Properties Note: ■ Setting the MinLimit property does not initialize the cache to contain the minimum number of connections. When InactivityTimeout expires. When AbandonedConnectionTimeout is set. The processing removes affected connections from the pool. InitialLimit does not depend on MinLimit. a heartbeat is registered to convey that this connection is active. the size of the cache is not allowed to shrink below minLimit. the underlying connection is reclaimed and returned to the cache for reuse. Connections can fall below the minimum limit set on the connection pool when JDBC Fast Connection Failover DOWN events are processed. JDBC monitors SQL database activity on each logical connection. the underlying physical connection is closed. ■ ■ TIMEOUT Properties These properties control the lifetime of an element in the cache. MinLimit will be honored as requests to the connection pool increase and the number of connections get past the MinLimit value. if it has been set. To do this. Default: 0 (no timeout in effect) 21-10 Oracle Database JDBC Developer's Guide and Reference . For example. it is possible to have any number of connections specified by InitialLimit up to a value specified by MaxLimit. If a connection has been inactive for the specified amount of time. use the InitialLimit property. and the underlying physical connection is returned to the cache for reuse.

util. If no connection is returned to the cache before the timeout elapses. ValidateConnection Setting ValidateConnection to true causes the connection cache to test every connection it retrieves against the underlying database.*.*. then each connection request waits for the specified number of seconds or until a connection is returned to the cache. import javax. This property is used whenever a releaseConnection() cache callback method is registered. import java. If a valid connection cannot be retrieved. Implicit Connection Caching 21-11 . Example 21–4 Using Connection Properties import java. If ConnectionWaitTimeout is greater than zero.Connection Cache Properties See Also: "Use Cases for TimeToLiveTimeout and AbandonedConnectionTimeout" on page 21-14 PropertyCheckInterval Sets the time interval at which the Connection Cache Manager inspects and enforces all specified cache properties. See Also: "AttributeWeights" on page 21-13 ClosestConnectionMatch ClosestConnectionMatch causes the connection cache to retrieve the connection with the closest approximation to the specified connection attributes. that is. See Also: "ClosestConnectionMatch" on page 21-13 ConnectionWaitTimeout Specifies cache behavior when a connection is requested and there are already MaxLimit connections active. then each connection request waits for zero seconds. Default: zero LowerThresholdLimit Sets the lower threshold limit on the cache. then the connection request returns null. PropertyCheckInterval is set in seconds.*. AttributeWeights AttributeWeights sets the weight for each attribute set on the connection. Default: false Connection Property Example Example 21–4 demonstrates how an application uses connection properties. null connection is returned immediately. then an exception is thrown. The default is 20 percent of the MaxLimit on the connection cache. If ConnectionWaitTimeout is equal to zero.sql. Default: 900 seconds Other Properties These properties control miscellaneous cache behavior.sql.

21-12 Oracle Database JDBC Developer's Guide and Reference . prop.*.REFRESH_ALL_CONNECTIONS). .println(occm.setProperty("InactivityTimeout".getNumberOfAvailableConnections(cacheName) " connections are available in cache " + cacheName). import oracle.sql.util. "10"). "60").setProperty("MaxLimit".sql. "5"). import javax.println(occm.naming. "3"). // seconds prop.jdbc. // Look for a specific cache // Use Cache Manager to check # of available connections // and active connections System.out.lookup(". java..util.getConnectionCacheManagerInstance().Connection Cache Manager API import javax. "50").Properties ().util.spi. . import javax. "25").*. import oracle.*.*. OracleDataSource ds = (OracleDataSource) ctx. // seconds prop.util. // Reinitialize cache.. "1800"). // Get singleton ConnectionCacheManager instance OracleConnectionCacheManager occm = OracleConnectionCacheManager.setProperty("MinLimit". // Refresh all connections in cache occm..getNumberOfActiveConnections(cacheName) + " connections are active"). newProp).*. This section provides an example of using the Connection Cache Manager.naming.setProperty("MaxStatementsLimit". import javax.getConnectionCacheProperties(). // create 3 connections at startup prop.setConnectionCacheProperties (prop).getConnection().reinitializeCache(cacheName.*. conn. Example of ConnectionCacheManager Use Example 21–5 demonstrates the OracleConnectionCacheManager interface. closing all connections java.*. import oracle.out.. // set properties Connection conn = ds.*. occm.*.").*. prop. OracleConnectionCacheManager.naming. java..spi.refreshCache(cacheName.. String cacheName = "foo".setProperty("PropertyCheckInterval".naming.dosomework(). import java.setProperty("AbandonedConnectionTimeout".pool.Properties newProp = new java.jdbc.jdbc. Example 21–5 Connection Cache Manager Example import java.jdbc.*. prop. // the cache size is 5 at least prop.Properties().Properties prop = new java.pool.util. // retrieve Connection Cache Manager API OracleConnectionCacheManager provides administrative APIs that the middle tier can use to manage available connection caches. // seconds ds.setProperty("MaxLimit". newProp. import oracle. import javax.Properties propList=ds. System.setProperty("InitialLimit".util. "900").

load(InputStream) method.Advanced Topics Advanced Topics This section discusses cache functionality that is useful for advanced users. Each String is in the format written by the java. An attribute with a high weight is given more importance in determining a match than an attribute with a low weight. you are telling the Connection Cache Manager to return connections that match only some of the attributes you have specified.Properties. connections with a matching TRANSACTION_ISOLATION will be favored over connections with a matching ROLE. Callback methods are supported with the OracleConnectionCacheCallback interface. and thus can be read by the java. When you set the ClosestConnectionMatch property to true. This section covers the following topics: ■ ■ Attribute Weights and Connection Matching Connection Cache Callbacks Attribute Weights and Connection Matching There are two connection cache properties that enable the developer to specify which connections in the connection cache are accepted in response to a getConnection request. For example. Default: false AttributeWeights Sets the weights for each connectionAttribute. A weight must be an integer value greater than 0. This property is used when ClosestConnectionMatch is set to true to determine which attributes are given highest priority when searching for matches. If you specify attributeWeights. String) method.util. TRANSACTION_ISOLATION could be assigned a weight of 10 and ROLE a weight of 5.Store(OutputStream. AttributeWeights contains a set of Strings representing key-value pairs.Properties. but is not essential to understanding or using the implicit connection cache. when a connectionAttribute based connection request is made on the cache. then you can control the priority the manager uses in matching attributes. If you do not specify attributeWeights. Default: No AttributeWeights Connection Cache Callbacks The implicit connection cache offers a way for the application to specify callbacks to be called by the connection cache. The default weight is 1. This callback mechanism is useful to Implicit Connection Caching 21-13 . If ClosestConnectionMatch is set to true. Each key/value pair sets the weights for each connectionAttribute for which the user intends to request a connection. then the Connection Cache Manager returns the connection that matches the highest number of attributes. This can be used in combination with AttributeWeights to specify what is considered a closest match. ClosestConnectionMatch Setting ClosestConnectionMatch to true causes the connection cache to retrieve the connection with the closest approximation to the specified connection attributes. The Key is a connectionAttribute and the Value is the weight.util.

When the connections are stateless. If the callback returns false. unmodified. to invoke all callback methods ((OracleConnection)conn). The usrObj parameter contains any parameters that the user wants supplied. cbk is the user implementation of the OracleConnectionCacheCallback interface. 21-14 Oracle Database JDBC Developer's Guide and Reference . For example. ■ The application maintains state on each connection.ALL_CALLBACKS When ALL_CALLBACKS is set. new SomeUserObject(). when the callback method is called. These connections are valid for reuse because there is no session state associated with them. Note that these timeout mechanisms are applicable to the logical connection when it is retrieved from the connection cache. the connection cache calls the handleAbandonedConnection method of the callback before reclaiming the connection. Object usrObj. int cbkflag). When a callback is registered. // register callback. The UserConnectionCacheCallback interface supports two callback methods to be implemented by the user. The connections for which the timeout expires are put back into the connection cache for reuse. This user object is passed back. If the callback returns true. either of the timeout mechanisms can be used. ■ The application considers the connections completely stateless. In this interface. An application can register a ConnectionCacheCallback on an OracleConnection. then the connection is reclaimed.ABANDONED_CONNECTION_CALLBACK OracleConnection. OracleConnection. then the connection remains active. releaseConnection and handleAbandonedConnection. It must be one of the following values: ■ ■ ■ OracleConnection. but has a cleanup routine that can render the connections stateless when they are returned to the connection cache.Advanced Topics take advantage of the special knowledge of the application about particular connections. all the connection cache callback methods are called.registerConnectionCacheCallback( new UserConnectionCacheCallback(). The registration API is as follows: public void registerConnectionCacheCallback( OracleConnectionCacheCallback cbk.ALL_CALLBACKS). supplementing the default behavior when handling abandoned connections or when the cache is empty. The cbkflag parameter specifies which callback method should be called.RELEASE_CONNECTION_CALLBACK OracleConnection. Use Cases for TimeToLiveTimeout and AbandonedConnectionTimeout The following are the use cases for the TimeToLiveTimeout and AbandonedConnectionTimeout timeout mechanisms when used with implicit connection cache. OracleConnectionCacheCallback is an interface that must be implemented by the user and registered with OracleConnection.

cannot ensure cleaning up of state for reuse of connections by other applications or users. therefore. The handleAbandonedConnection callback method is implemented by the application and ensures that the necessary cleanup is done. but has no control over the connection and. JDBC internally knows how to reclaim a connection even when it is in an invalid state. The closing of this connection by the callback method causes the connection to be put back into the connection cache in a state where it is reusable. The connection is closed when the timeout processing invokes this callback method. AbandonedConnectionTimeout can be used in this scenario. TimeToLiveTimeout cannot be used. Implicit Connection Caching 21-15 . The use of either of the timeout mechanisms is not recommended.Advanced Topics In this case. There is no way for the connection cache to ensure that a connection returned to the cache is in a reusable condition. Note: Do not to close the connection after calling handleAbandonedConnection method because the connection could be in an invalid state. "Connection Cache Callbacks" on page 21-13 See Also: ■ The application maintains state on each connection. only if OracleConnectionCacheCallback is registered on the connection. However.

Advanced Topics 21-16 Oracle Database JDBC Developer's Guide and Reference .

22 Run-Time Connection Load Balancing Oracle Database 11g provides the run-time connection load balancing feature. However. In the best case. Figure 22–1 illustrates run-time connection load balancing. Run-Time Connection Load Balancing 22-1 . minimizing the need to relocate work. a connection could belong to any instance that provides the relevant service. when one instance performs better than others. When run-time connection load balancing is enabled on the implicit connection cache. 2. The run-time connection load balancing feature enables routing of work requests to an instance that offers the best performance. This chapter contains the following sections: ■ ■ Overview of Run-Time Connection Load Balancing Enabling Run-Time Connection Load Balancing Overview of Run-Time Connection Load Balancing In an Oracle Real Application Clusters environment. 3. the following steps occur: 1. In Figure 22–1. The run-time connection load balancing mechanism selects the connection that belongs to the best instance from the connection cache. A client requests a connection from the connection cache by calling the getConnection method on the DataSource object. this could be either Instance1 or Instance2. all instances perform equally well and randomly retrieving a connection from the cache is appropriate. random selection of a connection is inefficient. The client receives the connection that would process the work request with the best response time.

When the events stop arriving.Enabling Run-Time Connection Load Balancing Figure 22–1 Run-Time Connection Load Balancing Implicit Connection Cache RAC Database 2 Instance1Best Client 1 Instance2Best 3 Instance3Bad Connection retrieval based on the load balancing advisory is automatic. that is. As a result.THROUGHPUT ■ The connection balancing goal must be set to SHORT. Run-time connection load balancing relies on the Oracle Notification Service (ONS) infrastructure.modify_service. you must configure the Oracle Real Application Clusters database in the following manner: ■ The service goal must be set to one of the following: – – DBMS_SERVICE. or best throughput. The service goal can be set using the goal parameter. See Also: "Using Fast Connection Failover" on page 26-2 Enabling Run-Time Connection Load Balancing To enable and use run-time connection load balancing. The service goal determines whether the connection provides best service quality. how efficiently an entire job or long-running query completes. that is. how efficiently a single transaction completes. There is no additional setup or configuration of ONS required to benefit from run-time connection load balancing. run-time connection load balancing is enabled by default when Fast Connection Failover is enabled. and the connection balancing goal can be set using the clb_goal parameter. 22-2 Oracle Database JDBC Developer's Guide and Reference . It uses the same out-of-band ONS event mechanism that is used for Fast Connection Failover processing. The advisory is used by the connection cache as long as the events are posted by Oracle Real Application Clusters. A request for a connection is serviced by selecting a connection based on the service goal as determined by the Load Balancing Advisory. These goals must be set when calling dbms_service.SERVICE_TIME DBMS_SERVICE.create_service or dbms_service. the connection cache reverts to random retrieval of connections from the cache.

when the rate of completing work is equal to the rate of starting new work.Enabling Run-Time Connection Load Balancing Note: You can set the connection balancing goal to LONG. See Also: Oracle Real Application Clusters Administration and Deployment Guide Run-Time Connection Load Balancing 22-3 . this is mostly useful for closed workloads. that is. However.

Enabling Run-Time Connection Load Balancing 22-4 Oracle Database JDBC Developer's Guide and Reference .

which is referred to as standard update batching The Oracle-specific model. This section covers the following topics: ■ ■ ■ ■ Overview of Update Batching Models Oracle Update Batching Standard Update Batching Premature Batch Flush Performance Extensions 23-1 .0 specification. by grouping multiple UPDATE. thereby improving application performance. In any single application. This chapter covers the following topics: ■ ■ Update Batching Additional Oracle Performance Extensions Update Batching You can reduce the number of round-trips to the database. Note: The JDBC 2. Oracle JDBC driver will throw exceptions when you mix these. independent of the JDBC 2. you can use one model or the other. implementing the JDBC 2. when you are repeating the same statement with different bind variables.0 specification refers to update batching as batch updates. This is referred to as update batching.0 specification. This is especially useful with prepared statements. DELETE.23 Performance Extensions This chapter describes the Oracle performance extensions to the Java Database Connectivity (JDBC) standard. which is referred to as Oracle update batching Note: ■ It is important to be aware that you cannot mix these models. Oracle JDBC supports two distinct models for update batching: ■ The standard model. or INSERT statements into a single batch and having the whole batch sent to the database and processed in one trip. but not both.

Use standard update batching if portability is a higher priority than performance. The batch value is the number of operations you want to add to a batch for each trip to the database. For any individual prepared statement object. To adhere to the JDBC 2. ■ ■ Standard update batching is a manual. In this sense.Update Batching Overview of Update Batching Models This section compares and contrasts the general models and types of statements supported for standard update batching and Oracle update batching. If you want to use update batching. ■ ■ 23-2 Oracle Database JDBC Developer's Guide and Reference . when you are repeating the same statement with different bind variables. then you can choose between the two models on the basis of the following: ■ Use Oracle update batching if portability is not critical. INSERT.0 standard. the batch is processed. and the connection default batch value is overridden with a value of 1. and generic statements. explicit model. or DELETE operations. For a callable statement. Oracle implementation of standard update batching supports callable statements. overriding both the connection batch value and the statement batch value. You can migrate standard update batching into an Oracle JDBC application without difficulty. update batching is intended for use with prepared statements. and then. the standard model is more dynamic in nature. Be aware of the following: ■ Oracle update batching supports only prepared statement objects. In this sense. the driver has no way of knowing in advance how many operations will be batched. Note the following: ■ You can set a default batch for the connection object. You can batch only UPDATE. In an Oracle generic statement. Oracle update batching is a more efficient model because the driver knows ahead of time how many operations will be batched. without OUT parameters. explicitly choose when to process the batch. which applies to any prepared statement run in that connection. There is no batch value. This will probably result in the greatest performance improvement. as well as prepared statements. You manually add operations to the batch. You can choose to explicitly process a batch at any time. the Oracle model is more static and predictable. Oracle Model Versus Standard Model Oracle update batching uses a batch value that typically results in implicit processing of a batch. With the standard model. you can set a statement batch value that overrides the connection batch value. As soon as that many operations have been added to the batch. ■ Types of Statements Supported As implemented by Oracle. there is no statement batch value. both the connection default batch value and the statement batch value are overridden with a value of 1. Processing a batch that includes an operation that attempts to return a result set will cause an exception.

The JDBC driver will throw an exception when you mix these. Regardless of the batch value in effect. The statement receives a close request. and this batch value applies to any Oracle prepared statement in the connection. instead of the JDBC driver running a prepared statement each time the executeUpdate method is called. In case an error occurs while you are processing a batch. Although Oracle JDBC supports the use of standard batching syntax for Statement and CallableStatement objects. A method in the OracleConnection class enables you to set a default batch value for the Oracle connection as a whole. Performance Extensions 23-3 ■ ■ . Oracle JDBC driver automatically runs the sendBatch method of an Oracle prepared statement in any of the following circumstances: – – – The connection receives a COMMIT request. Disable auto-commit mode if you use either update batching model. the driver adds the statement to a batch of accumulated processing requests. then each batch of 10 operations will be sent to the database and processed in one trip. a method in the OraclePreparedStatement class enables you to set a statement batch value that overrides the connection batch value. With Oracle update batching. Note: ■ Do not mix standard update batching with Oracle update batching in the same application. The connection receives a close request. you will see performance improvement for only PreparedStatement objects. if any of the bind variables of an Oracle prepared statement is a stream type. Batch values between 5 and 30 tend to be the most effective. if the batch value is 10. there is no statement batch value and the connection batch value is 1. Oracle Update Batching The Oracle update batching feature associates a batch value with each prepared statement object. For any particular Oracle prepared statement. then Oracle JDBC driver sets the batch value to 1 and sends any queued requests to the database for processing. You can also override both batch values by choosing to manually process the pending batch. The driver will pass all the operations to the database for processing once the batch value is reached. ■ Oracle Update Batching Characteristics and Limitations Note the following limitations and implementation details regarding Oracle update batching: ■ ■ By default. either as a result of calling the commit method or as a result of auto-commit mode. Setting a very high value might even have a negative effect. It is worth trying different values to verify the effectiveness for your particular application.Update Batching Note: The Oracle implementation of standard update batching does not implement true batching for generic statements and callable statements. this provides you the option of committing or rolling back the operations that ran successfully prior to the error. For example.

■ If the connection receives a ROLLBACK request before sendBatch has been called. This will override any connection batch value set using the setDefaultExecuteBatch method of the OracleConnection instance for the connection in which the statement is processed."Oracle"). statement close. 1. and specify input values for the first row.setInt (1.getExecuteBatch()). In this example.Update Batching Note: A connection COMMIT request. the following code sets the default batch value to 20 for all prepared statement objects associated with the conn connection object: ((OracleConnection)conn). you can set the defaultBatchValue Java property if you use a Java Properties object in establishing the connection.setDefaultExecuteBatch(20).?. 2. Cast your prepared statement to OraclePreparedStatement.12). You must explicitly call clearBatch to do this. then it has no effect on a pending batch.out.println (" Statement Execute Batch Value " + ((OraclePreparedStatement)ps).setString (3. as follows: System. as follows: PreparedStatement ps = conn. For example. ps. Setting the Connection Batch Value You can specify a default batch value for any Oracle prepared statement in your Oracle connection. Note that instead of calling the setDefaultExecuteBatch method. To do this. use the setDefaultExecuteBatch method of the OracleConnection object.?)"). and apply the setExecuteBatch method."USA"). ps.OraclePreparedStatement interface on individual Oracle prepared statements. Setting the Statement Batch Value Use the following steps to set the statement batch value for a particular Oracle prepared statement.prepareStatement ("INSERT INTO dept VALUES (?. insert the getExecuteBatch method at any point in the program to check the default batch value for the statement. the batch size of the statement is set to 2. or connection close has an effect on a pending batch only if you use Oracle update batching. ((OraclePreparedStatement)ps). Even though this sets the default batch value for all the prepared statements of the connection. However. ps. then the pending batched operations are not removed. The connection batch value will apply to statement objects created after this batch value was set.setExecuteBatch(2). you can override it by calling the setExecuteBatch method of the oracle. If you wish. Write your prepared statement.jdbc.setString (2. 23-4 Oracle Database JDBC Developer's Guide and Reference . if you use standard update batching.

?. then the number of batch calls to executeUpdate will be equal to the batch value of 2. // No data is sent to the database by this call to executeUpdate System. "Oracle"). Checking the Batch Value To check the overall connection batch value of an Oracle connection instance. use the OracleConnection class getDefaultExecuteBatch method: Integer batch_val = ((OracleConnection)conn).out. The data will be sent to the database.getExecuteBatch(). System.out.setDefaultExecuteBatch (20). ps.getDefaultExecuteBatch().executeUpdate ()).println ("Number of rows updated now: " + rows).setInt (1.setString (3. Overriding the Batch Value If you want to process accumulated operations before the batch value in effect is reached. You can accomplish this by casting your connection to OracleConnection and applying the setDefaultExecuteBatch method for the connection. ps. and then process the statement. presume you set the connection batch value to 20. then no data will be sent to the database. To check the particular statement batch value of an Oracle prepared statement. 32). ps. If you send an execute-update call to the database at this point.setInt (1. 4. "Indonesia").prepareStatement ("insert into dept values (?. Override the batch value as follows: 1. int rows = ps.setString (2.close ().setString (2. Performance Extensions 23-5 . This sets the default batch value for all prepared statement objects associated with the connection to 20. then getExecuteBatch will return the connection batch value. as follows: ((OracleConnection)conn). Note: If no statement batch value has been set. then use the sendBatch method of the OraclePreparedStatement object. use the OraclePreparedStatement class getExecuteBatch method: Integer batch_val = ((OraclePreparedStatement)ps). ps.executeUpdate (). ps. 11). For this example. and the call will return 0. as follows: PreparedStatement ps = conn. ps. If you enter a set of input values for a second row and an execute-update. "Applications"). ?)").println ("Number of rows updated so far: " + ps. specify input values for the first row. Write your prepared statement. and both rows will be inserted in a single round-trip.Update Batching 3.

"USA"). If you enter a set of input values for a second operation and call executeUpdate again.out. Calling commit on the connection object in Oracle batching not only commits operations in batches that have been processed. // Execution of both previously batched executes will happen // at this point. this method returns the number of rows affected at the time the method is invoked.setInt (1. So commit effectively commits changes for all operations that have been added to a batch. If you apply the sendBatch method at this point.println ("Number of rows updated before calling sendBatch: " + rows).println (ps. the executeUpdate method of an OraclePreparedStatement object will return the number of database rows affected by the operation.out. Note that the value of rows in the println statement is 0. then the two previously batched operations will be sent to the database in a single round-trip. 23-6 Oracle Database JDBC Developer's Guide and Reference . Committing the Changes in Oracle Batching After you process the batch. as follows: ■ If an executeUpdate call results in the operation being added to the batch. but also issues an implicit sendBatch call to process all pending batches.println ("Number of rows updated by calling sendBatch: " + rows).executeUpdate (). ps.close ().setString (2. 2.setString (3. // this batch is still not executed at this point int rows = ps. you must still commit the changes. System. "Applications").Update Batching ps. 3. Update Counts in Oracle Batching In a nonbatching situation. The number of rows updated will be // returned by sendBatch.executeUpdate ()). then the method returns a value of 0. System. The ps. ps. which is 20.setString (3. then the data will still not be sent to the database. 33). because nothing was written to the database yet. System.sendBatch (). ps. This property of sendBatch is used by println to print the number of updated rows.executeUpdate method returns 0. The batch is not processed at this point. rows = ((OraclePreparedStatement)ps). The sendBatch method also returns the total number of updated rows. In an Oracle batching situation. because the batch value in effect for the statement is the connection batch value.out. "Indonesia"). presuming auto-commit is disabled as recommended. ps.

ps. ps..executeUpdate(). ods. "India").sendBatch(). Example 23–1 Oracle Update Batching The following example illustrates how you use the Oracle update batching feature. Similarly.executeUpdate().setString(3. ps. PreparedStatement ps = conn. ods. Example 23–1 illustrates the use of Oracle update batching. 23). ?.Update Batching ■ If an executeUpdate call results in the batch value being reached and the batch being processed.setString(2.setString(3. "Mongolia"). //JDBC queues this for later execution ps.close().setUser("scott"). //Change batch size for this statement to 3 ((OraclePreparedStatement)ps). "Sales"). "HR").setInt(1. "Montana").* interfaces. "USA").setString(2.setString(2.setString(3. 24). ps.setInt(1. //JDBC queues this for later execution ((OraclePreparedStatement)ps). Connection conn = ods. // JDBC sends the queued request conn. .commit(). then the method will return the total number of rows affected by all operations in the batch.prepareStatement("insert into dept values (?. conn.getConnection(). ps. "Applications"). ps. //JDBC queues this for later execution ps.setInt(1. "Blue Sky"). ?)"). the sendBatch method of an OraclePreparedStatement object returns the total number of rows affected by all operations in the batch. ps.setExecuteBatch (3). ps. ods.setInt(1. ps.driver. 26)..executeUpdate(). OracleDataSource ods = new OracleDataSource(). ps. ps.setAutoCommit(false). ps.. Performance Extensions 23-7 .setURL("jdbc:oracle:oci).setPassword("tiger"). . It assumes you have imported the oracle. //The queue size equals the batch value of 3 //JDBC sends the requests to the database ps.executeUpdate().setString(3..setString(2. ps. 25). ps.

This model. 23-8 Oracle Database JDBC Developer's Guide and Reference . then the processing stops and a java. Standard Update Batching Oracle implements the standard update batching model according to the JDBC 2. However.1). the integer array returned contains n Statement. In case an error occurs while you are processing a batch. The only option you have is to roll back the transaction. In Oracle Database 11g Release 1 (11.sql. the integer array returned contains n Statement. depending on whether or not a predetermined batch value is reached. then the second will return unexpected results: UPDATE emp SET name = "Sue" WHERE name = "Bob". In the following example. Disable auto-commit mode if you use either update batching model. this does not indicate where in the batch the error occurred. but whether an operation is added to the batch or the whole batch is processed is typically determined implicitly.SUCCESS_NO_INFO entries. If the exception is raised. if the first query is deferred due to batching. In the Oracle model. This method returns an int array of update counts. you call executeUpdate as in a nonbatching situation. unlike the Oracle update batching model. SELECT name FROM emp WHERE name = "Sue". where n is the number of elements in the batch that have been successfully executed. Note: ■ Do not mix standard update batching with Oracle update batching in the same application. depends on explicitly adding statements to the batch using an addBatch method and explicitly processing the batch using an executeBatch method.BatchUpdateException is generated. Error Reporting in Oracle Update Batching If any one of the batched operations fails to complete successfully or attempts to return a result set during an executeBatch call.1). In Oracle Database 11g Release 1 (11. just as the executeBatch method does. you can call the getUpdateCounts method on the BatchUpdateException object to retrieve the update count.0 specification.EXECUTE_FAILED entries.Update Batching Note: Updates deferred through batching can affect the results of other queries. where n is the size of the batch. this provides you the option of committing or rolling back the operations that ran successfully prior to the error. ■ Limitations in the Oracle Implementation of Standard Batching This section discusses the limitations and implementation details regarding the Oracle implementation of standard update batching. Note: The execution of the batch always stops with the first element of the batch that generates an error. Oracle JDBC driver will throw exceptions when these are mixed.

This method is specified in the standard java.addBatch().Update Batching In Oracle JDBC applications.sql. 3000).prepareStatement("INSERT INTO employees VALUES(?. stmt.setString(2. OraclePreparedStatement. pstmt.. .addBatch("INSERT INTO emp_dept VALUES(1000. but remember that in the Oracle implementation of standard update batching. Note: Remember.setInt(1. and OracleCallableStatement interfaces. pstmt. For example: . which are implemented by the oracle. the addBatch method takes a Java String with a SQL operation as input. PreparedStatement pstmt = conn. pstmt. At this point. 'Sales')").. "Sulu Simpson"). you are unlikely to see performance improvement. and CallableStatement interfaces. It simply adds the operation to the batch using the bind parameters last set by the appropriate setXXX methods. "Milo Mumford").. The Oracle implementation of standard update batching does not implement true batching for generic statements and callable statements.. respectively. the addBatch method takes no input. stmt. update batching is intended for use with prepared statements that are being processed repeatedly with different sets of bind values.jdbc. ?)"). that in the Oracle implementation of standard update batching. For a Statement object. Use the standard addBatch method to add an operation to the statement batch. update batching is used to batch multiple runs of the same statement with different sets of bind parameters. 2000). For a PreparedStatement or OraclePreparedStatement object. you will probably see no performance improvement in batching generic statements. pstmt. Adding Operations to the Batch When any statement object is first created. .addBatch(). Even though Oracle JDBC supports the use of standard batching for Statement and CallableStatement objects. pstmt. three operations are in the batch.setString(2..createStatement(). two operations are in the batch. however. pstmt. At this point. 260)").OracleStatement. 'Joe Jones')").addBatch("INSERT INTO dept VALUES(260. PreparedStatement.setInt(1. Performance Extensions 23-9 . For example: .addBatch("INSERT INTO emp VALUES(1000. its statement batch is empty. For prepared statements...Statement. This is also true for CallableStatement or OracleCallableStatement objects.. stmt. you will probably see no performance improvement in batching callable statements. Statement stmt = conn.

addBatch().. Calling commit. you can batch only repeated runs of a single prepared statement.prepareStatement("INSERT INTO employees VALUES(?.setString(2. the executeBatch method has been improved so that when an error occurs in the middle of the batch execution. Starting from Oracle Database 11g Release 1 (11. After calling addBatch.setString(2. operations are performed in the order in which they were batched. So if an error occurs in the 5th element of the batch. Processing the Batch To process the current batch of operations. the BatchUpdateExecution exception that is thrown contains the position of the error in the batch. has no effect on pending statement batches that have not been processed. .setInt(1.addBatch(). This method is specified in the standard Statement interface.1).. pstmt. "Milo Mumford"). pstmt. pstmt. Committing the Changes in the Oracle Implementation of Standard Batching After you process the batch. ?)"). "Sulu Simpson"). Clearing the Batch To clear the current batch of operations instead of processing it. otherwise there will be a SQL exception. 2000). PreparedStatement pstmt = conn. presuming auto-commit is disabled as recommended. The BatchUpdateExecution. which is extended by the standard PreparedStatement and CallableStatement interfaces.getUpdateCounts method returns an array of int containing the update counts for the updates that were executed successfully before this error occurred. This method is specified in the standard Statement interface.setInt(1. commits nonbatched operations and batched operations for statement batches that have been processed. pstmt. as in this example.executeBatch().. you must call either executeBatch or clearBatch before a call to executeUpdate. you must still commit the changes. int[] updateCounts = pstmt. but for the Oracle implementation of standard batching. ■ 23-10 Oracle Database JDBC Developer's Guide and Reference . Following is an example that repeats the prepared statement addBatch calls shown previously and then processes the batch: .Update Batching Because a batch is associated with a single prepared statement object. use the executeBatch method of the statement object. use the clearBatch method of the statement object. which is extended by the standard PreparedStatement and CallableStatement interfaces. 3000). pstmt. pstmt. Keep the following things in mind: ■ When a batch is processed.. then the size of the array returned is 4 and each value is Statement.SUCCESS_NO_INFO.

.executeBatch(). pstmt.) { int[] updateCounts = pstmt. then you have to invoke clearBatch method to clear your batches explicitly after a rollback. 2000). pstmt.setString(2. 3000). PreparedStatement pstmt = conn. ?)").. if (. then the integer array.. If you are using Oracle update batching in an earlier release..addBatch(). } else { pstmt. You must explicitly call clearBatch to reset it.. However. then you do not have to clear your batches explicitly in the code after a rollback. returned by the statement executeBatch call will always have one element for each operation in the batch.condition. all array elements have a value of -2. or update counts array.prepareStatement("INSERT INTO employees VALUES(?. "Milo Mumford"). "Sulu Simpson").setString(2... In the Oracle implementation of standard update batching. According to the JDBC 2.clearBatch()... Note: ■ If you are using Oracle update batching in Oracle Database 11g. The statement batch is not reset to empty if the connection receives a ROLLBACK request. An executeBatch call closes the current result set of the statement object.setInt(1. if one exists. pstmt. pstmt. it is not possible to know the number of rows affected in the database by each individual statement in the batch. ..Update Batching ■ ■ A clearBatch or executeBatch call resets the statement batch to empty. ■ ■ ■ Invoking clearBatch method after a rollback works for all releases. it is OK to invoke clearBatch method after a rollback. pstmt. Nothing is returned by the clearBatch method.addBatch(). the values of the array elements are as follows: ■ For a prepared statement batch. a value Performance Extensions 23-11 . } Update Counts in the Oracle Implementation of Standard Batching If a statement batch is processed successfully. pstmt.setInt(1.0 specification. ■ Following is an example that repeats the prepared statement addBatch calls shown previously but then clears the batch under certain circumstances: . Therefore..

Disabling auto-commit mode.setInt(1. then the processing stops and a java. 2000).. pstmt. the array contains the actual update counts indicating the number of rows affected by each operation. . upon successful processing of a batch. 1. which you should always do when using either update batching model Creating a prepared statement object Adding operations to the batch associated with the prepared statement object Processing the batch Committing the operations from the batch conn. pstmt. PreparedStatement pstmt = conn. pstmt. Example 23–2 illustrates the use of standard update batching. 3. 3000). 2.Update Batching of -2 indicates that the operation was successful but the number of rows affected is unknown. or true update counts in the array elements.setString(2. the array contains either all -2.BatchUpdateException is generated. 1. pstmt. or all positive integers. For a successful batch processing.close(). you should be prepared to handle either -2. pstmt. Error Handling in the Oracle Implementation of Standard Batching If any one of the batched operations fails to complete successfully or attempts to return a result set during an executeBatch call. pstmt. ■ For a generic statement batch. pstmt.setString(2. accomplishing the following steps: 1. conn. irrespective of the number rows affected by each operation. int[] updateCounts = pstmt. the server always returns the value 1 as the update count. 4.commit(). You can process the update counts array to determine if the batch processed successfully.setAutoCommit(false).sql.executeBatch(). "Milo Mumford"). For a callable statement batch. The actual update counts can be provided only in the case of generic statements in the Oracle implementation of standard batching.addBatch().addBatch(). Example 23–2 Standard Update Batching This example combines the sample fragments in the previous sections.prepareStatement("INSERT INTO employees VALUES(?. 23-12 Oracle Database JDBC Developer's Guide and Reference . ■ In your code. 5. ?)"). "Sulu Simpson").setInt(1..

Update Batching After a batch exception.prepareStatement("INSERT INTO employees VALUES(?. "Milo Mumford").setInt(1. it labels all the batched operations as failures. pstmt.. 4000). after a batch is processed: ■ For a prepared statement batch. pstmt. For a failed batch processing. it is not possible to know which operation failed. no operations in pstmt batch // Now start a batch Performance Extensions 23-13 . For example. If the batch is non-empty.0 specification. The actual update counts can be provided because Oracle JDBC cannot use true batching for generic and callable statements in the Oracle implementation of standard update batching.setString(2. // OK. This returns an int array of update counts. pstmt. However. "Stan Leland"). it is valid to have a sequence. According to the JDBC 2. you should be prepared to handle either -3 or true update counts in the array elements when an exception occurs. nonbatched processing of an operation if the statement object has a pending batch of operations. In this case. Essentially. ■ For a generic statement batch or callable statement batch. You should always perform a ROLLBACK operation in this situation. "Sulu Simpson"). You can either commit or roll back the successful operations in this situation. as you prefer. if there were 20 operations in the batch. PreparedStatement pstmt = conn. containing actual update counts of the successful operations. int scount = pstmt. The array has one element for each operation in the batch. ?)"). 3000). For example. the update counts array can be retrieved using the getUpdateCounts method of the BatchUpdateException object. pstmt. then an exception will be generated.setString(2. but because the JDBC driver does not know which operation that was. then the update counts array will have 13 elements. contents of the update counts array are as follows.setInt(1.executeUpdate().setString(2.setInt(1. and the 14th generated an exception. the update counts array is only a partial array containing the actual update counts up to the point of the error. pstmt. In your code. and each element has a value of -3. In the Oracle implementation of standard update batching. a value of -3 indicates that an operation did not complete successfully. 2000). you can intermix batched operations and nonbatched operations in a single statement object if you process nonbatched operations either prior to adding any operations to the statement batch or after processing the batch. just as the executeBatch method does. such as the following: . pstmt. it was presumably just one operation that actually failed.. the first 13 succeeded. Intermixing Batched Statements and Nonbatched Statements You cannot call executeUpdate for regular. upon failed processing of a batch. pstmt.addBatch(). you will have either a full array of -3 or a partial array of positive integers. you can call executeUpdate for a statement object only when its update batch is empty.

// property: batch flush type info.getConnection(). Premature Batch Flush Premature batch flush happens due to a change in cached metadata. "SCOTT"). such as the following: ■ ■ The initial bind was null and the following bind is not null. pstmt. . info.Update Batching pstmt.setExecuteBatch (2). "Amy Feiner").addBatch(). A scalar type is initially bound as string and then bound as scalar type or the reverse. you can set the AccumulateBatchResult property to false. 5000). A COMMIT request will affect all nonbatched operations and all successful operations in processed batches..util. OracleTypes..util. but will not affect any pending batches. The old functionality lost all these batch flush values which can be obtained now. info. pstmt batch was executed Intermixing nonbatched operations on one statement object and batched operations on another statement object within your code is permissible. // other properties .setNull (1. To switch back to the old functionality.executeUpdate().NUMBER).setURL("jdbc:oracle:oci:@"").. ods. OracleDataSource ods = new OracleDataSource(). pstmt. "test11"). pstmt. "false"). Different statement objects are independent of each other with regard to update batching operations. // OK. "TIGER"). Example 23–3 Premature Batch Flushing ((OraclePreparedStatement)pstmt).Properties info = new java. as follows: java.executeBatch().setConnectionProperties(info). int[] bcounts = pstmt.setProperty("AccumulateBatchResult".setInt(1. Connection conn = ods. int scount = pstmt. Note: The AccumulateBatchResult property is set to true by default.setString (2. The premature batch flush count is summed to the return value of the next executeUpdate or sendBatch method. Cached metadata can be changed due to various reasons.setProperty("user".Properties().. 23-14 Oracle Database JDBC Developer's Guide and Reference . pstmt.setString(2. Example 23–3 illustrates premature batch flushing.setProperty("passwd". ods.

"test33"). The extra data is stored in client-side buffers for later access by the client. // returns 0 pstmt. that is. then JDBC changes the statement Performance Extensions 23-15 . Oracle JDBC drivers support the following extensions that improve performance by reducing round-trips to the database: ■ Prefetching rows This reduces round-trips to the database by fetching multiple rows of data each time data is fetched. 22).executeUpdate (). pstmt. it receives the default row-prefetch setting from the associated connection. These extensions enable you to set the remarksReporting flag and default values for row prefetching and update batching.setInt (1. The default value is 10. pstmt. Oracle provides several extensions to connection properties objects to support these performance extensions.Additional Oracle Performance Extensions int count = pstmt. */ int count = pstmt. LONG RAW or LOBs returned through the data interface. Subsequent changes to the default connection row-prefetch setting will have no effect on the statement row-prefetch setting.executeUpdate (). */ pstmt. You can set the default connection row-prefetch value using a Properties object. When a statement object is created. ■ Suppressing database metadata TABLE_REMARKS columns This avoids an expensive outer join operation. The number of rows to prefetch can be set as desired. If a column of a result set is of data type LONG. This section covers the following topics: ■ ■ ■ Oracle Row-Prefetching Limitations Defining Column Types DatabaseMetaData TABLE_REMARKS Reporting Oracle Row-Prefetching Limitations There is no maximum prefetch setting.setString (2. ■ Specifying column types This avoids an inefficiency in the standard JDBC protocol for performing and returning the results of queries. Additional Oracle Performance Extensions In addition to update batching.executeUpdate (). Larger or smaller values may be appropriate depending on the number of rows and columns expected from the query. * returns 2 with the old batching scheme. int count = pstmt. // returns 0 /* * Premature batch flush happens here.setString (2. the streaming types. /* * returns 3 with the new batching scheme where as.setInt (1. 33). "test22").

Setting the prefetch size to 1 will decrease memory and CPU usage and cannot increase round-trips. scroll-sensitive/updatable. Increasing the prefetch size will reduce the number of round-trips required to get all the data. say. Note: ■ Do not mix the JDBC 2. It will also depend on the memory and CPU loading of the JDBC client machine. Previously. but also explicitly refetching rows in a result set through the result set refreshRow method. This saves one round-trip in select statements. Setting the prefetch size can affect the performance of an application. affecting how often automatic refetches are performed.Additional Oracle Performance Extensions row-prefetch setting to 1. If you are migrating an application from earlier releases of Oracle JDBC drivers to 10g Release 1 (10. use the useFetchSizeWithLongColumn connection property. then in the case where only zero or one row is expected. The optimum for a standalone client application will be different from a heavily loaded application server. In previous releases. However. all of the drivers benefited 23-16 Oracle Database JDBC Developer's Guide and Reference .0 fetch size application programming interface (API) and the Oracle row-prefetching API in your application. but will increase memory usage. You can use one or the other. However. and FETCH in a single round-trip.1) or later releases of Oracle JDBC drivers. A common situation that you may encounter is. but not both. the Oracle fetch size value will be overridden by any setting of the fetch size. Please consider also the speed and latency of the network connection.next()). you must be careful to avoid the error of requesting an extra fetch by writing while(rs. even if you never actually read a value of either of these types. Tuning of the prefetch size should be done along with tuning of memory management in your JVM under realistic loads of the actual application. and the window size of a scroll-sensitive result set. If you are using the JDBC Thin driver. then you should revisit the optimizations that you had done earlier. the Thin driver can fetch the first prefetch_size number of rows from the server in the very first roundtrip. because the memory usage and performance characteristics may have changed substantially. The query will return only zero or one row. which is relevant for scroll-sensitive/read-only. and scroll-insensitive/updatable result sets. Note: Starting from Oracle Database 11g Release 1 (11. This will depend on the number and size of the columns in the query and the number of rows expected to be returned. Be aware that setting the Oracle fetch size value can affect not only queries. "Supported Connection Properties" on page 8-8 ■ See Also: Defining Column Types The implementation of defineColumnType changed significantly in Oracle Database 10g.next()) instead of if(rs. EXECUTE. defineColumnType was used both as a performance optimization and to force data type conversion. because it will perform PARSE.1). you have a query that selects a unique key.

The JDBC Oracle Call Interface (OCI) and server-side internal drivers still get better performance when the application uses defineColumnType.VARCHAR. You can also use defineColumnType to control how much memory the client-side allocates or to limit the size of variable-length data.INTEGER. If necessary. as applicable. Employee. use the clearDefines method of your Statement object to clear any previous column definitions for this Statement object. Types. it will be ignored. and arrays. If this parameter is omitted.Additional Oracle Performance Extensions from calls to defineColumnType.defineColumnType(column_index. Doing this makes defineColumnType have no effect. the JDBC Thin driver no longer needs the information provided. or EmployeeArray. ■ Form of use (short) Optionally specify a form of use for the column. You cannot specify a maximum field size parameter if you are defining the column type for a structured object. ■ Maximum field size (integer) Optionally specify a maximum data length for this column. On each column.defineColumnType(column_index. This can be OraclePreparedStatement. call the defineColumnType method of your Statement object.ROWID.FORM_NCHAR to use the national character set. EmployeeRef. 3.FORM_CHAR to use the database character set or OraclePreparedStatement. For example. use: stmt. assuming stmt is an Oracle statement. Follow these general steps to define column types for a query: 1.OracleTypes class. you can disable the defineColumnType method when using the Thin driver by setting the connection property disableDefineColumnType to true. If the column is VARCHAR or equivalent and you know the length limit: stmt. The JDBC Thin driver achieves maximum performance without calls to defineColumnType.FLOAT.Types class or oracle. ■ Type name (string) For structured objects.jdbc. Type codes for standard types are identical in these two classes. or array. Performance Extensions 23-17 .VARCHAR. Starting from Oracle Database 10g. object reference. you must also specify the type name. If you try to include this parameter. Types. and OracleTypes. the default is FORM_CHAR. or OracleCallableStatement. 2. OraclePreparedStatement. OracleTypes. For example. max_size). cast your statement object to OracleStatement. If your code is used with both the JDBC Thin and OCI drivers. such as Types.sql. Do not set this connection property to true when using the JDBC OCI or server-side internal drivers. passing it these parameters: ■ ■ Column index (integer) Type code (integer) Use the static constants of the java. object references. typeCode. If necessary. typeCode).

stmt. The createStatement method of the connection returns an object of type java. It assumes you have imported the oracle.* interfaces.FORM_CHAR ). As this example shows. Calling the setMaxFieldSize method of the standard JDBC Statement class sets a restriction on the amount of data returned. they can be defined to the Types. 23-18 Oracle Database JDBC Developer's Guide and Reference .jdbc. Note: It is no longer necessary to specify a data type for each column of the expected result set. Types. Statement stmt = conn. typeName).getConnection(). In most cases. 0. For structured object. typeCode. The allowed define types for columns depend on the internal Oracle type of the column. OraclePreparedStatement.executeQuery("select ename from emp").defineColumnType(column_index. ods. ods.Additional Oracle Performance Extensions For an NVARCHAR column where the original maximum length is desired and conversion to the database character set is requested: stmt. typeCode.getString(1)). ods.CHAR or Types.defineColumnType(1. 2).Statement. Connection conn = ods.out. you must cast the Statement object.sql. Specifically.println(rset. use the executeQuery method of the statement to perform the query.defineColumnType(column_index.setURL("jdbc:oracle:thin:@localhost:1502:orcl").close(). while (rset. ResultSet rset = stmt. // Allocate only 2 chars for this column (truncation will happen) ((OracleStatement)stmt). The define-extensions use JDBC types to specify the desired types. Example 23–4 illustrates the use of this feature. All columns can be defined to their natural JDBC types. stmt. which does not have the defineColumnType and clearDefines methods.next() ) System. Example 23–4 Defining Column Types OracleDataSource ods = new OracleDataSource(). object reference. the size of the data returned will be the minimum of the following: ■ ■ ■ The maximum field size set in defineColumnType The maximum field size set in setMaxFieldSize The natural maximum size of the data type After you complete these steps.VARCHAR. Set a maximum field size if you do not want to receive the full default length of the data. and array columns: stmt. to OracleStatement in the invocation of the defineColumnType method.setPassword("tiger").VARCHAR type code.setUser("scott").createStatement(). These methods are provided only in the OracleStatement implementation.

instead of calling setRemarksReporting. the JDBC driver does not report TABLE_REMARKS columns by default. VARCHAR2 LONG LONGRAW RAW DATE ROWID BLOB CLOB It is always valid to use defineColumnType with the original data type of the column. you must cast it to OracleConnection to use setRemarksReporting. FLOAT. you can set the remarksReporting Java property if you use a Java Properties object in establishing the connection. VARBINARY. Example 23–5 TABLE_REMARKS Reporting Assuming conn is the name of your standard Connection object. CHAR. you must call the setIncludeSynonyms method on the connection as follows: ( (oracle.OracleConnection)conn ). For this reason. REAL.sql. TIMESTAMP.setRemarksReporting(true). because this necessitates an expensive outer join. DECIMAL. NUMERIC. If you are using a standard java. the following statement enables TABLE_REMARKS reporting: ( (oracle. and getTables methods of the database metadata classes are slow if they must report TABLE_REMARKS columns.setIncludeSynonyms(true) Performance Extensions 23-19 . TIME. BINARY VARBINARY. SMALLINT.driver. VARCHAR CHAR.jdbc. BINARY LONG. VARNUM CHAR.Connection object. You can enable TABLE_REMARKS reporting by passing a true argument to the setRemarksReporting method of an OracleConnection object. Table 23–1 Valid Column Type Specifications You can use defineColumnType to define it as: BIGINT. the getColumns method does not retrieve information about the columns if a synonym is specified.jdbc. DatabaseMetaData TABLE_REMARKS Reporting The getColumns. CHAR. VARCHAR If the column has Oracle SQL type: NUMBER. getProcedureColumns. Equivalently. Example 23–5 illustrates how to enable TABLE_REMARKS reporting.OracleConnection)conn ).Additional Oracle Performance Extensions Table 23–1 lists the valid column definition arguments you can use in the defineColumnType method. VARCHAR. DOUBLE. VARCHAR CHAR. LONGVARCHAR LONGVARBINARY. VARCHAR ROWID VARBINARY. Considerations for getColumns By default. getProcedures. BINARY DATE. To enable the retrieval of information if a synonym is specified. CHAR. INTEGER. TINYINT.

which is the catalog parameter. bear in mind that if includeSynonyms is true. retrieves procedures and arguments without a package.1 and 1. then the name of the object returned in the table_name column will be the synonym name. but it does have packages. Considerations for getProcedures and getProcedureColumns Methods According to JDBC versions 1. This is true even if you pass the table name to getColumns. the construct " ". the construct " " will raise an exception. and the output.2. is interpreted on input to mean the objects in the current schema. Consequently. the catalog parameter should be a package name pattern. In the Oracle definition of these methods. the construct " ". Thus. the catalog parameter is treated as the package name. that is. columnNamePattern. return information about both standalone and packaged objects. On input. which is an empty string. That is. This is similar to the remarksReporting connection property. Thus. schemaPattern. that is. 23-20 Oracle Database JDBC Developer's Guide and Reference . null has the same effect as passing in percent sign (%). To be consistent with the behavior of the catalog parameter. if a synonym exists. To be consistent with the behavior of other parameters. with SQL wild cards. Alternatively. that is.Additional Oracle Performance Extensions This will cause all subsequent getColumns method calls on the connection to include synonyms. ■ procedureNamePattern and columnNamePattern The empty string (" ") does not make sense for either parameter. so it does not make sense to return information for those objects without one. the one to which you are currently connected. However. it has the same effect as passing in the percent sign (%). and procedureNamePattern parameters in the same way. the methods getProcedures and getProcedureColumns treat the catalog. null is interpreted to drop the schema from the selection criteria. ■ schemaPattern All objects within Oracle database must have a schema. This applies both on input. That is. standalone objects. the parameters are treated differently: ■ catalog Oracle does not have multiple catalogs. Otherwise. because all procedures and arguments must have names. A null value means to drop from the selection criteria. it has the same effect as passing in %. you can set the includeSynonyms connection property. This is similar to setRemarksReporting. which is the catalog column in the returned ResultSet. if desired. It can also be used as a pattern with SQL wild cards. which is an empty string.

Oracle recommends using the implicit connection cache functionality. thereby achieving a high degree of scalability by pooling of connections and back-end Oracle server processes. A JDBC application can have multiple pools at the same time. The Oracle sessions are the OracleOCIConnection objects obtained from OracleOCIConnectionPool. The connection pool itself is usually configured with a much smaller shared pool of physical connections. This chapter contains the following sections: ■ ■ ■ ■ ■ ■ ■ OCI Driver Connection Pooling: Background OCI Driver Connection Pooling and Shared Servers Compared Defining an OCI Connection Pool Connecting to an OCI Connection Pool Sample Code for OCI Connection Pooling Statement Handling and Caching JNDI and the OCI Connection Pool Note: Use OCI connection pooling if you need session multiplexing. OCI Connection Pooling 24-1 . such as the fine-grained management of Oracle sessions and connections.24 OCI Connection Pooling The Java Database Connectivity (JDBC) Oracle Call Interface (OCI) driver connection pooling functionality is part of the JDBC client. This functionality is provided by the OracleOCIConnectionPool class. The connection pooling provided by the JDBC OCI driver enables applications to have multiple logical connections. translating to a back-end server pool containing an identical number of dedicated server processes. Multiple pools can correspond to multiple application servers or pools to different data sources. Otherwise. The connection pooling provided by the OracleOCIConnectionPool interface simplifies the session/connection separation interface hiding the management of the physical connection pool. all using a small set of physical connections. It is possible for a high-end application server or transaction monitor to multiplex several sessions over fewer physical connections on a call-level basis. OCI Driver Connection Pooling: Background The Oracle JDBC OCI driver provides several transaction monitor capabilities. Each call on a logical connection gets routed on to the physical connection that is available at the time of call.

ora configuration file. From an OracleOCIConnectionPool instance. On the other hand. Therefore. if suffice.OCI Driver Connection Pooling and Shared Servers Compared Note that many more Oracle sessions can be multiplexed over this pool of fewer shared connections and back-end Oracle processes. OCI Driver Connection Pooling and Shared Servers Compared In some ways. which extends the OracleDataSource class. Each thread could maintain a session to the database. pass null if the default configuration suffices. you can obtain logical connection objects. These connection objects are of the OracleOCIConnection class type. * @param p ConnectionPool password * @param name logical name of the pool. names. Note that OCI connection pool is mainly beneficial only if the middle tier is multithreaded. The actual connections to the database are maintained by OracleOCIConnectionPool.jdbc. OCI driver connection pooling makes a dedicated server instance behaves as a shared instance by managing the session multiplexing logic on the middle tier. The oracle. This class implements the OracleConnection interface.pool.OracleOCIConnectionPool class. The following code shows header information for the OracleOCIConnectionPool class: /* * @param us ConnectionPool user-id. max=1. Default connection configuration incr=0 Please refer setPoolConfig for property be one in the the default does not is min =1. This needs to * tnsnames. The dispatcher is responsible for directing the client request to an appropriate shared server. and these connections. * @return * * Notes: Choose a userid and password that can act as proxy for the users 24-2 Oracle Database JDBC Developer's Guide and Reference . what OCI driver connection pooling offers on the middle tier is similar to what shared server processes offer on the back end. is used to create OCI connection pools. The Statement objects you create from the OracleOCIConnection instance have the same fields and methods as OracleStatement objects you create from OracleConnection instances. including the pool of dedicated database server processes. the pooling of dedicated server processes and incoming connections into the dedicated server processes is controlled by the OCI connection pool on the middle tier. Creating connections from a pool is quite similar to creating connections using the OracleDataSource class. are shared among all the threads in the middle tier. Since this is optional. Defining an OCI Connection Pool An OCI connection pool is created at the beginning of the application. @param config (optional) Properties of the pool. the physical connection from the OCI connection pool is established directly from the middle tier to the Oracle dedicated server process in the back-end server pool. the connection from the client is typically to a dispatcher in the database instance. The main difference between OCI connection pooling and shared servers is that in the case of shared servers.

Defining an OCI Connection Pool * in the getProxyConnection() method.jdbc. effect CONNPOOL_MIN_LIMIT CONNPOOL_MAX_LIMIT CONNPOOL_INCREMENT then the following default values will take = 1 = 1 = 0 */ public synchronized OracleOCIConnectionPool (String user.oci.CONNPOOL_MAX_LIMIT. poolConfig).jdbc. poolConfig is a set of properties that specify the connection pool. password and connection pool name values set LATER using the methods setUser. import oracle. "4"). setPassword later. If config is null. Properties config) /* * This will use the user-id. poolConfig. import the following to have Oracle OCI connection pooling functionality: import oracle. "10").jdbc.CONNPOOL_MIN_LIMIT. setPassword.pool and oracle. throws SQLException String name. setConnectionPoolName.oci Packages Before you create an OCI connection pool. "jdbc:oracle:oci:@(description=(address=(host= myhost)(protocol=tcp)(port=1521))(connect_data=(INSTANCE_NAME=orcl)))".pool. * @return * * Notes: No OracleOCIConnection objects can be created on this class unless the methods setUser. then the default values are used.put (OracleOCIConnectionPool. choose a userid and password that can act as proxy for the users in the getProxyConnection() method. When invoking the setUser.*. consider the following: ■ poolConfig.jdbc. setPoolConfig are invoked. If poolConfig is null. String password. Creating an OCI Connection Pool The following code show how you create an instance of the OracleOCIConnectionPool class called cpool: OracleOCIConnectionPool cpool = new OracleOCIConnectionPool ("SCOTT".*.put (OracleOCIConnectionPool. For example. * */ public synchronized OracleOCIConnectionPool () throws SQLException Importing the oracle. ■ OCI Connection Pooling 24-3 . setPassword. "TIGER".

and CONNPOOL_INCREMENT parameters are 1. OracleOCIConnectionPool cpool = new OracleOCIConnectionPool ( ).setUser("SCOTT"). that an error is returned if a call needs a physical connection while the maximum number of connections in the pool are busy. // In case you want to specify a different // configuration other than the default // values.Defining an OCI Connection Pool ■ poolConfig. CONNPOOL_MAX_LIMIT. cpool. Once this attribute is set to true. As an alternative to the constructor call. Setting the OCI Connection Pool Parameters The connection pool configuration is determined by the following OracleOCIConnectionPool class attributes: ■ CONNPOOL_MIN_LIMIT Specifies the minimum number of physical connections that can be maintained by the pool. cpool. if enabled. If disabled. Note: The default values for the CONNPOOL_MIN_LIMIT. the increment is done only when the total number of open physical connections is less than the maximum number that can be opened in that pool. an application has the flexibility of reading the current load. ■ CONNPOOL_TIMEOUT Specifies how much time must pass before an idle physical connection is disconnected.put (OracleOCIConnectionPool. 24-4 Oracle Database JDBC Developer's Guide and Reference .setURL("jdbc:oracle:oci:@(description=(address=(host= myhost)(protocol=tcp)(port=1521))(connect_data=(INSTANCE_NAME=orcl)))"). ■ CONNPOOL_NOWAIT Specifies. cpool. you can create an instance of the OracleOCIConnectionPool class using individual methods to specify the user. ■ CONNPOOL_MAX_LIMIT Specifies the maximum number of physical connections that can be maintained by the pool. using the setPoolConfig method.setPoolConfig(poolConfig). and adjusting these attributes appropriately. it cannot be reset to false. cpool. this does not affect a logical connection. You can configure all of these attributes dynamically.setPassword("TIGER"). password. Therefore. and connection string. a call waits until a connection is available. and 0.CONNPOOL_INCREMENT. respectively. ■ CONNPOOL_INCREMENT Specifies the incremental number of physical connections to be opened when all the existing ones are busy and a call needs one more connection. "2"). 1. that is number of open connections and number of busy connections.

put (OracleOCIConnectionPool. the age of a connection is based on the Least Recently Used (LRU) algorithm.util.CONNPOOL_MIN_LIMIT. p.CONNPOOL_TIMEOUT. ■ int getConnectionIncrement() Retrieves the incremental number of physical connections to be opened when all the existing ones are busy and a call needs a connection.Properties p = new java. "true"). CONNPOOL_NOWAIT must be true or false. p. . CONNPOOL_MIN_LIMIT must be a value greater than zero. "1").util. p... Observe the following rules when setting these attributes: ■ CONNPOOL_MIN_LIMIT. ■ int getPoolSize() OCI Connection Pooling 24-5 . "5"). ■ int getTimeout() Retrieves the specified time (in seconds) that a physical connection in a pool can remain idle before it is disconnected. java.setPoolConfig(p). p.put (OracleOCIConnectionPool.put (OracleOCIConnectionPool. "2"). The following is a typical example of how the OracleOCIConnectionPool class attributes can be set: . It returns a string of "true" or "false". CONNPOOL_INCREMENT must be a value greater than or equal to zero.CONNPOOL_INCREMENT. use the following methods from the OracleOCIConnectionPool class: ■ int getMinLimit() Retrieves the minimum number of physical connections that can be maintained by the pool. and CONNPOOL_INCREMENT are mandatory.CONNPOOL_NOWAIT.Properties( ). "10"). CONNPOOL_TIMEOUT must be a value greater than zero. CONNPOOL_MAX_LIMIT. p.CONNPOOL_MAX_LIMIT.put (OracleOCIConnectionPool.put (OracleOCIConnectionPool. See Also: ■ ■ ■ ■ ■ Oracle Call Interface Programmer's Guide Checking the OCI Connection Pool Status To check the status of the connection pool. CONNPOOL_MAX_LIMIT must be a value greater than or equal to CONNPOOL_MIN_LIMIT plus CONNPOOL_INCREMENT.Defining an OCI Connection Pool The setPoolConfig method is used to configure OCI connection pool properties. ■ String getNoWait() Retrieves if the NOWAIT property is enabled. cpool... ■ int getMaxLimit() Retrieves the maximum number of physical connections that can be maintained by the pool.

There are two ways of calling getConnection: ■ OracleConnection getConnection() If you do not supply the user name and password. password. setPassword. otherwise. String p) throws SQLException As an enhancement to OracleConnection. ■ boolean isPoolCreated() Retrieves if the pool has been created. String password) If you this method. then the default user name and password used for the creation of the connection pool are used while creating the connection objects. This should be used only as an estimate and for statistical analysis. The pool is actually created when OracleOCIConnection(user. they are closed when the pool instance is closed. The following code shows the signatures of the overloaded getConnection method: public synchronized OracleConnection getConnection( ) throws SQLException /* * For getting a connection to the database. creates an instance of the OracleOCIConnection class. it has the functionality of this class too. String oldPassword. the following new method is added into OracleOCIConnection as a way to change the password for the user: void passwordChange (String user. which can be different from that used for pool creation. ■ int getActiveSize() Retrieves the number of physical connections that are open and busy. through a getConnection method call. * * @param us Connection user-id * @param p Connection password * @return connection object */ public synchronized OracleConnection getConnection(String us. Close the OracleOCIConnection objects once the user session is over. This instance represents a connection. String newPassword) 24-6 Oracle Database JDBC Developer's Guide and Reference . you will get a logical connection identified with the specified user name and password. and setURL has been done after calling OracleOCIConnection(). Because the OracleOCIConnection class extends OracleConnection class. poolConfig) is called or when setUser. url. Connecting to an OCI Connection Pool The OracleOCIConnectionPool class.Connecting to an OCI Connection Pool Retrieves the number of physical connections that are open. ■ OracleConnection getConnection(String user. This should be used only as an estimate and for statistical analysis.

start ().println("Unable to create connection. "tiger"). java.com".OracleDriver. ++i) { conn[i] = cpool.out. Integer. String s = null. Thread []t = new Thread[_maxCount].DriverManager.pool.").sql.CONNPOOL_MIN_LIMIT. try { DriverManager.println ("-. OCI Connection Pooling 24-7 .setPoolConfig(p1).toString(1)). return. oracle.getProperty ("JDBC_URL"). p1.sql.The default configuration for the OracleOCIConnectionPool --").out.put (OracleOCIConnectionPool.Connection. //displayPoolConfig(cpool). "tiger". Integer. t[i].PreparedStatement. Integer. conn[i]).put (OracleOCIConnectionPool.SQLException. //String url = ( s == null ? "jdbc:oracle:oci8:@orcl" : s). Connection []conn = new Connection[_maxCount]. public class conPoolAppl extends Thread { public static final String query = "SELECT object_name FROM all_objects WHERE rownum < 300". null).CONNPOOL_MAX_LIMIT.Properties. } t[i] = new conPoolAppl (i. url.jdbc.sql.util. java. // Print out the default configuration for the OracleOCIConnectionPool System. if ( conn[i] == null ) { System. for (int i = 0. // Enable the initial configuration cpool.sql. String url = "jdbc:oracle:oci8:@orcl. //System. static public void main(String args[]) throws SQLException { int _maxCount = 10.Sample Code for OCI Connection Pooling Sample Code for OCI Connection Pooling The following code illustrates the use of OCI connection pooling in a sample application: import import import import import import import import java. p1.ResultSet. p1.registerDriver(new OracleDriver()).toString(_maxCount)).OracleOCIConnectionPool. oracle. i < _maxCount.put (OracleOCIConnectionPool.jdbc. java.toString(1)).rmmslang.CONNPOOL_INCREMENT.getConnection("scott". displayPoolConfig(cpool). java.sql. OracleOCIConnectionPool cpool = new OracleOCIConnectionPool("scott". java. //Set up the initial pool configuration Properties p1 = new Properties().

println ("*** Thread id: " + m_threadId).printStackTrace (). private int m_threadId. } } // end of run private static void doQuery (Connection conn) throws SQLException { PreparedStatement pstmt = null. } catch (SQLException ea) { System. m_conn = conn.startAllThreads (). i < _maxCount. ResultSet rs = null. ea. public conPoolAppl (int i. } catch(Exception ex) { System. } catch (Exception ea) {} displayPoolConfig(cpool). i < _maxCount. for (int i = 0.yield ().println("Error: " + ex).out. ++i) if (conn[i] != null) conn[i]. ++i) t[i].Sample Code for OCI Connection Pooling } ((conPoolAppl)t[0]).out. Connection conn) { m_threadId = i. } public void run () { while (!m_startThread) Thread.close (). private static boolean m_startThread = false. try { doQuery (m_conn). } finally { for (int i = 0.printStackTrace (). ex. try { Thread. 24-8 Oracle Database JDBC Developer's Guide and Reference . return.sleep (200). } } //end of main private Connection m_conn.join (). } public void startAllThreads () { m_startThread = true.

and close cursors.close ().out.println (" Timeout: " + cpool.out.Statement Handling and Caching try { pstmt = conn. System.prepareStatement ("a_SQL_query") is processed. If a match is found. The default cache size is zero.println ("Object name: " +rs.println (" ActiveSize: " + cpool.prepareStatement (query). System.out. } finally { if (rs != null) rs.getMinLimit()).out.out. then you can reuse the Statement object instead of incurring the cost of creating another Statement object.out. Note: The OracleStatement object created from OracleOCIConnection has the same behavior as one that is created from OracleConnection.getTimeout()).println (" Connection Increment: " + cpool. parse.println ("Error during execution: " +ea).println (" PoolSize: " + cpool.getPoolSize()). while (rs.println (" NoWait: " + cpool.close (). ea. OCI Connection Pooling 24-9 .executeQuery (). When OracleOCIConnection.getNoWait()). /* System. } } // end of class conPoolAppl Statement Handling and Caching Statement caching is supported with OracleOCIConnectionPool.getString (1)). System. if (pstmt != null) pstmt.out.out. } } catch (Exception ea) { System.getActiveSize()). The caching improves performance by not having to open.println (" Min poolsize Limit: " + cpool.next ()) { //System.println (" Max poolsize Limit: " + cpool.close (). } } // end of doQuery (Connection) // Display the current status of the OracleOCIConnectionPool private static void displayPoolConfig (OracleOCIConnectionPool cpool) throws SQLException { System. rs = pstmt.out. if (conn != null) conn.getConnectionIncrement()). The cache size can be dynamically increased or decreased. System.getMaxLimit()).printStackTrace (). the statement cache is searched for a statement that matches the SQL query. */ System.

bind method makes the properties persist. No new interface calls in OracleOCIConnectionPool are necessary. The InitialContext.JNDI and the OCI Connection Pool JNDI and the OCI Connection Pool The Java Naming and Directory Interface (JNDI) feature makes the properties of a Java object persist. either on file or in a database.lookup method retrieves the properties from the persistent store and creates a new object with these properties. and at a later time a new object with exactly the same properties can be created. OracleOCIConnectionPool objects can be bound and looked up using the JNDI feature. 24-10 Oracle Database JDBC Developer's Guide and Reference . such as cloning the object. while the InitialContext. The benefit is that the old object can be freed. therefore these properties can be used to construct a new instance of the object.

1) provides a fast Java interface to AQ by introducing a new Java package.aq.25 Oracle Advanced Queuing Oracle Advanced Queuing (AQ) provides database-integrated message queuing functionality. all operational benefits of high availability. This package contains the following: ■ Classes – AQDequeueOptions Specifies the options available for the dequeue operation – AQEnqueueOptions Specifies the options available for the enqueue operation – AQFactory Is a factory class for AQ – AQNotificationEvent Is created whenever a new message is enqueued in a queue for which you have registered your interest Oracle Advanced Queuing 25-1 . See Also: Oracle Streams Advanced Queuing User's Guide This chapters covers the following topics: ■ ■ ■ ■ ■ ■ Functionality and Framework of Oracle Advanced Queuing AQ Asynchronous Event Notification Creating Messages Enqueuing Messages Dequeuing Messages Examples: Enqueuing and Dequeuing Functionality and Framework of Oracle Advanced Queuing Oracle Database 11g Release 1 (11. propagated between queues on different computers and databases.jdbc. and transmitted using Oracle Net Services. This chapter provides information about the Java interface to Oracle AQ. HTTP. scalability. and reliability are also applicable to queue data. Because Oracle AQ is implemented in database tables. It is built on top of Oracle Streams and optimizes the functions of Oracle Database so that messages can be stored persistently. oracle. and HTTPS.

and Priority and Ordering – AQNotificationListener Is a listener interface for receiving AQ notification events – AQNotificationRegistration Represents your interest in being notified when a new message is enqueued in a particular queue These classes and interfaces enable you to access an existing queue.1. AQ_ADMINISTRATOR_ROLE TO SCOTT. create messages. 25-2 Oracle Database JDBC Developer's Guide and Reference . and enqueue and dequeue messages. Delay and Expiration. Recipients. ADMINISTER DATABASE TRIGGER TO SCOTT. EXECUTE ON DBMS_AQADM to SCOTT. Clients do not need to be connected to a database. Sender. It shows how to enqueue and dequeue from a RAW type single-consumer and multiple-consumer queue. In this example. the SCOTT user is connecting to the database. you must grant the following privileges to the user: GRANT GRANT GRANT GRANT EXECUTE ON DBMS_AQ to SCOTT. Therefore. Queues must be created through the DBMS_AQADM PL/SQL package.AQ Asynchronous Event Notification ■ Interfaces – AQAgent Used to represent and identify a user of the queue or a producer or consumer of the message – AQMessage Represents a message that is enqueued or dequeued – AQMessageProperties Contains message properties such as Correlation. See Also: AQ Asynchronous Event Notification A JDBC application can do the following: ■ Register interest in notifications in the AQ namespace and receive notifications when an enqueue occurs Register interest in subscriptions to database events and receive notifications when the events are triggered ■ Registered clients are notified asynchronously when events are triggered or on an explicit AQ enqueue (or a new message is enqueued in a queue for which you have registered your interest). in the database. Example Example 25–1 illustrates the use of the new JDBC AQ interface which is new feature of the JDBC Thin driver in release 11. For more information about the APIs. refer to the Javadoc. Note: Oracle JDBC drivers do not provide any API to create a queue. It also shows how AQ asynchronous notification works.

null). public static final void main(String[] argv) { DemoAQRawQueue demo = new DemoAQRawQueue(). */ void demoSingleConsumerQueue(OracleConnection connection) throws SQLException { System.printStackTrace(). connection.com) (PORT=1521))"+"(CONNECT_DATA=(SERVICE_NAME=mydatabaseinstance)))".AQ Asynchronous Event Notification Example 25–1 AQ Asynchronous Event Notification Example import java.RAW_SINGLE_QUEUE". static final String PASSWORD= "tiger". import oracle. dequeue(connection.setAutoCommit(false).queueName.close().out.queueName. try { demo. import oracle.jdbc.aq. String queueName = USERNAME+". static final String URL = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=oracleserver.queueType.util. } } void run() throws SQLException { OracleConnection connection = connect(). cleanup(connection). import java.mydomain . // run the demo for multi consumer queue: demoMultipleConsumerQueue(connection).run(). setup(connection). The AQ listener will be notified that a new message has arrived * in the queue and it will dequeue it. String queueType = "RAW". enqueueDummyMessage(connection. public class DemoAQRawQueue { static final String USERNAME= "scott".*.println("\n ============= Start single consumer queue demo ============= \n").jdbc. }catch(SQLException ex) { ex.sql. connection. * Then it registers for AQ notification on this same queue and enqueues a * message again. AQNotificationRegistration reg = registerForAQEvents( Oracle Advanced Queuing 25-3 .*.null).Properties.*. // run the demo for single consumer queue: demoSingleConsumerQueue(connection). } /** * Single consumer queue demo: * This method enqueues a dummy message into the RAW_SINGLE_QUEUE queue and dequeues it.

It * then enqueues a message for "RED" and "BLUE" */ void demoMultipleConsumerQueue(OracleConnection connection) throws SQLException { System. String queueType = "RAW".currentThread().closeConnection()."RED").out.queueType). DemoAQRawQueueListener single_li = new DemoAQRawQueueListener( queueName.currentThread().closeConnection().getEventsCount() < 1) { try { Thread.sleep(1000).queueName+":BLUE"). reg.unregisterAQNotification(reg). AQAgent[] recipients = new AQAgent[2]. connection.println("\n ============= Start multi consumer queue demo ============= \n"). recipients[1] = AQFactory.queueName.queueName.getEventsCount() < 1) { try { Thread. multi_li. reg.RAW_MULTIPLE_QUEUE". while(single_li. connection.createAQAgent().createAQAgent(). } catch (InterruptedException e) { } } single_li.commit(). AQNotificationRegistration reg = registerForAQEvents( connection. enqueueDummyMessage(connection.sleep(1000). recipients[0]. } catch (InterruptedException e) { } } dequeue(connection.recipients).setName("RED").null). } 25-4 Oracle Database JDBC Developer's Guide and Reference . String queueName = USERNAME+". enqueueDummyMessage(connection.queueType). recipients[1].addListener(multi_li).setName("BLUE").commit().addListener(single_li). DemoAQRawQueueListener multi_li = new DemoAQRawQueueListener( queueName.queueType. connection. while(multi_li.queueName).unregisterAQNotification(reg).queueName. connection.AQ Asynchronous Event Notification connection. } /** * Multi consumer queue demo: * This method first registers for AQ notification upon the agent "BLUE". recipients[0] = AQFactory.

msgprop.setAddress("MY_SENDER_AGENT_ADDRESS"). } /** * This methods dequeues the next available message from the queue specified * by "queueName".setExceptionQueue("MY_EXCEPTION_QUEUE"). // We want to retrieve the message id after enqueue: AQEnqueueOptions opt = new AQEnqueueOptions(). ag.setRecipientList(recipients).sql.out. // execute the actual enqueue operation: conn.i++) rawPayload[i] = 'b'. AQAgent[] recipients) throws SQLException { System.setRetrieveMessageId(true).setCorrelation("mycorrelation"). } System.getMessageId().i<rawPayload. System.length.println("----------.println(msgprop. for(int i=0. String queueName.out. // and add a payload: byte[] rawPayload = new byte[500].setName("MY_SENDER_AGENT_NAME"). System. if(mesgId != null) { String mesgIdStr = byteBufferToHexString(mesgId.RAW(rawPayload)).Enqueue done ------------").println("Message ID from enqueue call: "+mesgIdStr).opt. String consumerName ) throws SQLException { Oracle Advanced Queuing 25-5 .Enqueue start ------------").AQ Asynchronous Event Notification /** * This method enqueues a dummy message in the queue specified by its name.out. ag.createAQMessageProperties().out. // First create the message properties: AQMessageProperties msgprop = AQFactory.setPayload(new oracle. // Create the actual AQMessage instance: AQMessage mesg = AQFactory.toString()). msgprop. opt.20).enqueue(queueName. byte[] mesgId = mesg. // Specify an agent as the sender: AQAgent ag = AQFactory. String queueName.mesg).setSender(ag). msgprop.createAQMessage(msgprop). */ public void dequeue(OracleConnection conn.println("----------. String queueType. */ public void enqueueDummyMessage(OracleConnection conn.createAQAgent(). mesg. // handle multi consumer case: if(recipients != null) msgprop.

RAW_SINGLE_QUEUE_TABLE').registerAQNotification(queueNameArr.out. System. "BEGIN "+ "DBMS_AQADM.setRetrieveMessageId(true).out. opt[0].out."true"). "+ " QUEUE_PAYLOAD_TYPE => 'RAW'. opt[0] = new Properties().length+".toString()). AQNotificationRegistration[] regArr = conn.RAW_SINGLE_QUEUE'.println("payload. queueNameArr[0] = queueName.opt.CREATE_QUEUE( "+ " QUEUE_NAME => '"+USERNAME+".NTF_AQ_PAYLOAD. "+ " QUEUE_TABLE => '"+USERNAME+".getMessageId(). "BEGIN "+ "DBMS_AQADM.queueType). System. ").out.Dequeue start ------------"). // print out the message that has been dequeued: byte[] payload = msg.0'). Properties[] opt = new Properties[1]. byte[] msgId = msg.CREATE_QUEUE_TABLE( "+ " QUEUE_TABLE => '"+USERNAME+". if(consumerName != null) deqopt.getPayload().RAW_SINGLE_QUEUE_TABLE'.globalOptions). "+ "END. "+ " COMPATIBLE => '10.20).println("ID of message dequeued = "+mesgIdStr). deqopt.println("----------.println("----------. } public AQNotificationRegistration registerForAQEvents( OracleConnection conn. String payloadStr = new String(payload.0. AQDequeueOptions deqopt = new AQDequeueOptions().length="+payload.dequeue(queueName.10). if(msgId != null) { String mesgIdStr = byteBufferToHexString(msgId. System. AQNotificationRegistration reg = regArr[0].out.println(msgProp. value="+payloadStr). "+ 25-6 Oracle Database JDBC Developer's Guide and Reference .setProperty(OracleConnection. System.Dequeue done ------------").deqopt. doUpdateDatabase(conn.AQ Asynchronous Event Notification System. } /** * */ private void setup(Connection conn) throws SQLException { doUpdateDatabase(conn. return reg. String[] queueNameArr = new String[1]. String queueName) throws SQLException { Properties globalOptions = new Properties().getMessageProperties(). } AQMessageProperties msgProp = msg. // dequeue operation: AQMessage msg = conn.setConsumerName(consumerName).

STOP_QUEUE('"+USERNAME+". // create a multi consumer RAW queue: doUpdateDatabase(conn.RAW_MULTIPLE_QUEUE'. "+ " FORCE => TRUE). "+ "END. "BEGIN "+ " DBMS_AQADM. "BEGIN "+ " DBMS_AQADM. tryUpdateDatabase(conn.RAW_SINGLE_QUEUE'). */ Oracle Advanced Queuing 25-7 .START_QUEUE('"+USERNAME+". "). "BEGIN "+ "DBMS_AQADM. "+ " MULTIPLE_CONSUMERS => TRUE. tryUpdateDatabase(conn. ").AQ Asynchronous Event Notification "END. "BEGIN "+ " DBMS_AQADM. "+ "END. "+ "END. tryUpdateDatabase(conn.RAW_MULTIPLE_QUEUE'). "+ "END.RAW_MULTIPLE_QUEUE_TABLE'). "+ " QUEUE_TABLE => '"+USERNAME+". "+ "END. "+ "END. "+ " QUEUE_PAYLOAD_TYPE => 'RAW'.RAW_SINGLE_QUEUE_TABLE'. "+ " COMPATIBLE => '10.STOP_QUEUE('"+USERNAME+". "). "BEGIN "+ " DBMS_AQADM. "+ "END.RAW_MULTIPLE_QUEUE_TABLE'. doUpdateDatabase(conn. doUpdateDatabase(conn.START_QUEUE('"+USERNAME+".CREATE_QUEUE_TABLE( "+ " QUEUE_TABLE => '"+USERNAME+". "). "BEGIN "+ " DBMS_AQADM. "+ "END. "+ " FORCE => TRUE). "). } void cleanup( Connection conn) { tryUpdateDatabase(conn.RAW_MULTIPLE_QUEUE_TABLE'. } /** * Creates a connection the database. "). "BEGIN "+ " DBMS_AQADM.RAW_SINGLE_QUEUE'). ").0').DROP_QUEUE_TABLE( "+ " QUEUE_TABLE => '"+USERNAME+". ").RAW_MULTIPLE_QUEUE'). "). "BEGIN "+ "DBMS_AQADM. doUpdateDatabase(conn.CREATE_QUEUE( "+ " QUEUE_NAME => '"+USERNAME+".DROP_QUEUE_TABLE( "+ " QUEUE_TABLE => '"+USERNAME+".

createStatement().USERNAME).prop).String sql) { Statement stmt = null. stmt.close(). */ private void doUpdateDatabase(Connection conn. try { stmt = conn. } /** * Utility method: executes a DML query but doesn't throw any exception if * an error occurs. prop.createStatement(). }catch(SQLException sqlex) { System.connect(DemoAQRawQueue.close(). } finally { if(stmt != null) { try { stmt.PASSWORD).DemoAQRawQueue.URL. }catch(SQLException exx){} } } } 25-8 Oracle Database JDBC Developer's Guide and Reference .executeUpdate(sql).DemoAQRawQueue.setProperty("password".AQ Asynchronous Event Notification OracleConnection connect() throws SQLException { OracleDriver dr = new OracleDriver().getMessage()+") while trying to execute \""+sql+"\""). stmt.setProperty("user". try { stmt = conn. prop. }catch(SQLException exx){exx. Properties prop = new Properties(). } finally { if(stmt != null) { try { stmt.String sql) throws SQLException { Statement stmt = null.} } } } /** * Utility method: executes a DML query and throws an exception if * an error occurs.printStackTrace().executeUpdate(sql).out. return (OracleConnection)dr. */ private void tryUpdateDatabase(Connection conn.println("Exception ("+sqlex.

String hexrep = Integer. String typeName.setRetrieveMessageId(true). conn = (OracleConnection)DriverManager. return ret. DemoAQRawQueue. String _typeName) throws SQLException { queueName = _queueName.getConnection (DemoAQRawQueue. int eventsCount = 0. System.toString()).AQ Asynchronous Event Notification static final String byteBufferToHexString(byte[] buffer. try { AQDequeueOptions deqopt = new AQDequeueOptions(). int offset = 0.getMessageProperties()). } } class DemoAQRawQueueListener implements AQNotificationListener { OracleConnection conn.toHexString((int)buffer[offset]&0xFF). StringBuffer sb = new StringBuffer().println("----------.").println("\n----------. if(e. System. else isFirst = false.getConsumerName()).getConsumerName() != null) deqopt. } String ret= sb.setConsumerName(e.URL.toString().append(' '). public DemoAQRawQueueListener(String _queueName.length && offset < maxNbOfBytes) { if(!isFirst) sb. sb. offset++. int maxNbOfBytes) { if(buffer == null) return null.setDeliveryMode(AQDequeueOptions. System. deqopt.USERNAME. if((e. typeName = _typeName. } public void onAQNotification(AQNotificationEvent e) { System. DemoAQRawQueue.PASSWORD).out.MESSAGE_BUFFERED) { deqopt.out.append(hexrep).out.println(e.println("------------------------------------------------------").DEQUEUE_BUFFERED). if(hexrep.length() == 1) hexrep = "0"+hexrep.DemoAQRawQueueListener: got an event ----------. boolean isFirst = true. Oracle Advanced Queuing 25-9 . String queueName.out. while(offset < buffer.DemoAQRawQueueListener: Dequeue start -----------").getDeliveryMode() == AQMessageProperties.

} AQMessage msg = conn.println("----------. ■ 25-10 Oracle Database JDBC Developer's Guide and Reference .DEQUEUE_IMMEDIATE).dequeue(queueName. An AQ message contains properties (metadata) and a payload (data). Correlation: Is an identifier supplied by the producer of the message at the time of enqueuing the message. Create an instance of AQMessageProperties.length="+payload. Perform the following to create an AQ message: 1. An instance of a class implementing the AQMessage interface represents an AQ message.close(). } catch(SQLException sqlex) { System.deqopt.out.out. Set the property attributes. AQ Message Properties The properties of the AQ message are represented by an instance of the AQMessageProperties interface. } System. System. 3.getPayload().typeName). System.getMessageProperties(). You can set or get the following message properties: ■ Dequeue Attempts Count: Specifies the number of attempts that have been made to dequeue the message.println("ID of message dequeued = "+mesgIdStr).byteBufferToHexString(msgId.println("payload.length+".equals("RAW")) { String payloadStr = new String(payload. Create the AQ message using the AQMessageProperties object.getMessageId().setVisibility(AQDequeueOptions.0. 4. Set the payload.DemoAQRawQueueListener: Dequeue done -----------").println(sqlex.out. } System. value="+payloadStr).10). } eventsCount++.getMessage()).out. } } Creating Messages Before you enqueue a message.20). if(typeName.out. 2. } public void closeConnection() throws SQLException { conn. you must create the message. byte[] msgId = msg. byte[] payload = msg.println(msg. This property cannot be set. if(msgId != null) { String mesgIdStr = DemoAQRawQueue. } public int getEventsCount() { return eventsCount.toString()).Creating Messages deqopt.

this attribute identifies the ID of the queue from which it was last propagated. Sender: Is an identifier specified by the producer at the time of enqueuing the message.Creating Messages ■ Delay: Is the number of seconds for which the message is in the WAITING state.setAddress("MY_SENDER_AGENT_ADDRESS"). Exception Queue: Specifies the name of the queue into which the message is moved if it cannot be processed successfully. ■ ■ ■ ■ ■ ■ The following code snippet illustrates how to create an AQMessageProperties object and create an AQ message using it: . It can be any integer including negative integers.setPriority(1). If the message is not dequeued before it expires. Enqueue Time: Specifies the time at which the message was enqueued. This property cannot be set. Dequeuing a message by using the message ID (msgid) overrides the delay specification. Previous Queue Message ID: Is the ID of the message in the last queue that generated the current message.createAQAgent(). msgprop. // Create the message properties object AQMessageProperties msgprop = AQFactory.createAQMessageProperties().setExpiration(0). This parameter is valid only for multiple-consumer queues.setExceptionQueue("MY_EXCEPTION_QUEUE").. AQAgent ag = AQFactory. Oracle Advanced Queuing 25-11 . Message State: Specifies the state of the message at the time of dequeuing the message. Recipient list: Is a list of AQAgent objects that represent the recipients. then it is moved to the exception queue in the EXPIRED state. After the specified delay. The message has expired. This property cannot be set. ■ ■ ■ Expiration: Is the number of seconds during which the message is available for dequeuing. It is an instance of AQAgent. ag. Priority: Specifies the priority of the message. Transaction group: Specifies the transaction group of the message for transaction-grouped queues. the higher the priority. This value is determined by the system and cannot be set by the user.setCorrelation("mycorrelation").setName("MY_SENDER_AGENT_NAME"). the message is in the READY state and available for dequeuing. When a message is propagated from one queue to another. ag. the smaller the value. starting from when the message reaches the READY state. Messages are moved in two cases: – – The number of unsuccessful dequeue attempts has exceeded max_retries. It is set after a successful call to the dequeueArray method.. Note: Delay is not supported with buffered messaging. This property cannot be set. msgprop. ■ Delivery Mode: Specifies whether the message is a buffered message or a persistent message. // Set some properties (optional) msgprop. msgprop. The default recipients are the queue subscribers.

. ■ Visibility: Specifies the transactional behavior of the enqueue request.createAQMessage(msgprop).. . the payload of the AQ message can be specified using the setPayload method of the AQMessage interface. Delivery mode can be set to either persistent (ENQUEUE_PERSISTENT) or buffered (ENQUEUE_BUFFERED).length. for(int i=0. you can specify some enqueue options. // Set the enqueue options AQEnqueueOptions opt = new AQEnqueueOptions()..Enqueuing Messages msgprop. Note: ■ ■ Transformations must be created in PL/SQL using DBMS_TRANSFORM. Enqueuing Messages After you create a message and set the message properties and payload.setRetrieveMessageId(true).. The AQEnqueueOptions class enables you to specify the following enqueue options: ■ Delivery mode: Specifies the delivery mode. Retrieve Message ID: Specifies whether or not the message ID has to be retrieved from the server when the message has been enqueued.setRecipientList(recipients). These methods are defined in the AQMessage interface.setSender(ag). opt.. By default..CREATE_TRANSFORMATION(.). It indicates that the enqueue operation is part of the current transaction. Transformation: Specifies a transformation that will be applied before enqueuing the message. you must use ENQUEUE_IMMEDIATE. which commits at the end of the operation. Before you enqueue the message. mesg. you can enqueue the message using the enqueue method of the OracleConnection interface. The following code snippet illustrates how to set the enqueue options and enqueue the message: .i++) rawPayload[i] = 'b'. msgprop. . For buffered messaging.. The return type of the transformation function must match the type of the queue. the message ID is not retrieved. The following code snippet illustrates how to set the payload: ..setPayload(new oracle. // Create the message AQMessage mesg = AQFactory. 25-12 Oracle Database JDBC Developer's Guide and Reference . AQ Message Payload Depending on the type of the queue.i<rawPayload... You can retrieve the payload of an AQ message using the getPayload method or the appropriate getXXXPayload method.sql. byte[] rawPayload = new byte[500].RAW(rawPayload)). ENQUEUE_IMMEDIATE indicates that the enqueue operation is an autonomous transaction. The default value for this option is ENQUEUE_ON_COMMIT.

then the exceeding bytes will be silently ignored.FIRST_MESSAGE: The first available message matching the search criteria is dequeued. Delivery Filter: Specifies the type of message to be dequeued. Dequeue mode: Specifies the locking behavior associated with the dequeue operation. Consumer name: If specified. ■ ■ ■ ■ Maximum Buffer Length: Specifies the maximum number of bytes that will be allocated when dequeuing a message from a RAW queue. ■ Oracle Advanced Queuing 25-13 .BROWSE: Message is dequeued without acquiring any lock. The AQDequeueOptions class enables you to specify the following dequeue options: ■ Condition: Specifies a conditional expression based on the message properties.LOCKED: Message is dequeued with a write lock that lasts for the duration of the transaction. It can take one of the following values: – – – – DequeueMode.enqueue(queueName.REMOVE: (default) Message is dequeued and deleted. A dequeue condition is specified as a Boolean expression using syntax similar to the WHERE clause of a SQL query. You dequeue buffered messages only (DEQUEUE_BUFFERED) or persistent messages only (DEQUEUE_PERSISTENT). DequeueMode. Dequeuing Messages Enqueued messages can be dequeued using the dequeue method of the OracleConnection interface.. and PL/SQL functions. Before you dequeue a message you must set the dequeue options. . The message can be retained in the queue based on the retention properties. DequeueMode. This can be used to dequeue a unique message whose ID is known. which is the default. If the buffer is not large enough to contain the entire message. It can take one of the following values: – NavigationOption.REMOVE_NO_DATA: Message is marked as updated or deleted. DequeueMode. Navigation: Specifies the position of the message that will be retrieved. Note: ■ If the queue is a single-consumer queue. mesg). the message data properties. opt. ■ Correlation: Specifies a correlation criterion (or search criterion) for the dequeue operation.Dequeuing Messages // Enqueue the message // conn is an instance of OracleConnection // queueName is a String // mesg is an instance of AQMessage conn.. only the messages matching the consumer name are accessed. The default maximum is DEFAULT_MAX_PAYLOAD_LENGTH but it can be changed to any other nonzero value. Dequeue Message ID: Specifies the message identifier of the message to be dequeued. do not set this option. or both (DEQUEUE_PERSISTENT_OR_BUFFERED).

then the dequeue operation waits for the specified number of seconds. – ■ Retrieve Message ID: Specifies whether or not the message identifier of the dequeued message needs to be retrieved. // Set the dequeue options AQDequeueOptions deqopt = new AQDequeueOptions(). By default. deqopt. VisibilityOption. Transformation: Specifies a transformation that will be applied after dequeuing the message. and the first message of the next transaction group is dequeued. It can take one of the following values: – – VisibilityOption. ■ Wait: Specifies the wait time for the dequeue operation. However. The default value is DEQUEUE_WAIT_FOREVER indicating that the operation waits forever.ON_COMMIT: (default) The dequeue operation is part of the current transaction. it is not retrieved. The source type of the transformation must match the type of the queue. you can interrupt the dequeue operation by calling the cancel method on the OracleConnection object. then the next available message matching the search criteria in the message group is dequeued.. then the operation does not wait. The following code snippet illustrates how to set the dequeue options and dequeue the message: .CREATE_TRANSFORMATION(.NEXT_MESSAGE: (default) The next available message matching the search criteria is dequeued.setConsumerName(consumerName).setRetrieveMessageId(true).NEXT_TRANSACTION: Messages in the current transaction group are skipped. ■ Visibility: Specifies whether or not the message is dequeued as part of the current transaction.. deqopt.IMMEDIATE.. if none of the messages matches the search criteria.. If set to DEQUEUE_NO_WAIT.IMMEDIATE: The dequeue operation is an autonomous transaction that commits at the end of the operation.). Note: The Visibility option is ignored in the DequeueMode.Dequeuing Messages – NavigationOption. then this option must be set to VisibilityOption. // Dequeue the message // conn is an OracleConnection object 25-14 Oracle Database JDBC Developer's Guide and Reference .BROWSE dequeue mode. Note: ■ Transformations must be created in PL/SQL using DBMS_TRANSFORM. If a number is specified. If the previous message belongs to a message group. This setting can be used only if message grouping is enabled for the queue. NavigationOption. If the delivery filter is DEQUEUE_BUFFERED or DEQUEUE_PERSISTENT_OR_BUFFERED. then the dequeue operation will not return until a message that matches the search criterion is available in the queue. Note: If you use DEQUEUE_WAIT_FOREVER.

// Set the dequeue options AQDequeueOptions options = new AQDequeueOptions(). msgprop. // Set the enqueue options AQEnqueueOptions options = new AQEnqueueOptions().setExceptionQueue("EXCEPTION_QUEUE"). create a message.jdbc.jdbc.dequeue(queueName. msgprop.setSender(agent). set the dequeue options. // Get access to the queue // conn is an instance of oracle.createAQMessageProperties().setAddress("AGENTADDRESS"). options. msgprop. Example 25–3 Dequeuing a Single Message This example illustrates how to obtain access to a queue. Example 25–2 illustrates how to enqueue a message.enqueue(options.OracleConnection oracle.createAQMessage(msgprop).AQMessageProperties msgprop = oracle."RAW"). // Get access to the queue // conn is an instance of oracle.jdbc. and dequeue the message.setPriority(1). // Create the message AQMessage mesg = AQMessage. Examples: Enqueuing and Dequeuing This section provides a few examples that illustrate how to enqueue and dequeue messages. // Set some properties (optional) msgprop. AQAgent agent = AQAgent.jdbc.getAQQueue ("SCOTT. // Enqueue the message queue.jdbc. and Example 25–3 illustrates how to dequeue a message.BUFFERED).aq. and enqueue it.AQMessageProperties. mesg). Example 25–2 Enqueuing a Single Message This example illustrates how to obtain access to a queue.deqopt.aq.MY_QUEUE".jdbc. //Set the enqueue options using the setXXX methods of AQEnqueueOptions.setExpiration(0).setRawPayload(new AQRawPayload(buffer)).Examples: Enqueuing and Dequeuing // queueName is a String identifying the queue // queueType is a String specifying the type of the queue. ag2.getAQQueue("SCOTT.MY_QUEUE". such as RAW AQMessage msg = conn.AQQueue queue = conn.createAQAgent("AGENTNAME")."RAW"). // Set the payload // where buffer contains the RAW payload: mesg.OracleConnection oracle. Oracle Advanced Queuing 25-15 .setDeliveryMode(AQDequeueOptions. // Create the message properties object oracle.aq.aq.queueType).AQQueue queue = conn.

25-16 Oracle Database JDBC Developer's Guide and Reference .Examples: Enqueuing and Dequeuing // Dequeue the message AQMessage mesg = queue.dequeue(options).

"Fast Connection Failover" Chapter 27. "Transparent Application Failover" . It discusses the Fast Connection Failover and Transparent Application Failover (TAF) features Part VI contains the following chapters: ■ ■ Chapter 26.Part VI High Availability This section provides information about the high-availability features of Oracle Database 11g.

.

DOWN event processing Fast Connection Failover 26-1 . ■ Integration with implicit connection cache The two features work together synergistically to improve application performance and high availability. Fast Connection Failover Features When enabled. The advantages of Fast Connection Failover include the following: ■ Driver independence Fast Connection Failover supports both the JDBC Thin and JDBC Oracle Call Interface (OCI) drivers. As a result.26 Fast Connection Failover The Fast Connection Failover mechanism depends on the implicit connection cache feature. Fast Connection Failover provides the following: ■ Rapid detection and cleanup of invalid cached connections. ■ Integration with Oracle Real Application Clusters (Oracle RAC) This provides superior Real Application Clusters/high availability event notification mechanisms. This chapter is divided into the following sections: ■ ■ ■ ■ Overview of Fast Connection Failover Using Fast Connection Failover Understanding Fast Connection Failover Comparison of Fast Connection Failover and TAF See Also: Chapter 21. that is. "Implicit Connection Caching" Overview of Fast Connection Failover Fast Connection Failover offers a driver-independent way for your Java Database Connectivity (JDBC) application to take advantage of the connection failover facilities offered by Oracle Database 11g. for Fast Connection Failover to be available. ■ Easy integration with application code You only need to enable Fast Connection Failover and no further configuration is required. implicit connection caching must be enabled.

ORACLE_HOME/opmn/conf/ons.oraclehome set to point to your ORACLE_HOME. Fast Connection Failover works in conjunction with the JDBC connection caching mechanism. ■ Oracle Notification Service (ONS) is configured and available on the node where JDBC is running. JDBC depends on ONS to propagate database events and notify JDBC of them. you must configure ONS correctly. that is. This helps applications manage connections to ensure high availability. ■ The underlying database has Oracle Database 11g Real Application Clusters capability. ONS is shipped as part of Oracle Database 11g.config. ■ The application uses service names to connect to the database.Using Fast Connection Failover ■ ■ Load balancing of available connections. This section covers the following topics: ■ ■ ■ ■ ONS Configuration File Client-Side ONS Configuration Server-Side ONS Configuration Using racgons Remote ONS Subscription ONS Configuration File ONS configuration is controlled by the ONS configuration file. Configuration information 26-2 Oracle Database JDBC Developer's Guide and Reference . This section covers the following topics: ■ ■ ■ ■ Fast Connection Failover Prerequisites Configuring ONS for Fast Connection Failover Enabling Fast Connection Failover Querying Fast Connection Failover Status Fast Connection Failover Prerequisites Fast Connection Failover is available under the following circumstances: ■ The implicit connection cache is enabled. If failover events are not propagated. Configuring ONS for Fast Connection Failover In order for Fast Connection Failover to work. UP event processing Run-time work request distribution to all active Oracle RAC instances Using Fast Connection Failover Applications manage Fast Connection Failover through DataSource instances. then connection failover cannot occur. ■ The Java Virtual Machine (JVM) in which your JDBC instance is running must have oracle.ons. The application cannot use service identifiers. This file tells the ONS daemon details about how it should behave and who it should talk to.

log The third optional value is a walletfile name. Do not use this option on the client-side. if one ONS config file cluster node is aware of the middle tier. This specifies a log file that ONS should use for logging messages. Listing the nodes ensures that the middle-tier node can communicate with the RAC nodes. At least one middle-tier node and one node in the RAC instance must be configured to see one another. The following is an example: logfile=/private/oraclehome/opmn/logs/myons. In order to maintain an identical file on all nodes. In particular.wlt/default One optional value is reserved for use on the server-side. a list of other ONS daemons to talk to. This value is an integer that ranges from 1. As long as one node on each side is aware of the other. An example of the localport configuration is the following: localport=4100 The second value is remoteport. the host:port of the current ONS node can also be listed in the nodes list. This means that if you want to turn on SSL for one ONS instance.123. The following is an example: loglevel=3 The second optional value is a logfile name. The first optional value is a loglevel. Node values are given as a comma-delimited list of either host names or IP addresses plus ports. This specifies the level of messages that should be logged by ONS.p12 file is located. Fast Connection Failover 26-3 .123. useocr=on is used to tell ONS to store all Oracle RAC nodes and port numbers in Oracle Cluster Registry (OCR) instead of in the ONS configuration file.Using Fast Connection Failover within ons.config is defined in simple name and value pairs.log. The nodes listed in the nodes line correspond to the individual nodes in the RAC instance.config. then all nodes in the cluster are aware of it. The default value for logfile is $ORACLE_HOME/opmn/logs/ons. which indicates least messages logged.com:4200. The default value is 3.example. it will use SSL when communicating with other ONS instances and require SSL certificate authentication from all ONS instances that try to connect to it. all nodes are visible.config. If a wallet file is specified to ONS. which indicates most messages logged. The following is an example: walletfile=/private/oraclehome/opmn/conf/ssl. This value should point to the directory where your ewallet. The first is localport. It will be ignored when reading the list. An example of the remoteport configuration is the following: remoteport=4200 The third value specifies nodes. the port that ONS binds to on all interfaces for talking to other ONS daemons.123:4200 There are also several optional values that can be provided in ons.123. There are three values that should always be configured within ons. the port that ONS binds to on the localhost interface to talk to local clients. to 9. A wallet file is used by the Oracle Secure Sockets Layer (SSL) to store SSL certificates. An example of the nodes configuration is the following: nodes=myhost. You need not list every single cluster and middle-tier node in the ONS config file of each Oracle RAC node. Note that the port value that is given is the remote port that each ONS instance is listening on. then you must turn it on for all instances that are connected.

so that all nodes share the configuration. use ORACLE_HOME/opmn/bin/onsctl to start..example.config to set useocr=on. there are two ways to set up ONS: ■ Remote ONS configuration See Also: "Remote ONS Subscription" on page 26-5 ■ ONS daemon on the client-side Example 26–1 illustrates how a sample configuration file may look.example. Before using racgons.. Client-Side ONS Configuration You can access the client-side ONS through ORACLE_HOME/opmn. This command is found in ORA_CRS_HOME/bin/racgons. Using the onsctl Command After configuring. help detailed Server-Side ONS Configuration Using racgons You can access the server-side ONS through ORA_CRS_HOME/opmn. Table 26–1 Command start stop ping reconfig onsctl Commands Effect Starts the ONS daemon Stops the ONS daemon Verifies whether or not the ONS daemon is running Triggers a reload of the ONS configuration without shutting down the ONS daemon Prints a help summary message for onsctl Prints a detailed help message for onsctl Output onsctl: ons started onsctl: shutting down ons daemon...racnode2. The middle-tier nodes should be configured in OCR. and no matter which Oracle RAC nodes are up they can communicate 26-4 Oracle Database JDBC Developer's Guide and Reference . you start the ONS daemon with the onsctl command. you must edit ons.config file # # The first three values are required localport=4100 remoteport=4200 nodes=racnode1. Table 26–1 is a summary of the commands that onsctl supports. stop. It is the user's responsibility to make sure that an ONS daemon is running at all times.com:4200 After configuring ONS. and monitor the ONS daemon. reconfigure.com:4200. You configure the server-side by using racgons to add the middle-tier node information to OCR.config File # This is an example ons.config file allows blank lines and comments on lines that begin with the number sign (#). Example 26–1 Example of a Sample ons. On the client-side. ons is running .Using Fast Connection Failover The ons.

which is a list of host:port pairs.example. assuming ods is an OracleDataSource instance: ods. or walletpassword. If multiple port numbers are configured for a host. name can be one of nodes. racgons remove_config hostname[:port] [hostname:port] [hostname:port] ...com:4200. if the walletpassword attribute is not specified. you do not need to edit a file on every node to change the configuration. each pair separated by comma (.racnode2:4200\nwalletfile=/mydir/Wall et\nwalletpassword=mypasswd"). therefore. the remove_config version removes them. the application invokes the following method on an OracleDataSource instance: setONSConfiguration(String remoteONSConfig) The remoteONSConfig parameter is a list of name and value pairs of the form name=value that are separated by a new line character (\n). Following are a few examples. See Also: Oracle Real Application Clusters Administration and Deployment Guide Other Uses of racgons You should run racgons whenever you add a new node to the cluster. In such cases. The add_config version adds the listed host name(s). That way. The command takes two forms: racgons add_config hostname:port [hostname:port] [hostname:port] . When running on a cluster. always configure the ONS hosts and ports not by using the ONS configuration files but using racgons. where every node can see it. Fast Connection Failover 26-5 . The racogns command enables you to specify hosts and ports on one node.Using Fast Connection Failover to the middle-tier.setONSConfiguration("nodes=racnode1. no need to manage this process Simple configuration using the DataSource property ■ When using remote ONS subscription for Fast Connection Failover.com:4200 "). the specified port number is removed from hostname.setONSConfiguration("nodes=racnode1:4200. walletfile.racnode2.. If only hostname is specified. See Also: "ONS Configuration File" on page 26-2 SSL could be used in communicating with the ONS daemons when the walletfile attribute is specified as an Oracle wallet file. Both commands propagate the changes among all instances in a cluster. This parameter should specify at least the nodes ONS configuration attribute. single sign-on (SSO) would be assumed.. all port numbers for that host are removed. The hosts and ports denote the remote ONS daemons available on the Oracle RAC nodes. then propagate your changes among all nodes in a cluster. just run a single command on one of the cluster nodes.example. ods. Remote ONS Subscription The advantages of remote ONS subscription are the following: ■ ■ Support for an All Java middle-tier stack No ONS daemon needed on the client computer and.). The racgons command stores the ONS hosts and ports in OCR.

Use a service name rather than a service identifier when setting the OracleDataSource url property. Example 26–2 illustrates how to enable Fast Connection Failover. and JDBC Fast Connection Failover continues to work as before. then you must first set FastConnectionFailoverEnabled before retrieving any connections.setONSConfiguration("nodes=racnode1:4200.setUser("scott").ods). // transparently creates and accesses cache catch (SQLException SE { } } 26-6 Oracle Database JDBC Developer's Guide and Reference . Enabling Fast Connection Failover An application enables Fast Connection Failover by calling setFastConnectionFailoverEnabled(true) on a DataSource instance. the failover applies to all connections in the connection cache.bind("myDS".jar file must be in the CLASSPATH on the client. then implicit connection cache creation fails and an ONSException is thrown at the first getConnection request. Note: The ons. If ONS is not correctly set up. ods. To enable Fast Connection Failover.racnode2:4200\nwalletfile=/mydir/conf /Wallet"). you cannot disable Fast Connection Failover during the lifetime of that cache.lookup("MyDS"). When Fast Connection Failover is enabled. Enabling Fast Connection Failover ■ ■ Example 26–2 // declare datasource ods. Set the FastConnectionFailoverEnabled property before making the first getConnection request to an OracleDataSource. If your application explicitly creates a connection cache using the Connection Cache Manager. ods. In the case of Oracle Application Server.setConnectionCachingEnabled(true). try { ds. ONS is embedded in Oracle Process Manager and Notification Server (OPMN).getConnection(). You cannot enable Fast Connection Failover when reinitializing a connection cache. you must perform the following: ■ Configure and start ONS.setUrl( "jdbc:oracle:oci:@(DESCRIPTION= (ADDRESS=(PROTOCOL=TCP)(HOST=cluster_alias) (PORT=1521)) (CONNECT_DATA=(SERVICE_NAME=service_name)))"). Note: After a cache is Fast Connection Failover-enabled.setFastConnectionFailoverEnabled(true): ctx. ods.Using Fast Connection Failover ods. as before. before retrieving any connections from that instance. You must enable it before using the OracleDataSource instance. ds=(OracleDataSource) ctx.

it is possible to receive SQLException. the mechanism is automatic. The RAC mechanism in the database generates an Oracle RAC event which is sent to the JVM containing JDBC.getFastConnectionFailoverEnabled. and host name.Understanding Fast Connection Failover . A daemon thread inside the JVM receives the Oracle RAC event and passes it on to the Connection Cache Manager. All work done before the connection was closed has been lost. The cache manager then cleans up all invalid connections. leaving several stale connections in the cache. When an application holding an invalid connection tries to do work through that connection. Fast Connection Failover 26-7 . When a database generates an Oracle RAC event. The transaction was already rolled back in the database by the time the application received the exception.. the database already rolls back the local transaction. ORA-17008. that event is forwarded to the JVM in which JDBC is running. This section covers the following topics: ■ ■ What the Application Sees How It Works What the Application Sees By the time an Oracle RAC service failure is propagated to the JDBC application. Closed Connection.. Replay the transaction. instance. Understanding Fast Connection Failover After Fast Connection Failover is enabled. When an application receives a Closed Connection error message. Retry the connection request. which returns true if failover is enabled. false otherwise. This section discusses how a connection failover is presented to an application and what steps the application takes to recover. database. 2. Querying Fast Connection Failover Status An application determines if Fast Connection Failover is enabled by calling OracleDataSource. each connection in the cache maintains a mapping to a service. The Connection Cache Manager then throws SQL exceptions to the applications affected by the Oracle RAC event. How It Works Under Fast Connection Failover. A typical failover scenario may work like the following: 1. A database instance fails. This is essential. no application intervention is needed. because the old connection is no longer open. Note: The application should not try to roll back the transaction. 2. it should do the following: 1.

Each individual connection receives a SQL exception and must retry. ■ Event-based Fast Connection Failover is based on the Oracle RAC event mechanism. 4. This means that Fast Connection Failover is efficient and detects failures quickly for both active and inactive connections. For example. 26-8 Oracle Database JDBC Developer's Guide and Reference . notifies them of the closed connection through SQL exceptions. The application can choose whether to retry the connection or to rethrow the exception. This gives the application control of responding to connection failovers. TAF supports connection retries only at the OCI/Net layer. The daemon thread inside the JVM finds all the connections affected by the Oracle RAC event. TAF works at the network level on a per-connection basis. failed connections are automatically invalidated in the cache. and rolls back any open transactions.Comparison of Fast Connection Failover and TAF 3. Comparison of Fast Connection Failover and TAF Fast Connection Failover differs from Transparent Application Failover (TAF) in the following ways: ■ Application-level connection retries Fast Connection Failover supports application-level connection retries. Note: Oracle recommends not to use TAF and Fast Connection Failover in the same application. which allows the Connection Cache Manager to manage the cache for high availability. ■ Load-balancing support Fast Connection Failover supports UP event load balancing of connections and run-time work request distribution across active Oracle RAC instances. ■ Integration with the implicit connection cache Fast Connection Failover is well-integrated with the implicit connection cache. which means that the connection cache cannot be notified of failures.

the connection on the client-side becomes stale and would throw exceptions to the caller trying to use it. In this case. It enables the application to automatically reconnect to a database. Note: ■ ■ TAF is always active and does not have to be set. the active transactions roll back. but identical to the connection that was established on the first original instance. ■ FO_SELECT Is equivalent to FAILOVER_MODE=SELECT in tnsnames. if the database instance to which the connection is made fails. the connection properties are the same as that of the earlier connection. This means that only the user session is authenticated again on the server side. That is.ora file CONNECT_DATA flags. This is true regardless of how the connection was lost.27 Transparent Application Failover This chapter contains the following sections: ■ ■ ■ ■ Overview of Transparent Application Failover Failover Type Events TAF Callbacks Java TAF Callback Interface Overview of Transparent Application Failover Transparent Application Failover (TAF) is a feature of the Java Database Connectivity (JDBC) Oracle Call Interface (OCI) driver. creating a fresh connection. When an instance to which a connection is established fails or is shut down. Failover Type Events The following are possible failover events in the OracleOCIFailover interface: ■ FO_SESSION Is equivalent to FAILOVER_MODE=SESSION in the tnsnames. while open cursors in the OCI application need to be reprocessed. This means that not only the user session is Transparent Application Failover 27-1 . TAF does not work with the OCI connection pool.ora file CONNECT_DATA flags. TAF enables the application to transparently reconnect to a preconfigured secondary instance.

Note: The callback setting is optional. supporting the following types and events: public interface OracleOCIFailover{ // Possible Failover Types public static final int FO_SESSION = 1. ■ FO_END Indicates successful completion of failover. Additionally. This can also be explicitly specified to prevent failover from happening. The application also has some control of failover. TAF Callbacks TAF callbacks are used in the event of the failure of one database connection. but it gives the application the opportunity to handle the error and retry failover.ora file CONNECT_DATA flags. 27-2 Oracle Database JDBC Developer's Guide and Reference . ■ FO_ABORT Indicates that failover was unsuccessful and there is no option of retrying. public static final int FO_SELECT = 2. ■ FO_BEGIN Indicates that failover has detected a lost connection and failover is starting. Java TAF Callback Interface The OracleOCIFailover interface includes the callbackFn method. The callback is called during the failover to notify the JDBC application of events generated. TAF callbacks are callbacks that are registered in case of failover. ■ FO_ERROR Indicates that failover was temporarily unsuccessful. in which no failover functionality is used.TAF Callbacks re-authenticated on the server side. and failover to another database connection. ■ FO_REAUTH Indicates that a user handle has been re-authenticated. ■ FO_EVENT_UNKNOWN Indicates a bad failover event. public static final int FO_NONE = 3. This implies that the client-side logic maintains fetch-state of each open cursor. FO_TYPE_UNKNOWN implies that a bad failover type was returned from the OCI driver. This is the default. The usual method of error handling is to issue the sleep method and retry by returning the value FO_RETRY. but open cursors in the OCI can continue fetching. ■ FO_RETRY Indicates that the application should retry failover. ■ FO_NONE Is equivalent to FAILOVER_MODE=NONE in the tnsnames.

public static final int FO_EVENT_UNKNOWN = 7. public static final int FO_ABORT = 3. the JDBC application is able to retry failover. public static final int FO_REAUTH = 4. either indefinitely or for a limited amount of time. // One of the possible Failover Events Handling the FO_ERROR Event In case of an error while failing over to a new connection. public static final int FO_END = 2. Handling the FO_ABORT Event Callback registered should return the FO_ABORT event if the FO_ERROR event is passed to it. // One of the possible Failover Types int event ). by having the callback return FO_RETRY. Typically. public int callbackFn (Connection conn. Object ctxt. // Possible Failover events registered with callback public static final int FO_BEGIN = 1. the application sleeps for a while and then it retries. public static final int FO_ERROR = 5. // ANy thing the user wants to save int type. Transparent Application Failover 27-3 .Java TAF Callback Interface public static final int. public static final int FO_RETRY = 6.

Java TAF Callback Interface 27-4 Oracle Database JDBC Developer's Guide and Reference .

"Distributed Transactions" . Part VII contains the following chapter: ■ Chapter 28.Part VII Transaction Management This part provides information about transaction management in Oracle Java Database Connectivity (JDBC). It includes a chapter that discusses the Oracle JDBC implementation of distributed transactions.

.

which must be committed in a coordinated way. often using multiple databases. The transactions that constitute a distributed transaction might be in the same database. which is available through the javax packages from Sun Microsystems. For further introductory and general information about distributed transactions. formerly known as the JDBC 2. sometimes referred to as a global transaction. distributed transaction functionality is built on top of connection pooling functionality. You would not want either transaction committed without assurance that both will complete successfully. but more typically are in different databases and often in different locations. These are multiphased transactions. is a set of two or more related transactions that must be managed in a coordinated way. a distributed transaction might consist of money being transferred from an account in one bank to an account in another bank. for distributed transactions.0 Optional Package and the Java Transaction API (JTA). Overview of Distributed Transactions A distributed transaction. XA is part of the X/Open standard and is not specific to Java.0 extension API. For example. refer to the Sun Microsystems specifications for the JDBC 2. and not specific to Java. The following topics are discussed: ■ ■ ■ ■ ■ Overview of Distributed Transactions XA Components Error Handling and Optimizations Implementing a Distributed Transaction Native-XA in Oracle JDBC Drivers Note: This chapter discusses features of the JDBC 2. which is a general standard.0 Standard Extension application programming interface (API). This distributed transaction functionality is also built upon the open XA standard for distributed transactions. In the JDBC 2. Each individual transaction of a distributed transaction is referred to as a transaction branch.0 Optional Package. There is also related discussion of XA.28 Distributed Transactions This chapter discusses the Oracle Java Database Connectivity (JDBC) implementation of distributed transactions. Distributed Transactions 28-1 .

XA functionality includes the following key components: ■ XA data sources These are extensions of connection pool data sources and other data sources. The term resource manager is often used in discussing distributed transactions. it will be helpful to keep the following points in mind: ■ A distributed transaction system typically relies on an external transaction manager. because that has been tested with the Oracle drivers. such as a software component that implements standard JTA functionality. Wherever the term is used in this chapter. The section covers the following topics: ■ ■ ■ ■ Distributed Transaction Components and Scenarios Distributed Transaction Concepts Switching Between Global and Local Transactions Oracle XA Packages Distributed Transaction Components and Scenarios In reading the remainder of the distributed transactions section. to coordinate the individual transactions. 28-2 Oracle Database JDBC Developer's Guide and Reference . Note: Using JTA functionality requires jta. being implemented instead in a middle-tier environment.Overview of Distributed Transactions JDBC is used to connect to database resources. possibly together with some of the application code as well.jar to be in the CLASSPATH environment variable. the application server and transaction manager will be together on the middle tier. Distributed Transaction Concepts When you use XA functionality. There will be one XA data source instance for each resource manager that will be used in the distributed transaction. This file is located at ORACLE_HOME/jlib. Oracle includes this file with the JDBC product. but it is advisable to use the version from Oracle. to include all changes to multiple databases within a transaction. and similar in concept and functionality. you must use the JDBC connections within a JTA global transaction. the transaction manager uses XA resource instances to prepare and coordinate each transaction branch and then to commit or roll back all transaction branches appropriately. The process of including database SQL updates within a transaction is referred to as enlisting a database resource. ■ ■ Discussion throughout this section is intended mostly for middle-tier developers. You can also obtain it from the Sun Microsystems Web site. You will typically create XA data source instances in your middle-tier software. However. such as an application server. it refers to a database. which includes JTA in Oracle9i Application Server and Oracle Application Server 10g. Many vendors offer XA-compliant JTA modules. including Oracle. A resource manager is simply an entity that manages data or some other kind of resource. ■ XA functionality is usually isolated from a client application. In many scenarios.

Individual connection instances are temporary handles to these physical connections. An XA connection instance corresponds to a single Oracle session. You will typically get an XA connection instance from an XA data source instance in your middle-tier software. Equivalently. as with pooled connection instances. You can get multiple XA connection instances from a single XA data source instance if the distributed transaction will involve multiple sessions in the same database. Once the transaction manager sees that the operations of each transaction branch have prepared successfully. However. end. The transaction manager will issue a PREPARE to each OracleXAResource instance. ■ XA connections These are extensions of pooled connections and similar in concept and functionality. although the session can be used in sequence by multiple logical connection instances. there can be additional suspended transaction branches. the middle-tier component will hand off OracleXAResource instances to the transaction manager. Because each OracleXAResource instance corresponds to a single Oracle session. it will issue a COMMIT to each OracleXAResource instance to commit all the changes. This is how a branch is associated with a distributed transaction. ■ OracleXAResource. there is a one-to-one correlation between OracleXAResource instances and Oracle sessions. Distributed Transactions 28-3 . ■ XA resources These are used by a transaction manager in coordinating the transaction branches of a distributed transaction. An XA connection encapsulates a physical database connection. for use in coordinating distributed transactions. XA connections produce OracleXAResource instances and JDBC connection instances. In a typical scenario.ORATRANSLOOSE Start a loosely coupled transaction with transaction ID xid. prepare. there can be only a single active transaction branch associated with an OracleXAResource instance at any given time. Each OracleXAResource instance has the functionality to start. All OracleXAResource instances associated with a given distributed transaction would have a transaction ID that includes the same distributed transaction ID component. You will get one OracleXAResource instance from each XA connection instance. ■ Transaction IDs These are used to identify transaction branches. commit. The prepare step is the first step of a two-phase commit operation. or roll back the operations of the transaction branch running in the session with which the OracleXAResource instance is associated. typically in your middle-tier software.Overview of Distributed Transactions XA data sources produce XA connections. There is a one-to-one correlation between OracleXAResource instances and XA connection instances. Each ID includes a transaction branch ID component and a distributed transaction ID component.

NEVER Current Mode NO_TXN LOCAL_TXN Any of the following happens: ■ An Oracle data definition language (DDL) statement is run. commit is called. Table 28–1 describes the connection mode transition rules. A connection is always in NO_TXN mode when it is instantiated. Each connection switches automatically between these modes depending on the operations carried out on the connection. Table 28–1 Connection Mode Transitions Switches to NO_TXN When NA Switches to LOCAL_TXN When Auto-commit mode is false and an Oracle data manipulation language (DML) statement is run. Applications can also switch connections between local transactions and global transactions. ■ GLOBAL_TXN A global transaction is actively using this connection.Overview of Distributed Transactions Switching Between Global and Local Transactions As of JDBC 3.0. NA ■ ■ GLOBAL_TXN NEVER Within a global transaction open on this connection. applications can share connections between local and global transactions. A connection is always in one of the following modes: ■ NO_TXN No transaction is actively using this connection. NA Switches to GLOBAL_TXN When start is called on an XAResource obtained from the XAconnection that provided this connection. Note: The modes are maintained internally by the JDBC drivers in association with Oracle Database. 28-4 Oracle Database JDBC Developer's Guide and Reference . but without parameters. ■ LOCAL_TXN A local transaction with auto-commit turned off or disabled is actively using this connection. rollback is called. end is called on an XAResource obtained from the XAconnection that provided this connection.

rollback. setAutoCommit(true). however.server package instead of the client package.XA Components If none of these rules is applicable.jdbc.0 Optional Package. Doing so causes a SQLException to be thrown. then do not import either package.client oracle.client package. applications must not call commit. If you intend your XA code to run in the target Oracle Database. In the GLOBAL_TXN mode. Doing so causes an XAException to be thrown. that is. and must not call OracleSetSavepoint or oracleRollback on an oracle. Note: ■ This mode-restriction error checking is in addition to the standard error checking on the transaction and savepoint APIs.sql.jdbc. Instead. rollback(Savepoint). XA Components This section discusses the XA components. applications must not call start. you will import the oracle. Mode Restrictions on Operations The current connection mode restricts which operations are valid within a transaction. standard XA interfaces specified in the JDBC 2. and the oracle. ■ In the LOCAL_TXN mode. Class names are duplicated between these packages.jdbc.jdbc. prepare. then the mode does not change.xa package. Oracle XA Packages Oracle supplies the following three packages that have classes to implement distributed transaction functionality according to the XA standard: ■ ■ ■ oracle. or end on an XAResource. or setSavepoint on a java.xa. because their functionality does not depend on where the code is running. commit. An abstract class for each is in the top-level package. you will import OracleXid. OracleXAException.jdbc. The OracleXid and OracleXAException classes are in the top-level oracle.xa.server Classes for XA data sources. If code that will run inside a target database must also access remote databases.Connection.xa.xa.jdbc. In middle-tier scenarios. and the Oracle classes that implement them. forget. and XA resources are in both the client package and the server package.OracleConnection. rollback.jdbc. XA connections. you must fully qualify the names of any classes that you use from the client package to access a remote database or from the server package to access the local database.xa oracle. The following topics are covered: ■ ■ ■ ■ XADatasource Interface and Oracle Implementation XAConnection Interface and Oracle Implementation XAResource Interface and Oracle Implementation OracleXAResource Method Functionality and Input Parameters Distributed Transactions 28-5 .

sql.XAResource getXAResource() throws SQLException. so it also includes the getConnection.. encapsulates a physical connection to a database.XA Components ■ Xid Interface and Oracle Implementation XADatasource Interface and Oracle Implementation The javax.XADataSource interface outlines standard functionality of XA data sources.sql. as with a pooled connection instance. } Oracle JDBC implements the XADataSource interface with the OracleXADataSource class.sql. The OracleXADataSource classes also extend the OracleConnectionPoolDataSource class. .server package.client package and the oracle.xa. the XAConnection interface extends the javax. see Chapter 26. which extends the OracleDataSource class.jdbc.XAConnection interface: public interface XAConnection extends PooledConnection { javax.xa. located both in the oracle.jdbc. which are factories for XA connections. See Also: For information about Fast Connection Failover. and therefore. Note: You can register XA data sources in Java Naming Directory and Interface (JNDI) using the same naming conventions as discussed previously for nonpooling data sources.PooledConnection interface. } As you see.. An XA connection instance is an instance of a class that implements the standard javax. String password) throws SQLException. Each XA connection instance also has the facility to produce the OracleXAResource instance that will correspond to it for use in coordinating the distributed transaction. The getXAConnection methods of the OracleXADataSource class returns the Oracle implementation of XA connection instances. XAConnection getXAConnection(String user. "Fast Connection Failover". which are OracleXAConnection instances.xa. This would be the database specified in the connection properties of the XA data source instance that produced the XA connection instance.jta. 28-6 Oracle Database JDBC Developer's Guide and Reference . The overloaded getXAConnection method returns an XA connection instance and optionally takes a user name and password as input: public interface XADataSource { XAConnection getXAConnection() throws SQLException. XAConnection Interface and Oracle Implementation An XA connection instance. include all the connection properties.

Essentially. and closes any previous connection instance that still exists and had been returned by the same XA connection instance. This is typically performed in the middle tier. it associates distributed transactions with the physical connection or session encapsulated by the XA connection instance. which is an OracleXAResource instance.jdbc. XAResource Interface and Oracle Implementation The transaction manager uses OracleXAResource instances to coordinate all the transaction branches that constitute a distributed transaction. At that time.server package. addConnectionEventListener. Oracle JDBC implements the XAConnection interface with the OracleXAConnection class. Calling the close method of an XA connection instance closes the physical connection to the database. as opposed to encapsulating the physical connection. typically invoked by the transaction manager: ■ It associates and disassociates distributed transactions with the transaction branch operating in the XA connection instance that produced this OracleXAResource instance. The physical connection is encapsulated by the XA connection instance. Each OracleXAResource instance provides the following key functionality.jdbc. the default status is true. The connection obtained from an XAConnection object behaves exactly like a regular connection. auto-commit status is returned to the value it had before the global transaction. located both in the oracle.xa. The getConnection method returns an OracleConnection instance.XA Components close. After the global transaction ends. it is advisable to explicitly close any previous connection instance before opening a new one. The default auto-commit status on a connection obtained from XAConnection is false in all releases prior to Oracle Database 10g. until it participates in a global transaction. Each time an XA connection instance getConnection method is called. it returns a new connection instance that exhibits the default behavior. Starting from Oracle Database 10g. ■ Distributed Transactions 28-7 .xa. The OracleXAConnection class getXAResource method returns the Oracle implementation of an OracleXAResource instance. auto-commit status is set to false.client package and the oracle. The OracleXAConnection classes also extend the OraclePooledConnection class. A JDBC connection instance returned by an XA connection instance acts as a temporary handle to the physical connection. It performs the two-phase commit functionality of a distributed transaction to ensure that changes are not committed in one transaction branch before there is assurance that the changes will succeed in all transaction branches. However. This is done through use of transaction IDs. and removeConnectionEventListener methods.

TMNOFLAGS Flag the start of a new transaction branch for subsequent operations in the session associated with this XA resource instance. receiving OracleXAResource instances from a middle-tier component.xa. ■ An OracleXAResource instance is an instance of a class that implements the standard javax. This branch will have the transaction ID xid. A transaction manager.xa. This method is how an OracleXAResource instance is associated with a particular connection and with the transaction branch being run in that connection.jdbc. which is an OracleXid instance created by the transaction manager.client package and the oracle. associating the transaction branch with a distributed transaction. 28-8 Oracle Database JDBC Developer's Guide and Reference .jdbc.xa. Every transaction branch has a unique transaction ID.transaction.XA Components Note: ■ Because there must always be a one-to-one correlation between XA connection instances and OracleXAResource instances. OracleXAResource Method Functionality and Input Parameters The OracleXAResource class has several methods to coordinate a transaction branch with the distributed transaction with which it is associated. such as an application server. int flags) The flags parameter must be one or more of the following values: ■ XAResource. but transaction branches belonging to the same global transaction have the same global transaction component as part of their transaction IDs. Oracle JDBC implements the XAResource interface with the OracleXAResource class. Oracle JDBC driver creates and returns an OracleXAResource instance whenever the getXAResource method of the OracleXAConnection class is called. start Starts work on behalf of a transaction branch. If a transaction is opened by a given OracleXAResource instance. and it is Oracle JDBC driver that associates an OracleXAResource instance with a connection instance and the transaction branch being run through that connection. ■ XAResource. in the form of an Xid instance. then it must also be closed by the same OracleXAResource instance. Each of these methods takes a transaction ID as input. typically invokes this functionality. This functionality usually involves two-phase commit operations. which includes a transaction branch ID component and a distributed transaction ID component. void start(Xid xid.TMJOIN Join subsequent operations in the session associated with this XA resource instance to the existing transaction branch specified by xid.server package. located both in the oracle.XAResource interface. an OracleXAResource instance is implicitly closed when the associated XA connection instance is closed. This will map the transaction branch to the appropriate distributed transaction.

ORATMSERIALIZABLE. then an external Oracle exception with code ORA-24790 is raised. an Oracle extension. ORATMREADONLY.TMNOMIGRATE). In order to avoid Error ORA 1002: fetch out of sequence. TMJOIN. TMRESUME. ■ OracleXAResource. Note: ■ Instead of using the start method with TMRESUME. then an exception with code XAER_INVAL is raised. ■ OracleXAResource. because you cannot set the isolation level of an existing transaction. as in start(xid. the transaction manager can cast to OracleXAResource and use the resume(Xid xid) method. ORATMSERIALIZABLE. ■ OracleXAResource. then you must also use TMNOMIGRATE. ■ OracleXAResource. When writing a transaction manager that uses these flags. If you try to use the isolation-mode flags when resuming a transaction.TMRESUME Resume the transaction branch specified by xid. Distributed Transactions 28-9 .ORATRANSLOOSE Start a loosely coupled transaction with transaction ID xid. you should be mindful of this. Note: A transaction branch can be resumed only if it had been suspended earlier.ORATMREADWRITE Start a read/write transaction with transaction ID xid. ■ ■ ■ ■ All the flags defined in OracleXAResource are Oracle extensions. and ORATMREADWRITE are the isolation-mode flags. If you use TMRESUME.ORATMREADONLY Start a read-only transaction with transaction ID xid. XAResource. include the TMNOMIGRATE flag as part of the start method. and ORATMREADWRITE are defined as static members of the XAResource interface and OracleXAResource class. TMNOFLAGS. Furthermore. If you use the isolation-mode flags incorrectly. This prevents the application from receiving the error ORA 1002: fetch out of sequence. XAResource.TMSUSPEND | OracleXAResource.XA Components ■ XAResource. ORATMREADONLY. you cannot use isolation-mode flags when resuming a global transaction.ORATMSERIALIZABLE Start a serializable transaction with transaction ID xid. For example: start(xid.TMRESUME | OracleXAResource. The default isolation behavior is READ COMMITTED.TMNOMIGRATE).

TMFAIL. You can use the XA classes to accomplish this.XA Components Note that to create an appropriate transaction ID in starting a transaction branch. Any transaction manager that uses these flags should take heed of this. the transaction manager must know to which distributed transaction the transaction branch belongs. ■ XAResource. however. XAResource. By suspending transaction branches. XAResource.TMSUCCESS This is to indicate that this transaction branch is known to have succeeded. ■ ■ ■ ■ All the flags defined in OracleXAResource are Oracle extensions.TMSUSPEND | OracleXAResource. Also. an Oracle extension. the transaction manager can cast to OracleXAResource and use the suspend(Xid xid) method. include the TMNOMIGRATE flag as part of the end method. ■ XAResource. you can have multiple transaction branches in a single session.TMSUSPEND This is to suspend the transaction branch specified by xid. then you must also use TMNOMIGRATE. For example: end(xid. disassociating the transaction branch from its distributed transaction. even if you are not in a distributed transaction environment and would otherwise have no need for the XA classes.TMNOMIGRATE).TMFAIL This is to indicate that this transaction branch is known to have failed. TMSUCCESS. If you use TMSUSPEND. as in end(xid. Only one can be active at any given time. and TMSUSPEND are defined as static members of the XAResource interface and OracleXAResource class. 28-10 Oracle Database JDBC Developer's Guide and Reference . This prevents the application from receiving the error ORA 1002: fetch out of sequence. end Ends work on behalf of the transaction branch specified by xid. this tends to be more expensive in terms of resources than having two sessions. void end(Xid xid. Note: ■ Instead of using the end method with TMSUSPEND. In order to avoid Error ORA 1002: fetch out of sequence.TMNOMIGRATE). This XA functionality to suspend a transaction provides a way to switch between various transactions within a single JDBC connection. The mechanics of this are handled between the middle tier and transaction manager. int flags) The flags parameter can have one of the following values: ■ XAResource.TMSUSPEND | OracleXAResource.

int prepare(Xid xid) This method returns an integer value as follows: ■ XAResource. You can call the OracleXAResource commit method without preparing first. the prepare step would be skipped. This is the second phase of a two-phase commit and is performed only after all transaction branches have been successfully prepared. void rollback(Xid xid) Distributed Transactions 28-11 . In this case. boolean onePhase) Set the onePhase parameter as follows: ■ true This is to use one-phase instead of two-phase protocol in committing the transaction branch. ■ NA (no value returned) No value is returned if the transaction branch runs updates and any of them encounters errors during preparation. This is appropriate if there is only one transaction branch in the distributed transaction. Note: ■ Always call the end method on a branch before calling the prepare method. If there is only one transaction branch in a distributed transaction. ■ false This is to use two-phase protocol in committing the transaction branch.XA_RDONLY This is returned if the transaction branch runs only read-only operations such as SELECT statements. void commit(Xid xid. an XA exception is thrown. ■ XAResource. to ensure that the database is accessible and that the changes can be committed successfully. ■ commit Commits prepared changes in the transaction branch specified by xid.XA Components prepare Prepares the changes performed in the transaction branch specified by xid. This is the first phase of a two-phase commit operation.XA_OK This is returned if the transaction branch runs updates that are all prepared without error. rollback Rolls back prepared changes in the transaction branch specified by xid. XA_RDONLY and XA_OK are defined as static members of the XAResource interface and OracleXAResource class. then there is no need to call the prepare method.

cause an exception to be thrown. presume xares1 and xares2 are OracleXAResource instances: boolean sameRM = xares1. Note: The recover method requires SELECT privilege on DBA_PENDING_TRANSACTIONS and EXECUTE privilege on SYS. The size of a format identifier is 4 bytes.XA Components forget Tells the resource manager to forget about a heuristically completed transaction branch.DBMS_SYSTEM in Oracle database. Each transaction branch is assigned a unique transaction ID.isSameRM(xares2). call the isSameRM method from one OracleXAResource instance. public void forget(Xid xid) recover The transaction manager calls this method during recovery to obtain the list of transaction branches that are currently in prepared or heuristically completed states. This field cannot be null. specifying the other OracleXAResource instance as input.DBMS_XA in Oracle database server. If an error occurs during the operation. isSameRM To determine if two OracleXAResource instances correspond to the same resource manager. ■ Branch qualifier 28-12 Oracle Database JDBC Developer's Guide and Reference . Xid Interface and Oracle Implementation The transaction manager creates transaction ID instances and uses them in coordinating the branches of a distributed transaction. which includes the following information: ■ Format identifier A format identifier specifies a Java transaction manager. For example. then the resource manager throws the appropriate XAException. ■ Global transaction identifier It is also known as a distributed transaction ID component. where an Oracle patch including a fix for bug 5945463 is not available or it is infeasible to apply the patch for the particular application scenario. TMENDRSCAN. For database versions prior to Oracle Database 11g Release 1 (11. otherwise flag is ignored. The size of a global transaction identifier is 64 bytes. or TMNOFLAGS. In the following example.1). The resource manager returns zero or more Xids for the transaction branches that are currently in a prepared or heuristically completed state. the recover method further requires EXECUTE privilege on SYS. there could be a format identifier ORCL. public Xid[] recover(int flag) Note: Values for flag other than TMSTARTRSCAN.

However.OracleXAException subclasse of the standard javax. An XA transaction ID instance is an instance of a class that implements the standard javax.Error Handling and Optimizations It is also known as transaction branch ID component. which is a Java mapping of the X/Open transaction identifier XID structure. use any class that implements the javax.transaction.Xid interface. transparent to application programs or an application server. An OracleXAException instance is constructed using one of the following constructors: Distributed Transactions 28-13 .xa.XAException or a subclass.transaction. An Oracle XAException is an instance that consists of an Oracle error portion and an XA error portion. Oracle provides the oracle. and bId[] is a byte array for the branch qualifier.xa package. The Xid interface specifies the following getter methods: ■ ■ ■ public int getFormatId() public byte[] getGlobalTransactionId() public type[] getBranchQualifier() Error Handling and Optimizations This section focuses on the functionality of XA exceptions and error handling and the Oracle optimizations in its XA implementation.xa. The size of a branch qualifier is 64 bytes.jdbc. The 64-byte global transaction identifier value will be identical in the transaction IDs of all transaction branches belonging to the same distributed transaction. as well as particular XA error codes and error-handling techniques.XAException class. byte gId[]. byte bId[]) throws XAException fId is an integer value for the format identifier.transaction. the overall transaction ID is unique for every transaction branch.xa. XAException Classes and Methods XA methods throw XA exceptions. A transaction manager may use the following in creating an OracleXid instance: public OracleXid(int fId.Xid interface. It covers the following topics: ■ ■ ■ ■ XAException Classes and Methods Mapping Between Oracle Errors and XA Errors XA Error Handling Oracle XA Optimizations The exception and error-handling discussion includes the standard XA exception class and the Oracle-specific XA exception class. Instead.xa. Oracle implements this interface with the OracleXid class in the oracle. An XA exception is an instance of the standard class javax.xa.jdbc. as opposed to general exceptions or SQLExceptions.transaction. Note: Oracle does not require the use of OracleXid for OracleXAResource calls. gId[] is a byte array for the global transaction identifier. OracleXid instances are employed only in a transaction manager.

.println("Error " + oraerr). The JDBC driver determines exactly how to combine the Oracle and XA error values.XAER_NOTA XAException..} In case the XA operations did not throw an Oracle-specific XA exception.Error Handling and Optimizations public OracleXAException() public OracleXAException(int error) The error value is an error code that combines an Oracle SQL error value and an XA error value.Process generic XA exception.Perform XA operations.XAER_RMERR Oracle Error Code ORA 3113 ORA 3114 ORA 24756 ORA 24764 ORA 24765 ORA 24766 ORA 24767 ORA 25351 all other ORA errors XA Error Handling The following example uses the OracleXAException class to process an XA exception: try { . ■ public int getXAError() This method returns the XA error code pertaining to the exception.XA_HEURMIX XAException. a standard ORA error number or 0 if there is no Oracle SQL error. Mapping Between Oracle Errors and XA Errors Oracle errors correspond to XA errors in OracleXAException instances as documented in Table 28–2. the code drops through to process a generic XA exception..xa.XA_RETRY XAException.XA_RDONLY XAException.XAER_RMFAIL XAException. The OracleXAException class has the following methods: ■ public int getOracleError() This method returns the Oracle SQL error code pertaining to the exception. XA error values are defined in the javax.XAException class..XA_HEURCOM XAException.getOracleError().......transaction. .. . System.. Table 28–2 Oracle-XA Error Mapping XA Error Code XAException. } catch(XAException xae) {.XA_HEURRB XAException.out. } catch(OracleXAException oxae) { int oraerr = oxae. 28-14 Oracle Database JDBC Developer's Guide and Reference .XAER_RMFAIL XAException.

Distributed Transactions 28-15 . This section covers the following topics: ■ ■ Summary of Imports for Oracle XA Oracle XA Code Sample Summary of Imports for Oracle XA You must import the following for Oracle XA functionality: import import import import import oracle. if the code will run inside Oracle Database and access that database for SQL operations.*. oracle.OracleXid. oracle.xa package.Implementing a Distributed Transaction Oracle XA Optimizations Oracle JDBC has functionality to improve performance if two or more branches of a distributed transaction use the same database instance.jdbc.jdbc.jdbc.OracleXAException.client. This way it can interpret the meaning of XA_RDONLY return values.*. the joined transaction through the OracleXAResource instance that returned XA_OK or failed. oracle.xa. some of which have XA-related classes as subclasses.pool package has classes for connection pooling functionality. and OracleXAResource classes.jdbc.xa. The transaction manager can use the OracleXAResource class isSameRM method to determine if two OracleXAResource instances are using the same resource manager.pool. import oracle. even if updates are made.jdbc. in case of failure.jdbc.server. then your code can use the fully qualified names of the oracle.jdbc.xa.xa. each to a separate database.xa. you must import oracle. In such a circumstance.*.xa. The oracle. the prepare method of only one of these OracleXAResource instances will return XA_OK or will fail. The rest will return XA_RDONLY. Implementing a Distributed Transaction This section provides an example of how to implement a distributed transaction using Oracle XA functionality. This allows the transaction manager to implicitly join all the transaction branches and commit or roll back. If your application must access another Oracle Database as part of an XA transaction using the server-side Thin driver.server instead of oracle. javax.*. The client and server packages each have versions of the OracleXADataSource.transaction. Oracle XA Code Sample This example uses a two-phase distributed transaction with two transaction branches.jdbc. Abstract versions of these three classes are in the top-level oracle.xa.client classes.xa. OracleXAConnection. Alternatively.jdbc.client. meaning that the OracleXAResource instances associated with these branches are associated with the same resource manager.

*.OracleXAException. Prepare branch #1.xa.*.getConnection(). // You can put a database name after the @ sign in the connection URL.sql. oracle. this example combines code that would typically be in a middle tier with code that would typically be in a transaction manager. oracle.pool. End transaction branch #2. Start transaction branch #2.Implementing a Distributed Transaction Note that for simplicity.setURL(URL1). 4.jdbc.setPassword("tiger"). 6. 28-16 Oracle Database JDBC Developer's Guide and Reference . ods2. 2. oracle. Execute DML operations on branch #2.*. // Create second DataSource and get connection OracleDataSource ods2 = new OracleDataSource(). ods1.setURL(URL2).setPassword("tiger"). ods2. 10. 3.jdbc. Commit branch #1. such as the OracleXAResource method invocations and the creation of transaction IDs.xa.sql. // You import import import import import import import import need to import the java. javax.transaction. // Create first DataSource and get connection OracleDataSource ods1 = new OracleDataSource(). ods2.sql package to use JDBC java.jdbc.*. ods1. the specifics of creating transaction IDs and performing SQL operations are not shown here.xa.setUser("scott"). Connection conna = ods1. End transaction branch #1.jdbc. Execute DML operations on branch #1.client. oracle. 8. This example performs the following sequence: 1.*. oracle. The complete example is shipped with the product.jdbc. ods1. For brevity. Start transaction branch #1.OracleXid. class XA4 { public static void main (String args []) throws SQLException { try { String URL1 = "jdbc:oracle:oci:@".xa. Connection connb = ods2. Commit branch #2. String URL2 ="jdbc:oracle:thin:@(description=(address=(host=dlsun991) (protocol=tcp)(port=5521))(connect_data=(sid=rdbms2)))". 7.setUser("scott"). 9. javax.getConnection(). 5. Prepare branch #2.*.

// Prepare a statement to create the table Statement stmtb = connb. oxds2.setUser("scott").setURL("jdbc:oracle:oci:@").execute ("create table my_tab (col1 char(30))"). } catch (SQLException e) { // Ignore an error here too } try { // Drop the test table stmtb.Implementing a Distributed Transaction // Prepare a statement to create the table Statement stmta = conna. OracleXADataSource oxds2 = new OracleXADataSource(). } catch (SQLException e) { // Ignore an error here } try { // Create a test table stmtb.setPassword("tiger").createStatement (). oxds1. oxds1. OracleXADataSource oxds1 = new OracleXADataSource(). } catch (SQLException e) { // Ignore an error here too } // Create XADataSource instances and set properties.setURL("jdbc:oracle:thin:@(description=(address=(host=dlsun991) (protocol=tcp)(port=5521))(connect_data=(sid=rdbms2)))").createStatement ().execute ("drop table my_table").execute ("drop table my_tab").setPassword("tiger"). oxds2.execute ("create table my_table (col1 int)"). try { // Drop the test table stmta.setUser("scott"). // Get XA connections to the underlying data sources Distributed Transactions 28-17 . oxds1. oxds2. } catch (SQLException e) { // Ignore an error here } try { // Create a test table stmta.

if (prp1 == XAResource. oxar2.commit (xid1.TMNOFLAGS).getConnection().println("Return value of prepare 2 is " + prp2). if (!((prp2 == XAResource.getXAResource(). // Create the Xids With the Same Global Ids Xid xid1 = createXid(1). // Prepare the RMs int prp1 = oxar1.IMPORTANT oxar1.TMSUCCESS). boolean do_commit = true.commit (xid2.TMSUCCESS). XAResource oxar2 = pc2.getConnection(). 28-18 Oracle Database JDBC Developer's Guide and Reference .out.println("Is oxar1 same as oxar2 ? " + oxar1.XA_RDONLY))) do_commit = false. System.TMNOFLAGS).end(xid1.isSameRM(oxar2)).prepare (xid2). doSomeWork2 (conn2).XA_RDONLY))) do_commit = false. int prp2 = oxar2. XAResource. false).end(xid2. if (!((prp1 == XAResource.println("Return value of prepare 1 is " + prp1). // Get the XA resources XAResource oxar1 = pc1. XAResource.getXAConnection(). Connection conn2 = pc2. XAResource. XAResource. // Close connections conn1.prepare (xid1).rollback (xid2).start (xid1.out.XA_OK) || (prp1 == XAResource. // Execute SQL operations with conn1 and conn2 doSomeWork1 (conn1). if (prp2 == XAResource.Implementing a Distributed Transaction XAConnection pc1 XAConnection pc2 = oxds1. Xid xid2 = createXid(2). conn1 = null. false).println("do_commit is " + do_commit).start (xid2. System. else oxar1. = oxds2.XA_OK) || (prp2 == XAResource.getXAResource().out. // Start the Resources oxar1.XA_OK) if (do_commit) oxar2. System. else oxar2.getXAConnection().XA_OK) if (do_commit) oxar1.out. System. // END both the branches -. // Get the physical connections Connection conn1 = pc1.rollback (xid1).close(). oxar2.

} private static void doSomeWork2 (Connection conn) throws SQLException {.executeQuery ("select col1 from my_table").next()) System. } catch (SQLException sqe) { sqe. ResultSet rset = stmta. conna.. stmta = null.getXAError())..} private static void doSomeWork1 (Connection conn) throws SQLException {.println("Col1 is " + rset.next()) System. rset = null. } catch (XAException xae) { if (xae instanceof OracleXAException) { System. stmtb. conn2 = null. pc2 = null.close(). while (rset.. rset = stmtb. System.Execute SQL operations.Implementing a Distributed Transaction conn2. connb. stmtb = null.Execute SQL operations.out.executeQuery ("select col1 from my_tab"). pc1. stmta. pc1 = null.out.getOracleError()).close().close(). connb = null..close().close().getInt(1)).println("XA Error is " + ((OracleXAException)xae). } } } static Xid createXid(int bids) throws XAException {.println("Col1 is " + rset..println("SQL Error is " + ((OracleXAException)xae). conna = null. rset.. while (rset. rset = null...} } Distributed Transactions 28-19 . rset..printStackTrace().Create transaction IDs.close()..getString(1))..close().close(). pc2.out.out.close()..

to enable the Native XA feature. This section covers the following topics: ■ ■ OCI Native XA Thin Native XA OCI Native XA Native XA is enabled through the use of the tnsEntry and nativeXA properties of the OracleXADataSource class.dll and heteroxa11_g. it is recommended that the application simply check for XAException or SQLException. The OCI driver uses the C/XA library of Oracle to support distributed transactions.dll files to enable the Native XA feature. 28-20 Oracle Database JDBC Developer's Guide and Reference . the Thin driver used PL/SQL procedures to send XA commands to the server because Thin native APIs were not available. " Oracle Extended Data Source Properties" on page 8-4 for explanation of these properties. Configuration and Installation On a Sun Solaris or Linux system. you need the shared libraries. the Thin native APIs are available and are used by default to send XA commands. Note: Currently. Exception Handling When using the Native XA feature in distributed transactions. this method is very slow. The use of native APIs provides high performance gains as compared to the use of PL/SQL procedures. which requires that an XAConnection be obtained for each thread before resuming a global transaction.so and libheteroxa11_g. Note: Libraries with the _g suffix are debug libraries. These files must be installed and available in the Windows DLL path for the Native XA feature to work properly. In order for the Native XA feature to work properly. rather than OracleXAException or OracleSQLException. Prior to Oracle Database 10g. There is a huge performance difference between the two methods of sending XA commands to the server. OCI Native XA does not work in a multithreaded environment. libheteroxa11. Through native APIs. these libraries must be installed and available in the Sun Solaris search path.so. On a Microsoft Windows system. See Also: Table 8–2. Starting from Oracle Database 10g. However.Native-XA in Oracle JDBC Drivers Native-XA in Oracle JDBC Drivers In general. XA commands can be sent to the server in the following ways: ■ ■ Through PL/SQL procedures. This method is faster than using PL/SQL procedures. you need the heteroxa11.

.. This is unlike the case of the JDBC OCI driver in which the support for Native XA is not enabled by default.setNativeXA(false). You can disable Native XA by calling setNativeXA(false) on the XA data source as follows: . Thin Native XA Like the JDBC OCI driver.. . // Set the nativeXA property to use Native XA feature oxds.. the JDBC Thin driver provides support for Native XA by default.Native-XA in Oracle JDBC Drivers See Also: "Native XA Messages" on page C-9 for a listing of Native XA messages. For example. // Create a XADataSource instance OracleXADataSource oxds = new OracleXADataSource(). oxds. Distributed Transactions 28-21 ..setTNSEntryName("ora805").. . // Set the tnsEntry property to an older DB as required oxds.. However. Native XA Code Example The following portion of code shows how to enable the Native XA feature: . // Create a XADataSource instance OracleXADataSource oxds = new OracleXADataSource(). you may need to disable Native XA as a workaround for a bug in the Native XA code. // Disabling Native XA oxds. Note: The mapping from SQL error codes to standard XA error codes does not apply to the Native XA feature..setURL(url)..setNativeXA(true)... the JDBC Thin driver also provides support for Native XA.

Native-XA in Oracle JDBC Drivers 28-22 Oracle Database JDBC Developer's Guide and Reference .

"JDBC DMS Metrics" . Part VIII contains the following chapters: ■ ■ ■ Chapter 29.Part VIII Manageability This part discusses the database management and diagnosability support in Oracle Java Database Connectivity (JDBC) drivers. "Database Management" Chapter 30. "Diagnosability in JDBC" Chapter 31.

.

29 Database Management Oracle Database 11g Release 1 (11. You cannot be connected to a shared server through a dispatcher. This is similar to the way you would start up or shut down a database instance from SQL*Plus. to configure system/manager to connect as sysdba with the JDBC Thin driver.1) provides many new features for managing the database. To use the startup and shutdown methods. perform the following: 1. type: orapwd file=$ORACLE_HOME/dbs/orapw entries=5 Enter password: password 2. in oracle. From the command line.1) introduces two new JDBC methods.jdbc. you must be connected as SYSDBA or SYSOPER. As opposed to the JDBC Thin driver. To connect as SYSDBA or SYSOPER with Oracle JDBC drivers. Connect to database as SYSDBA and run the following commands from SQL*Plus: GRANT SYSDBA TO system. For example. you must have a dedicated connection to the server. To use these methods. This chapter describes the following: ■ ■ Database Startup and Shutdown Database Change Notification Database Startup and Shutdown Oracle Database 11g Release 1 (11.ora and add the following line: REMOTE_LOGIN_PASSWORDFILE=EXCLUSIVE 4. Restart the database instance. PASSWORD system Changing password for system New password: password Retype new password: password 3. the JDBC OCI driver can connect as SYSDBA or SYSOPER locally without specifying a password file on the server. Database Management 29-1 . To log on as SYSDBA with the JDBC Thin driver you must configure the server to use the password file. Edit init. you need to set the internal_logon connection property accordingly.OracleConnection that enable you to start up and shut down an Oracle Database instance. startup and shutdown.

and run the following commands to mount and open the database instance: ALTER DATABASE MOUNT ALTER DATABASE OPEN Note: The startup method will start up the database using the server parameter file. To use this method. the application must first connect to the database as a SYSDBA or SYSOPER in the PRELIM_AUTH mode. In this case. You have to reconnect as SYSDBA or SYSOPER. which is the only connection mode that is permitted when the database is down. the DBA). The startup method takes a parameter that specifies the database startup option. These options are defined in the oracle. Refuses new transactions and waits for active transactions to end. These options are defined in the oracle. the parameter specifies the database shutdown option. The startup method only starts up a database instance. Table 29–2 lists the supported database shutdown options. Starts up the database and allows database access only to users with both the CREATE SESSION and RESTRICTED SESSION privileges (typically. You can do this by setting the new connection property prelim_auth to true. you must be connected to the database as a SYSDBA or SYSOPER. Does not wait for current calls to complete or users to disconnect from the database. 29-2 Oracle Database JDBC Developer's Guide and Reference . Table 29–1 lists the supported database startup options.Database Startup and Shutdown To start a database instance using the startup method. In the PRELIM_ AUTH mode. but without the PRELIM_AUTH mode. Refuses new local transactions and waits for active local transactions to end.OracleConnection. you can only start up a database instance that is down.DatabaseShutdownMode class. Table 29–2 Option ABORT CONNECT FINAL IMMEDIATE TRANSACTIONAL TRANSACTIONAL_LOCAL Supported Database Shutdown Options Description Does not wait for current calls to complete or users to disconnect from the database. Shuts down the database. the shutdown method also takes a parameter. It does not mount it nor open it. For shutdown options other than ABORT and FINAL.jdbc.jdbc. You cannot run any SQL statements in this mode.OracleConnection. you must call the shutdown method again with the FINAL option to actually shut down the database. Starts up the database with no restrictions. Table 29–1 Option FORCE NO_RESTRICTION RESTRICT Supported Database Startup Options Description Shuts down the database in the abort mode before starting a new instance. Refuses any new connection and waits for existing connection to end. The shutdown method enables you to shut down an Oracle Database instance. Like the startup method. Oracle JDBC drivers do not support database startup using the client parameter file.DatabaseStartupMode class.

TRANSACTIONAL_LOCAL.pool. The shut down option can be either CONNECT.FINAL) method must be preceded by another call to the shutdown method with one of the following options: CONNECT. TRANSACTIONAL_LOCAL. you need to create a password file for user "sys": * orapwd file=/path/orapw password=password entries=300 * and add the following setting in init.DatabaseStartupMode. prop. import java. Finish shutdown using the FINAL option. TRANSACTIONAL.ora: * REMOTE_LOGIN_PASSWORDFILE=EXCLUSIVE * then restart the database.Statement. 2. // Mounting and opening the database OracleDataSource ds1 = new OracleDataSource(). or IMMEDIATE.sql. Properties prop1 = new Properties(). In special circumstances to shut down the database as fast as possible. or IMMEDIATE. Example Example 29–1 illustrates the use of the startup and shutdown methods.com)(PORT=1521))" + "(CONNECT_DATA=(SERVICE_NAME=rdbms.setURL(DB_URL).setProperty("user". Dismount and close the database by calling the appropriate ALTER DATABASE command.close().OracleConnection.getConnection()."manager"). Database Management 29-3 . conn. the ABORT option can be used. public static void main(String[] argv) throws Exception { // Starting up the database: OracleDataSource ds = new OracleDataSource().XYZ. A standard way to shut down the database is as follows: 1.setProperty("password".NO_RESTRICTION). 3."sys"). conn.setConnectionProperties(prop). OracleConnection conn = (OracleConnection)ds.util. import oracle. */ public class DBStartup { static final String DB_URL = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=XYZ.startup(OracleConnection.Database Startup and Shutdown Note: The shutdown(DatabaseShutdownMode."sysdba"). Otherwise the call hangs.jdbc. prop.jdbc. import oracle. Initiate shutdown by prohibiting further connections or transactions in the database.setProperty("prelim_auth". prop. ds. prop.com)))". ds. This is the equivalent to SHUTDOWN ABORT in SQL*Plus. /** * To logon as sysdba.devplmt. TRANSACTIONAL.setProperty("internal_logon". Properties prop = new Properties(). Example 29–1 Database Startup and Shutdown import java."true").Properties.OracleDataSource.

setProperty("internal_logon". conn1.executeUpdate("ALTER DATABASE OPEN").setProperty("password". These queries are part of the registration. perform the following: 1.getConnection(). } } Database Change Notification Generally.setProperty("user". conn2.setProperty("user". stmt1."sys"). this is efficient only when the data rarely changes in the database.DatabaseShutdownMode.setProperty("internal_logon". The data cache has to be updated or invalidated when the data changes in the database. Properties prop = new Properties(). conn2.close().1) Oracle JDBC drivers provide support for the Database Change Notification feature of Oracle Database.IMMEDIATE). ds1. stmt1.FINAL). Its goal is to avoid redundant queries to the database. The JDBC drivers can register SQL queries with the database and receive notifications in response to the following: ■ ■ DML or DDL changes on the objects associated with the queries DML or DDL changes that affect the result set The notifications are published when the DML or DDL transaction commits (changes made in a local transaction do not generate any event until they are comitted).DatabaseShutdownMode. stmt.close(). Using this functionality of the JDBC drivers.executeUpdate("ALTER DATABASE MOUNT"). ds2."sysdba").executeUpdate("ALTER DATABASE CLOSE NORMAL"). prop. multi-tier systems can take advantage of the Database Change Notification feature to maintain a data cache as updated as possible by receiving invalidation events from the JDBC drivers.getConnection(). Statement stmt = conn1. The 11g Release 1 (11. prop. ds2.setURL(DB_URL). 2. prop1. // Shutting down the database OracleDataSource ds2 = new OracleDataSource().executeUpdate("ALTER DATABASE DISMOUNT").setConnectionProperties(prop). OracleConnection conn1 = (OracleConnection)ds1. conn2.setConnectionProperties(prop1).close(). stmt1."manager"). To use Oracle JDBC driver support for Database Change Notification.close()."manager"). Query association: After you have created a registration.createStatement().shutdown(OracleConnection.setURL(DB_URL). ds1.setProperty("password". stmt.shutdown(OracleConnection."sys"). 29-4 Oracle Database JDBC Developer's Guide and Reference .createStatement()."sysdba"). Statement stmt1 = conn2. Registration: You first need to create a registration. However.Database Change Notification prop1. you can associate SQL queries with it. a middle-tier data cache duplicates some data from the back-end database server. prop1. OracleConnection conn2 = (OracleConnection)ds2. stmt. prop.

There are two ways to create a registration: ■ The JDBC-style of registration: Use the JDBC driver to create a registration on the server. It returns a DatabaseChangeRegistration object. To set these options. A workaround would be to either create a new registration without this object or ignore the events that are related to this object. and the registration survives.Database Change Notification 3. Table 29–3 lists some of the registration options that can be set. the registration is not attached to the connection. The registration options have a direct impact on the notification events that the JDBC drivers will create. the JDBC drivers enable you to attach statements (queries) to this registration. These options are defined in the oracle. Creating a Registration Creating a registration is a one-time process and is done outside of the currently used transaction. a registration is a persistent entity that exists on all nodes. The PL/SQL-style of registration: If you want a PL/SQL stored procedure to handle the notifications. If a node goes down.jdbc. For example. The JDBC driver launches a new thread that listens to notifications from the server (through a dedicated channel) and converts these notification messages into Java events. you need to grant the CHANGE NOTIFICATION privilege to the user. As in the JDBC-style of registration. You can use the registerDatabaseChangeNotification method of the oracle. then you need to run the following command in the database: grant change notification to scott. Oracle database communicates these notifications to the JDBC drivers through a dedicated network connection and JDBC drivers convert these notifications to Java events. However the JDBC drivers do not get notifications from the server because the notifications are handled by the PL/SQL stored procedure. The driver then notifies all the listeners registered with this registration. if you connect to the database using the SCOTT user name. In an Oracle RAC environment. You can set certain registration options through the options parameter of this method. You need a JDBC connection to create a registration. Note: ■ There is no way to remove one particular object (table) from an existing registration. The API for creating a registration in the server is executed in its own transaction and is committed immediately. however. Notification: Notifications are created in response to changes in tables or result set. Database Management 29-5 .jdbc.OracleConnection interface.util. which can then be used to associate a statement with this registration. It also opens a listener socket that will be used by the database to send notifications. then create a PL/SQL-style registration. use the java. The registerDatabaseChangeNotification method creates a new database change registration in the database server with the given options.OracleConnection interface to create a JDBC-style of registration. You can close the connection after creating a registration.Properties object. Also. then the registration continues to exist and will be notified when the tables change. Example 29–1 illustrates how to use the Database Change Notification feature.

DELETE operations will not generate any database change event. DCN_QUERY_CHANGE_NOTIFICATION Activates query change notification instead of object change notification. NTF_LOCAL_HOST NTF_LOCAL_TCP_PORT NTF_QOS_PURGE_ON_NTFN NTF_QOS_RELIABLE NTF_TIMEOUT Specifies the IP address of the computer that will receive the notifications from the server. DCN_IGNORE_DELETEOP DCN_IGNORE_INSERTOP DCN_IGNORE_UPDATEOP DCN_NOTIFY_CHANGELAG DCN_NOTIFY_ROWIDS Database change events will include row-level details. such as operation type and ROWID. Specifies if the registration should be expunged on the first notification event. Associating a Query with a Registration After you have created a registration or mapped to an existing registration. You can associate a query with registration using the setDatabaseChangeRegistration method defined in the OracleStatement class.0 database. The following code snippet illustrates how to associate a query with a registration: 29-6 Oracle Database JDBC Developer's Guide and Reference . Like creating a registration. Specifies the number of transactions by which the client is willing to lag behind. If set to true. If there exists a registration. Specifies whether or not to make the notifications persistent. This method is particularly useful if you have created a registration using PL/SQL and want to associate a statement with it. Table 29–3 Option Database Change Notification Registration Options Description If set to true. which comes at a performance cost. then you can also use the getDatabaseChangeRegistration method to map the existing registration with a new DatabaseChangeRegistration object. even if the DCN_NOTIFY_ROWIDS option is set to true. UPDATE operations will not generate any database change event. Note: This option is available only when running against an 11. INSERT operations will not generate any database change event. Specifies the time in seconds after which the registration will be automatically expunged by the database. Specifies the TCP port that the driver should use for the listener socket. Note: If this option is set to any value other than 0. then this socket will be used by the new database change registration as well. The query will be associated even if the local transaction is rolled back. This method takes a DatabaseChangeRegistration object as parameter. See: Refer to the Javadoc for more information about the APIs. associating a query with a registration is a one-time process and is done outside of the currently used registration. then ROWID level granularity of information will not be available in the events. If set to true. you can associate a query with it.Database Change Notification Note: If a listener socket (created by a different registration) exists.

. // conn is a OracleConnection object..' is executed. if it refreshes the data cache by querying the database. You can attach a listener to a registration using the addListener method.. If the code is time-consuming. The listener code can then use the event to make decisions about the data cache. The event contains the object ID of the database object that has changed and the type of operation that caused the change.OracleConnection. Statement stmt = conn.. . . You must pass the DatabaseChangeRegistration object as a parameter to this method. ...addListener(list).. // conn is a OracleConnection object. This method deletes the registration from the server and the driver and closes the listener socket. Note: The listener code must not slow down the JDBC notification mechanism. dcr. To unregister a registration. // Attach the listener to the registration. The following code snippet illustrates how to attach a listener to a registration: .registerDatabaseChangeNotifictaion(prop). // Note: DCNListener is a custom listener and not a predefined or standard // lsiener DCNListener list = new DCNListener(). The driver then constructs a new Java event.jdbc. Database Management 29-7 . the event may also contain row-level detail information. Deleting a Registration You need to explicitly unregister a registration to delete it from the server and release the resources in the driver.. then it needs to be executed within its own thread.createStatement().. for example.. the database server notifies the JDBC driver. You can unregister a registration using a connection different from one that was used for creating it.registerDatabaseChangeNotifictaion(prop).setDatabaseChangeRegistration(dcr). attach a listener to the registration. // any query that will be executed with the 'stmt' object will be associated with // the registration 'dcr' until 'stmt' is closed or // '((OracleStatement)stmt). // prop is a Properties object containing the registration options. Notifying Database Change Events To receive database change notifications.. DatabaseChangeRegistration dcr = conn. Depending on the registration options. ..Database Change Notification . identifies the registration to be notified. When a database change event occurs. // associating the query with the registration ((OracleStatement)stmt). // prop is a Properties object containing the registration options.setDatabaseChangeRegistration(null). you can use the unregisterDatabaseChangeNotification method defined in oracle. and notifies the listeners attached to the registration. DatabaseChangeRegistration dcr = conn.

static String URL.DatabaseChangeRegistration. oracle.println("Error: You need to provide the URL in the first argument. public class DBChangeNotification { static final String USERNAME= "scott". oracle.out. } } void run() throws SQLException { 29-8 Oracle Database JDBC Developer's Guide and Reference . public static void main(String[] argv) { if(argv. oracle.run(). java.OracleConnection.Database Change Notification If the registration was created outside of JDBC.println(" For example: > java -classpath .sql. static final String PASSWORD= "tiger".").jdbc. it does not free any resources in the driver.dcn. } catch(SQLException mainSQLException ) { mainSQLException. Therefore in the database you need to grant the following privilege to the user: grant change notification to scott. System.sql.jdbc.yourdomain.jdbc. In this example.DatabaseChangeEvent.SQLException.util. Example 29–2 import import import import import import import import import import Database Change Notification java. try { demo.DatabaseChangeListener.:ojdbc5.jdbc.printStackTrace(). say using PL/SQL.exit(1).ResultSet. System.length < 1) { System.com)(PORT=1521))(CO NNECT_DATA= (SERVICE_NAME=yourservicename)))\""). oracle. then you must pass the registration ID instead of the DatabaseChangeRegistration object.jdbc. java.jdbc. The method will delete the registration from the server.Properties. Example Example 29–2 illustrates how to use the Database Change Notification feature.dcn. however.dcn.OracleDriver. oracle. oracle. the SCOTT user is connecting to the database.Statement. DBChangeNotification demo = new DBChangeNotification().sql.OracleStatement.jar DBChangeNotification \"jdbc:oracle:thin: @(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=yourhost. java. } URL = argv[0].out.

setProperty(OracleConnection. // first step: create a registration on the server: Properties prop = new Properties(). } catch(SQLException ex) { // if an exception occurs. This thread will be // dedicated to DCN (accept connection to the server and dispatch the events to // the listeners).14."). you need to provide the TCP address of the client. // For example: // prop. for(int i=0. // if connected through the VPN. ResultSet rs = stmt. // second step: add objects in the registration: Statement stmt = conn. Note that for now the registration is empty (we haven't registered // any table). dcr.executeQuery("select * from dept where deptno='45'").setDatabaseChangeRegistration(dcr).Database Change Notification OracleConnection conn = connect().close().addListener(list).unregisterDatabaseChangeNotification(dcr)."true"). rs.createStatement(). stmt. This also opens a new thread in the drivers. while (rs.getTables().length. try { // add the listenerr: DCNDemoListener list = new DCNDemoListener(this).DCN_NOTIFY_ROWIDS. DatabaseChangeRegistration dcr = conn. if(conn != null) conn.setProperty(OracleConnection.out. // Ask the server to send the ROWIDs as part of the DCN events (small performance // cost): prop.12"). throw ex.registerDatabaseChangeNotification(prop).13.close().println(tableNames[i]+" is part of the registration. } finally { try { Database Management 29-9 . It sends the client address (ip address and port) that // the server will use to connect to the client and send the notification // when necessary. // associate the statement with the registration: ((OracleStatement)stmt).i<tableNames. // The following operation does a roundtrip to the database to create a new // registration for DCN.next()) {} String[] tableNames = dcr."14.NTF_LOCAL_HOST.i++) System. we need to close the registration in order // to interrupt the thread otherwise it will be hanging around.

RETURN_GENERATED_KEYS).close().next()) System.executeUpdate("insert into dept (deptno. conn2.Statement. stmt2. conn3. } /** * Creates a connection the database.URL.getString(1)). return (OracleConnection)dr.printStackTrace().DBChangeNotification. if(autoGeneratedKey. if(autoGeneratedKey.dname) values ('45'.executeUpdate("insert into dept (deptno. prop.Statement. ResultSet autoGeneratedKey = stmt2. */ class DCNDemoListener implements DatabaseChangeListener { 29-10 Oracle Database JDBC Developer's Guide and Reference .setAutoCommit(false).createStatement().Database Change Notification // Note that we close the connection! conn. stmt2.println("inserted one row with ROWID="+autoGeneratedKey. Properties prop = new Properties(). conn3. } catch(SQLException ex) { ex.close().getGeneratedKeys(). prop. Statement stmt2 = conn2.prop).getString(1)). conn2.unregisterDatabaseChangeNotification(dcr).setProperty("password".out.wait().getGeneratedKeys().dname) values ('50'. } } /** * DCN listener: it prints out the event details in stdout.close().DBChangeNotification.'cool dept')".println("inserted one row with ROWID="+autoGeneratedKey. } // wait until we get the event try{ this.printStackTrace().next()) System.'fun dept')". stmt2.RETURN_GENERATED_KEYS). OracleConnection conn3 = connect(). } } synchronized( this ) { // The following code modifies the dept table and commits: try { OracleConnection conn2 = connect(). autoGeneratedKey = stmt2.setProperty("user".PASSWORD).connect(DBChangeNotification.USERNAME). } catch(Exception innerex){ innerex.close().out.commit(). conn2.} catch( InterruptedException ie ) {} } // At the end: close the registration (comment out these 3 lines in order // to leave the registration open). */ OracleConnection connect() throws SQLException { OracleDriver dr = new OracleDriver().

out. the query registration with finer granularity. That is. synchronized( demo ){ demo. what you register is the name of the tables involved and not the query itself.2). In other words.Database Change Notification DBChangeNotification demo.DEPT table and commit it. you will be notified although the result of your query has not changed.} } } This code will also work with Oracle Database 10g Release 2 (10.println(e. Database Management 29-11 .println("DCNDemoListener: got an event ("+this+" running on thread "+t+")"). DCNDemoListener(DBChangeNotification dem) { demo = dem. you might select one single row of a table and if another row is updated. System.notify(). if you leave the registration open instead of closing it. say from SQL*Plus. When using Oracle Database 11g. Now if you run a DML query that changes the SCOTT.out. System. In this example. you can use a different option. This can be done by setting the DCN_QUERY_CHANGE_ NOTIFICATION option.currentThread(). then the database change notification thread continues to run. This code uses table registration. then the Java program prints the notification. when you register a SELECT query.toString()). } public void onDatabaseChangeNotification(DatabaseChangeEvent e) { Thread t = Thread.

Database Change Notification 29-12 Oracle Database JDBC Developer's Guide and Reference .

util. the logging feature provided by JDBC driver releases prior to Oracle Database 11g. differs from the java.util. In Oracle Database 11g. and detailed JDBC internal events.0. such as entry to and exit from internal JDBC methods. running of SQL statements. the JDBC drivers no longer support J2SE 2.util.logging framework.util. Also refer to the Javadoc for java. It logs specific classes of information more consistently. Readers are advised to refer to the Sun Microsystems Web site to obtain information about these standard frameworks. Oracle JDBC drivers provide the following diagnosabilty features that enable users to identify and fix problems in their JDBC applications: ■ ■ Logging Diagnosability Management The diagnosability features of the JDBC drivers are based on the standard java. Only new parameters are added to the existing standard java. These features enable users to diagnose problems in the applications that use Oracle JDBC drivers and the problems in the drivers themselves. These Diagnosability in JDBC 30-1 . The enhanced logging system makes effective use of log levels to enable users to restrict log output to things of interest.util. Information about these standard frameworks is not covered in this document. making it easier for the user to understand the log file. Therefore. Events can include user-visible events. These versions of J2SE did not include java. JDBC drivers supported J2SE 2.0 and 3. They also reduce the effort required to develop and maintain Java applications that access an Oracle Database instance using Oracle JDBC drivers.logging configuration file. the logging feature of JDBC drivers makes full use of the standard java. such as SQL exceptions.30 Diagnosability in JDBC In Oracle Database 11g.0 and 3.0. Prior to Oracle Database 11g.logging framework and the javax. Users can enable this feature to log specific events or all the events.logging. This feature does not introduce new APIs or configuration files.logging package. Note: Logging This feature logs information about events that occur when JDBC driver code runs. the JDBC drivers have been enhanced by including new diagnosabilty features and improving existing diagnosabilty features.logging for information about the various configuration options available.management MBean framework. Therefore.util.

therefore.name=<loader> 30-2 Oracle Database JDBC Developer's Guide and Reference . The debug JAR file must be included in the CLASSPATH environment variable. which means that logging is enabled for the entire application. the exact content of the logs are likely to change from release to release. To a large extent the log content is dependent on the details of the implementation.util. and therefore. which are indicated with a "_g" in the file name.Trace system property. you must enable and configure JDBC logging. is the only Oracle JDBC JAR file in the CLASSPATH environment variable.jar or ojdbc6_g. get the ObjectName of the Diagnosability MBean. The details of the implementation change with every release. java -Doracle. or if you cannot or do not want to change the source code of the application.jar. This section covers the steps you must perform to enable and use JDBC logging.oracle. ■ Programmatically You can programmatically enable or disable logging in the following way: First.jar or ojdbc6_g. Note: Oracle does not guarantee the exact content of the generated logs. do not generate any log output when used. like ojdbc5_g.jar. The optimized JAR files do not contain any logging code and. It describes the following: ■ ■ ■ ■ ■ Configuring the CLASSPATH Environment Variable Enabling Logging Configuring Logging Using Loggers An Example Configuring the CLASSPATH Environment Variable Oracle ships several JAR files for each version of the JDBC drivers.. The ObjectName is com. Note: Ensure that the debug JAR file.Logging parameters are identical in use to the existing parameters and are intrinsic to using java. you must use the debug JAR files. say ojdbc5_g. To get log output. Setting the system property enables global logging.jdbc:type=diagnosability. Enabling Logging You can enable logging in the following ways: ■ Setting a Java system property You can enable logging by setting the oracle..jdbc.jdbc.Trace=true . You can use global logging if you want to debug the entire application.logging. Enabling and Using JDBC Logging Before you can start debugging your Java application.

ObjectName name = new javax.setAttribute(name.=:\"]+" . Configuring Logging To generate a useful and detailed log. javax. // enable logging mbs.properties -Doracle.Attribute("LoggingEnabled".Logging where.logging system.getPlatformMBeanServer(). Programmatic enabling and disabling of logging helps you to control what parts of your application need to generate log output.config.logging and provides some initial settings that you can start with. OracleLog. You may use this sample file as is. This file can reside anywhere. new javax. you must configure java.ObjectName("com. You can use both java.util. edit the file and use it. false)).config.jdbc. "LoggingEnabled")).logging.oracle.management. Now.util. Usually this is not of much use. // disable logging mbs. // find out if logging is enabled or not System.println("LoggingEnabled = " + mbs.file=/jdbc/demo/OracleLog.MBeanServer mbs = java. A sample configuration file. loader is a filtered version of the result of calling toString on the context ClassLoader.ManagementFactory.util.file and oracle.setAttribute(name.Trace=true Diagnosability in JDBC 30-3 . you must identify it to the Java run-time. ""). To generate a more useful and detailed log.logging.jdbc. // get the MBean server javax. It contains basic information about how to configure java.properties. is provided as part of the JDBC installation in the demo directory.toString(). Note: Enabling logging using either of the methods would only generate a minimal log of serious errors.logging. or create an entirely new file of any name.util. java -Djava. write the following lines of code: // compute the ObjectName String loader = Thread.Trace at the same time.jdbc:type=diagnosability.getAttribute(name.management. It is read by the java.Attribute("LoggingEnabled".config.file=/jdbc/demo/OracleLog.util.name="+loader) .lang.logging.management. you must configure java.management. new javax. To use a configuration file. true)).logging.out.replaceAll("[. For example: java -Djava.util. This can be done by setting a system property.getContextClassLoader(). This can be done either through a configuration file or programmatically.management. rename the file and edit it.management.util.properties.currentThread().

ConsoleHandler.FileHandler java. You can also configure java. ■ FINER 30-4 Oracle Database JDBC Developer's Guide and Reference .config.jdbc.ConsoleHandler.logging.SimpleFormatter 3. To do so.logging.SimpleFormatter This will generate exactly the same log output and save it in a file named jdbc.properties.util. ■ WARNING Logs SQLWarnings and bad but not fatal internal conditions.logging.properties file.logging. You can use any name you choose. java -Djava.file=<filepath>/myConfig.logging. You can control the amount of detail by changing the level settings.util.level=SEVERE oracle.FileHandler.logging.util.level=INFO java..pattern=jdbc.log java.jdbc.handlers=java.log in the current directory.logging.logging.logging. It produces a fairly high volume of log messages.ConsoleHandler java. You can also create and use your own configuration file by following these steps: 1.formatter=java. Insert the following lines of text in the file: .properties .Logging You can use the default OracleLog.util. ■ CONFIG Logs SQL strings that are executed.FileHandler. Set the system property to use this configuration file. 4. The defined levels from the least detailed to the most detailed are the following: ■ OFF Turns off logging. Create a file named myConfig. It produces a relatively low volume of log messages.logging.util.level=SEVERE oracle.util.count=1 java. ■ INFO Logs infrequent but significant events and errors.util. filepath is the path of the folder where you have saved the myConfig.handlers=java.FileHandler.jdbc.formatter=java.util.FileHandler..logging to dump the log output into a file. modify the configuration file as follows: . Save the file.properties file.jdbc.util.logging.util.level=INFO java.level=INFO oracle. ■ FINE Logs the entry and exit to every public method providing a detailed trace of JDBC operations.level=INFO oracle. ■ SEVERE Logs SQLExceptions and internal errors. It may or may not get you the desired output. 2.util.util.

and to the parent logger. The next line is oracle. change the java. The oracle.sql Diagnosability in JDBC 30-5 . the empty string. If you look at the first line of the configuration file you see .jdbc oracle.jdbc logger is a member of the logger tree. If as in this case.driver oracle. to reduce the amount of detail.level=SEVERE. the level is not set then it uses the parent level. If you restrict the log messages to one of the subloggers you will get substantially less output.jdbc. What will help is that the JDBC drivers use several subloggers. In this case the parent in the root logger. So a log message sent to oracle.FileHandler. for example. If the level is the same or less (less detailed) then it is sent to the FileHandler and to the parent logger.logging.jdbc. SEVERE. which there is not one.log is compared against that logger's level. The root logger is named "".Logging Logs calls to internal methods. and sent to the parent. This is setting the level of the root logger.jdbc. sometimes you need a lot of output from one part of the code and very little from other parts. Note: Levels more detailed than FINE generate huge log volumes. If the message passes the level check at that level. Loggers exist in a tree structure defined by their names. This sets the level of the logger named oracle. All this tree structure did not help you reduce the amount of output. ■ ALL Logs all the details. Using Loggers Setting the level reduces all the logging output from JDBC.jdbc.jdbc. it is not necessary to change the level of the oracle. To do that you must understand more about loggers. The parent of the oracle logger is the root logger (the empty string). Again it is checked against the level.util.xa oracle.level=INFO Although you can. Its parent is named oracle. The loggers used by Oracle JDBC drivers include the following: ■ ■ ■ ■ ■ ■ oracle.jdbc.rowset oracle.jdbc logger. In the example provided earlier. then the message is passed to the handler at that level.level setting from ALL to INFO: java. Logging messages are sent to a particular logger. INFO if you are following along. This is the most detailed level of logging.jdbc. oracle. However. Setting the FileHandler level will control what log messages are dumped into the log file. If the message level is the same or less it is passed to the handler.pool oracle.util. ■ FINEST Logs calls to high volume internal methods. 'oracle'. if any.logging.FileHandler.level=INFO.

level=INFO We want log output from both the oracle.jdbc. We will control the detail more explicitly at lower levels. Each logger inherits its level from its parent unless set explicitly. An Example Suppose you want to trace what is happening in the oracle. but will help us to keep track of what our test is doing. oracle.util package.jdbc.util.driver.driver. we set the level to INFO.sql component and also want to capture some basic information about the rest of the driver. Therefore.ConsoleHandler.level=OFF oracle.util.jdbc.level=INFO We only want to see the SQL execution from oracle. Therefore.util.jdbc. Therefore.driver loggers.util.logging. This is a more complex use of logging.sql.jdbc.util.level=INFO oracle. oracle. we turn it OFF.SimpleFormatter Let us consider what each line in the configuration file is doing.level=OFF We are using a DataSource in our test and do not want to see all of that logging. oracle. we set the level of the oracle logger to INFO. The following are the entries in the config file: # # set levels # .level=INFO 30-6 Oracle Database JDBC Developer's Guide and Reference . By setting the level of the root logger to SEVERE we ensure that all other loggers inherit that level except for the ones we set otherwise.Logging Note: The loggers used by the drivers may vary from release to release. Therefore.level=SEVERE oracle. non-Oracle components unless something fails badly.logging.handlers=java.ConsoleHandler.level=INFO oracle. oracle.jdbc. We do not want to see any logging from other.jdbc.pool.driver. we set the default level for all loggers to SEVERE.ConsoleHandler java.jdbc. This is a fairly low volume level.logging.formatter=java. Their common ancestor is oracle. If we were using XA or rowsets we would turn them off as well.level=OFF oracle.level=OFF We do not want to see the logging from the oracle.pool.level=SEVERE Sets the logging level of the root logger to SEVERE.logging.level=INFO java. oracle.sql. .sql and oracle.level=INFO # # configure handlers # oracle.util.jdbc.

and nothing from any other code.logging. oracle. it has certain performance. java.jar ojdbc6dms_g. a little bit of information from the core driver code.level=INFO We want to dump everything to the console which is System. we set the level to INFO.Logging We want to see what is happening in oracle. In this case.jar Diagnosability in JDBC 30-7 .sql.util.logging. and security issues. However.util. Logging involves protected access to a number of shared resources resulting in severely reduced scalability.formatter=java. java. scalability.SimpleFormatter We will use a simple. The following JAR files include full logging and should not be used in a sensitive environment: ■ ■ ■ ■ ojdbc5_g.jar ojdbc6dms. When logging is disabled. JDBC logging is not enabled and. and Security Issues Although the logging feature enables you to trace or debug your application and generate detail log output. This is intrinsic to the java.ConsoleHandler. in a typical production system. Performance. However.err.util.util. However. therefore. you will get moderately detailed information from the oracle. Security Concerns When full logging is enabled. When we run the test we will redirect stderr to a file. Performance and Scalability Issues Logging has substantial impact on performance. XMLFormatter is the best choice for logs that you send to Oracle Support. more or less human readable format.util. only certain JDBC JAR files include the JDBC logging feature. This provides a lot of information about the public method calls without overwhelming detail. we are doing the filtering with the loggers rather than the handler. It also has a negative impact on scalability.jar ojdbc5dms_g. When you run your test with this configuration file.jar The following JAR files include a limited logging capability: ■ ■ ojdbc5dms. JDBC logging is generally not enabled in production systems.logging. because it enables us to more easily use automated processing of the log output.ConsoleHandler. This is intrinsic to the logging feature. it will have no impact on performance. Scalability. will not have an impact on scalability.logging framework.handlers=java. You can also use XMLFormatter. it is almost guaranteed that all sensitive information will be exposed in the log files.logging.jar ojdbc6_g. Therefore.ConsoleHandler We are going to dump everything to stderr.sql package.

Enabling JDBC logging does not require any special permission. a defined value. In future releases. Security Concerns This feature can enable JDBC logging. This is a standard Java mechanism. or a bind value can appear in a log created using one of these JAR files. generating any log output requires the standard Java permission LoggingPermission. sensitive user data that is part of a SQL statement. the MBean will be enhanced to provide additional statistics about JDBC internals.Diagnosability Management Note: Database user names and passwords do not appear in log files created by these JAR files. 30-8 Oracle Database JDBC Developer's Guide and Reference . This MBean provides means to enable and disable JDBC logging. any JDBC operation that would generate log output will throw a security exception. Without this permission. oracle.driver. See Also: Refer to the JDBC JavaDoc for information about the OracleDiagnosabilityMBean API. once logging is enabled. Diagnosability Management The JDBC diagnosability management feature introduces an MBean. However.jdbc.OracleDiagnosabilityMBean. However.

1 the in following sections: ■ ■ ■ ■ Overview of JDBC DMS Metrics Determining the Type of Metric to Be Generated Generating the SQLText Metric Accessing DMS Metrics Using JMX Overview of JDBC DMS Metrics Starting with Oracle Database 10g. are enabled at all times. Customer use of end-to-end metrics in JDBC is generally discouraged. 9. This is by design and cannot be changed.1). But. In Oracle Database 11g Release 1 (11. End-to-end metrics are used for tagging application activity from the entry into the application code through JDBC to the database and back. DMS metrics are used to measure the performance of application components.2. the end-to-end metrics can be set only through DMS.31 JDBC DMS Metrics There are two kinds of metrics. and earlier versions of Oracle JDBC as it makes no attempt to retain compatibility with earlier versions. except those related to individual statements. This chapter discusses the DMS metrics generated by Oracle JDBC 11.1. Oracle Java Database Connectivity (JDBC) supports end-to-end metrics. end-to-end metrics and Dynamic Monitoring Service (DMS) metrics. All DMS metrics. The metrics generated in the Oracle JDBC 11. There are also no compatibility modes. 10.1 release are different from 10. All DMS metrics are available in the following DMS-enabled JAR files: ■ ■ ■ ■ ojdbc15dms.1.jar ojdbc6dms. if your application is using a DMS-enabled JAR file. JDBC DMS Metrics 31-1 .jar Any other JDBC JAR files do not generate any DMS metrics. Statement metrics can be reported consolidated for all statements in a connection or individually for each statement. A system that is dependent on the exact details of the DMS metrics generated by earlier versions of JDBC may have unexpected behavior when processing the metrics generated by Oracle JDBC 11.jar ojdbc6dms_g. the end-to-end metrics can be set directly by an application only when it is not using a DMS-enabled JAR files.2.jar ojdbc15dms_g.

one set of metrics is generated for each distinct statement object created by the JDBC driver. when consolidated statement metrics are generated. then each statement created will have a distinct 'execute' phase event.1 version of the DMS JAR file is not present in the classpath environment variable. one with a total time and average of 1 second and the other with a total time and average of 3 seconds. then JDBC checks the DMS update SQL text flag. There is only one list of statement metrics that is generated for both consolidated and individual statement metrics. Note: In the presence of Statement caching. The only difference between these two lists is the aggregation of the statements. then JDBC generates consolidated statement metrics.1 version of the DMS JAR file is present in the classpath environment variable. from two such statements created by the same connection. all statements created by a given connection use the same set of statement metrics. So. Changing the value of the sensor weight. Generating the SQLText Metric Depending on the version of DMS. If the sensor weight is less than or equal to DMSConsole. consider an 'execute' phase event. But. there are two mechanisms for determining the generating of the SQLText statement metrics: ■ If the 11. On the other hand. if consolidated statement metrics are used. it is enabled for all statements. If individual statement metrics are used. then there will be two distinct 'execute' phase events. If this statement property is true. then SQLText metric is updated. then the SQLText metric is updated. from two such statements. For example. then JDBC uses the value of the DMSStatementMetrics connection property. after the statement has been created. it may appear that changing sensor weight has no impact as statements are retrieved from the cache rather than created anew. It is disabled by default.Determining the Type of Metric to Be Generated Note: You can enable or disable the SQLText statement metric. If the sensor weight is greater than DMSConsole. JDBC checks the DMSConsole sensor weight when creating a Prepared or Callable statement and depending on the sensor weight at the time the statement is created. then the common 'execute' phase event will report a total execution time of 4 seconds and an average of 2 seconds. So. If one has an execution time of 1 second and the other an execution time of 3 seconds. then JDBC generates individual statement metrics. When individual statement metrics are generated. If enabled. all statements will use the single 'execute' phase event common to the connection. it will be possible to distinguish the execution statistics for the two separate statements. If one has an execution time of 1 second and the other an execution time of 3 seconds. ■ 31-2 Oracle Database JDBC Developer's Guide and Reference . If this flag is true. it will not be possible to distinguish the execution statistics for the two statements. JDBC checks the DMSConsole sensor weight.NORMAL. the metrics are generated. Determining the Type of Metric to Be Generated To determine whether to use consolidated or individual metrics. does not cause a statement to switch between consolidated and individual metrics.NORMAL. The default value of this connection property is false. If the 11.

Accessing DMS Metrics Using JMX JMX (Java Management Extensions) is a Java technology that supplies tools for managing and monitoring applications.com/technology/products/ias/toplink/doc/1013/m ain/_html/optimiz004.Accessing DMS Metrics Using JMX Whether or not the SQLText metric will be generated is independent of the use of the type of statement metrics used. You can easily access DMS metrics at run time using a management application that supports JMX.htm#BEEFGGBE JDBC DMS Metrics 31-3 . For more information about using JMX to access DMS data. individual statement metrics or consolidated statement metrics. and the JVM (Java Virtual Machine). devices. go to the following URL http://www. system objects. that is. service-oriented networks.oracle.

Accessing DMS Metrics Using JMX 31-4 Oracle Database JDBC Developer's Guide and Reference .

Part IX Appendixes This part consists of appendixes that discuss Java Database Connectivity (JDBC) reference information. "Troubleshooting" . and troubleshooting JDBC applications. tips for coding JDBC applications. "Reference Information" Appendix B. "JDBC Error Messages" Appendix D. JDBC error messages. "Coding Tips" Appendix C. Part IX contains the following appendixes: ■ ■ ■ ■ Appendix A.

.

sql.lang. Standard Java Types. including the following topics: ■ ■ ■ ■ Valid SQL-JDBC Data Type Mappings Supported SQL and PL/SQL Data Types Embedded SQL92 Syntax Oracle JDBC Notes and Limitations Valid SQL-JDBC Data Type Mappings Table 11–1 describes the default mappings between Java classes and SQL data types supported by Oracle JDBC drivers.lang.ORAData appears in italic.math.Integer java.A Reference Information This appendix contains detailed Java Database Connectivity (JDBC) reference information. Compare the contents of the JDBC Type Codes.sql.sql. use the getCHAR method.lang. and SQL Data Types columns in Table 11–1 with the contents of Table A–1. these can be generated by JPublisher.lang.lang. Note: For classes where oracle.sql.Time java.Long These SQL data types: CHAR. to materialize SQL CHAR data in an oracle. Table A–1 Valid SQL Data Type-Java Class Mappings Can be materialized as these Java types: oracle.sql. VARCHAR2.BigDecimal object.Byte java. For example.sql.Date java. To materialize it as a java.Short java. use the getBigDecimal method.String java.CHAR object. LONG Reference Information A-1 .Timestamp java. Oracle JDBC drivers will support these nondefault mappings.CHAR java. Table A–1 lists all the possible Java types to which a given SQL data type can be validly mapped.

sql.sql.Double java. short. int.lang.Time.sql.Timestamp java.Timestamp.TIMESTAMPTZ. long. double DATE oracle.Timestamp.sql.String. java. java.CLOB java. byte[] java.ROWID java.BFILE oracle.TIMESTAMPLTZ.Clob TIMESTAMP java.Date java.lang.sql.Date.lang.sql.sql.lang.sql.Blob CLOB oracle.Valid SQL-JDBC Data Type Mappings Table A–1 (Cont.sql.String NUMBER oracle.Date. oracle.sql.BLOB java. long. oracle. byte[] TIMESTAMP WITH TIME ZONE TIMESTAMP WITH LOCAL TIME ZONE A-2 Oracle Database JDBC Developer's Guide and Reference .sql.lang.CHAR oracle.Double java.sql. java.lang. oracle.math.DATE.Integer java.BigDecimal byte. short.sql.DATE java. byte[] java.sql. java.Time.sql.Time.sql.TIMESTAMP. int.sql. oracle.Timestamp.String BFILE BLOB oracle.lang.sql.sql.DATE. float. LONG RAW oracle.Byte java.sql. java.sql.Long java.Float java.sql. java. float.lang.lang.sql.lang.Float java.String.sql.NUMBER java.Date. oracle.) Valid SQL Data Type-Java Class Mappings These SQL data types: Can be materialized as these Java types: java.Time java.sql. java.math.String. oracle. double OPAQUE RAW.OPAQUE oracle.sql.DATE.sql.BigDecimal byte.sql.RAW byte[] ROWID oracle.lang.lang. java.Short java.lang. java.sql.

sql. Likewise.Array oracle. the value returned by a method with return type oracle.sql.SqlData oracle.Struct java.sql. Table A–2 describes Oracle JDBC driver support for SQL data types.sql.sql.sql.sql.ORAData Note: ■ ■ The type UROWID is not supported. The value passed to a parameter of type oracle.Supported SQL and PL/SQL Data Types Table A–1 (Cont.sql. The oracle. Table A–2 Support for SQL Data Types Supported by JDBC Drivers? yes yes yes yes yes no (see Note) no yes no (see Note) yes yes SQL Data Type BFILE BLOB CHAR CLOB DATE NCHAR NCHAR VARYING NUMBER NVARCHAR2 RAW REF Reference Information A-3 . Supported SQL and PL/SQL Data Types The tables in this section list SQL and PL/SQL data types.sql.) Valid SQL Data Type-Java Class Mappings These SQL data types: Object types Can be materialized as these Java types: oracle.ORAData Nested table types and VARRAY types oracle.REF java.ORAData Reference types oracle.Datum class is abstract.sql.sql.Ref oracle.sql.STRUCT java.Datum must be of the Java type corresponding to the underlying SQL type.Datum must be of the Java type corresponding to the underlying SQL type. and whether Oracle JDBC drivers support them.sql.ARRAY java.

then these types can be accessed.sql. There is no corresponding java. but if your application calls formOfUse(NCHAR). Table A–3 describes Oracle JDBC support for the ANSI-supported SQL data types.) Support for SQL Data Types SQL Data Type ROWID UROWID VARCHAR2 Supported by JDBC Drivers? yes no yes Note: The types NCHAR and NVARCHAR2 are supported indirectly. Table A–3 Support for ANSI-92 SQL Data Types ANSI-Supported SQL Data Type Supported by JDBC Drivers? CHARACTER DEC DECIMAL DOUBLE PRECISION FLOAT INT INTEGER NATIONAL CHARACTER NATIONAL CHARACTER VARYING NATIONAL CHAR NATIONAL CHAR VARYING NCHAR NCHAR VARYING NUMERIC REAL SMALLINT VARCHAR yes yes yes yes yes yes yes no no yes no yes no yes yes yes yes Table A–4 describes Oracle JDBC driver support for SQL User-Defined types.Supported SQL and PL/SQL Data Types Table A–2 (Cont. Table A–4 Support for SQL User-Defined Types Supported by JDBC Drivers? yes yes yes SQL User-Defined type OPAQUE Reference types Object types (JAVA_OBJECT) A-4 Oracle Database JDBC Developer's Guide and Reference .Types type.

Note that PL/SQL data types include these categories: ■ ■ ■ ■ ■ Scalar types Scalar character types.Supported SQL and PL/SQL Data Types Table A–4 (Cont.) Support for SQL User-Defined Types SQL User-Defined type Nested table types and VARRAY types Supported by JDBC Drivers? yes Table A–5 describes Oracle JDBC driver support for PL/SQL data types. which includes BOOLEAN and DATE data types Composite types Reference types Large object (LOB) types Support for PL/SQL Data Types Supported by JDBC Drivers? Table A–5 PL/SQL Data Type Scalar Types: BINARY INTEGER DEC DECIMAL DOUBLE PRECISION FLOAT INT INTEGER NATURAL NATURALn NUMBER NUMERIC PLS_INTEGER POSITIVE POSITIVEn REAL SIGNTYPE SMALLINT Scalar Character Types: CHAR CHARACTER LONG LONG RAW NCHAR NVARCHAR2 yes yes yes yes yes yes yes yes no yes yes yes yes no yes yes yes yes yes yes yes no (see Note) no (see Note) Reference Information A-5 .

which is the syntax that you specify between curly braces. POSITIVEn. NATURALn. The types NCHAR and NVARCHAR2 are supported indirectly. FLOAT. INTEGER. then these types can be accessed. The types DEC. The current support is basic. DOUBLE PRECISION. POSITIVE. There is no corresponding java. but if your application calls formOfUse(NCHAR).) Support for PL/SQL Data Types PL/SQL Data Type RAW ROWID STRING UROWID VARCHAR VARCHAR2 BOOLEAN DATE Composite Types: RECORD TABLE VARRAY Reference Types: REF CURSOR types object reference types LOB Types: BFILE BLOB CLOB NCLOB yes yes yes yes yes yes no no yes Supported by JDBC Drivers? yes yes yes no yes yes yes yes Note: ■ The types NATURAL.5" on page 19-3 for details. NVARCHAR2. This section describes the support offered by the drivers for the following SQL92 constructs: ■ ■ Time and Date Literals Scalar Functions A-6 Oracle Database JDBC Developer's Guide and Reference . REAL. ■ ■ Embedded SQL92 Syntax Oracle JDBC drivers support some embedded SQL92 syntax. and SIGNTYPE are subtypes of BINARY INTEGER. Refer to "NCHAR. NUMERIC. NCLOB and the defaultNChar Property in JDK 1.Types type.sql.Embedded SQL92 Syntax Table A–5 (Cont. INT. DECIMAL. and SMALLINT are subtypes of NUMBER.

// Select the ename column from the emp table where the hiredate is Jan-23-1982 ResultSet rset = stmt. // Iterate through the result and print the employee names while (rset.out. If you want the driver to use regular Oracle SQL syntax.setUser("scott"). Time and Date Literals Databases differ in the syntax they use for date. OracleDataSource ods = new OracleDataSource().setEscapeProcessing(false). time. // Create a Statement Statement stmt = conn. time.executeQuery ("SELECT ename FROM emp WHERE hiredate = {d '1982-01-23'}"). and timestamp literals in SQL statements.getConnection(). and timestamp literals. For example: {d '1995-10-22'} The JDBC drivers will replace this escape clause with the equivalent Oracle representation: "22 OCT 1995". month.next ()) System. then use this statement: stmt.createStatement (). Disabling Escape Processing Escape processing for SQL92 syntax is enabled by default. these sections also describe possible workarounds.getString (1)). The following code snippet contains an example of using a date literal in a SQL statement. which is more efficient than SQL92 syntax and escape processing. Date Literals The JDBC drivers support date literals in SQL statements written in the format: {d 'yyyy-mm-dd'} Where yyyy-mm-dd represents the year.setPassword("tiger"). ods. which results in the JDBC driver performing escape substitution before sending the SQL code to the database.Embedded SQL92 Syntax ■ ■ ■ LIKE Escape Characters Outer Joins Function Call Syntax Where driver support is limited. ods.println (rset. // Connect to the database // You can put a database name after the @ sign in the connection URL. JDBC supports dates and times written only in a specific format. Time Literals The JDBC drivers support time literals in SQL statements written in the format: Reference Information A-7 . ods. Connection conn = ods.setURL("jdbc:oracle:oci:@"). and day. This section describes the formats you must use for date.

and seconds. A-8 Oracle Database JDBC Developer's Guide and Reference .) is optional and can be omitted. Timestamp Literals The JDBC drivers support timestamp literals in SQL statements written in the format: {ts 'yyyy-mm-dd hh:mm:ss. NOV 01 1997 13:22:45. minutes. assuming the server is using a 24-hour clock.DATE to java. month.. hh:mm:ss represents the hours. day. This code snippet contains an example of using a time literal in a SQL statement. ResultSet rset = stmt. in Oracle format..sql.executeQuery ("SELECT ename FROM emp WHERE hiredate = {t '12:00:00'}"). hours. TIMESTAMP support was included and 9i JDBC drivers started mapping oracle.0.sql.'} where yyyy-mm-dd hh:mm:ss. Oracle Database 11..executeQuery ("SELECT ename FROM emp WHERE hiredate = {ts '1982-01-23 12:00:00'}").1 introduces a new flag mapDateToTimestamp.f.sql.Date. To overcome this problem. This code snippet contains an example of using a timestamp literal in a SQL statement. If the time is specified as: {t '14:20:50'} Then the equivalent Oracle representation would be "14:20:50". This mapping was incorrect as it truncated the time component of Oracle DATE data.f.sql. The fractional seconds portion (. Oracle Database 8i and earlier versions of JDBC drivers mapped oracle. then you can get it by setting the value of mapDateToTimestamp flag to false.DATE to java. So.DATE to java. minutes. but Oracle DATE data used to have a time component as an extension to the SQL standard..sql.DATE to java. If you still want the incorrect but 10g compatible oracle. Starting with Oracle Database 9.1.sql.Date mapping. For example: {ts '1997-11-01 13:22:45'} represents..Timestamp.sql.sql. For example: {t '05:10:45'} The JDBC drivers will replace this escape clause with the equivalent Oracle representation: "05:10:45"..Embedded SQL92 Syntax {t 'hh:mm:ss'} where. The default value of this flag is true.f. Mapping SQL DATE Data type to Java Oracle Database 8i and earlier versions did not support TIMESTAMP data. represents the year. ResultSet rset = stmt. retaining the time information. and seconds.Timestamp to preserve the time component. which means that by default the drivers will correctly map oracle.

out. For example. CURDATE. the function keyword.sql.2 had introduced a flag. HOUR. ASCII. For example.DatabaseMetadata interface: ■ getNumericFunctions() Returns a comma-delimited list of math functions supported by the driver. To find out which functions the drivers support.getString (1)). DAYOFYEAR. ■ getSystemFunctions() Returns a comma-delimited list of system functions supported by the driver.DATE to java. Reference Information A-9 . users could retain the time component of the Oracle DATE data by setting the value of this flag to true. Note: Oracle JDBC drivers support fn. // Iterate through the result and print the employee numbers while (rset. ABS. You use % to match zero or more characters and _ to match exactly one character. COS.jdbc. The default value of this flag was false. SQRT. ■ getTimeDateFunctions() Returns a comma-delimited list of time and date functions supported by the driver. LOCATE. DATABASE.OracleDatabaseMetaData class and the standard Java java.Date data.Date mapping.sql. For example. LIKE Escape Characters The characters % and _ have special meaning in SQL LIKE clauses. Scalar Functions Oracle JDBC drivers do not support all scalar functions. For example.println (rset. then you identify it in the SQL statement as: Statement stmt = conn. use the following methods supported by the Oracle-specific oracle.sql. // Select the empno column from the emp table where the ename starts with '_' ResultSet rset = stmt. then you precede them with a special escape character. which is no longer supported. which allowed the mapping of Oracle DATE data to java. This flag is deprecated in 11g because it controlled Oracle Database 8i compatibility. ■ getStringFunctions() Returns a comma-delimited list of string functions supported by the driver.next ()) System.sql. USER. But. if you want to use ampersand (&) as the escape character.executeQuery ("SELECT empno FROM emp WHERE ename LIKE '&_%' {ESCAPE '&'}"). For example. Oracle Database 9. If you want to interpret these characters literally in strings.Embedded SQL92 Syntax Note: To overcome the problem of oracle.createStatement (). V8Compatible.

deptno = b. In the program.executeQuery ("SELECT ename. time literals.) } Function calls: { ? = call procedure_name (argument1. then you must enter it twice..executeQuery ("SELECT ename. that is. \\.OracleSql class parse() method performs the conversions. argument2. ResultSet rset = stmt. show ("{? = call bar (?.OracleDriver driver = new oracle. Function Call Syntax Oracle JDBC drivers support the following procedure and function call syntax: Procedure calls: { call procedure_name (argument1. ResultSet rset = stmt.executeQuery("SELECT empno FROM emp WHERE ename LIKE '\\_%' {escape '\\'}").. For example: ResultSet rset = stmt. The following program prints the comparable SQL syntax for SQL92 statements for function calls. the oracle. ?)}"). ?)}"). show ("{d '1998-10-22'}").jdbc..OracleDriver(). dname FROM {OJ dept LEFT OUTER JOIN emp ON dept. Outer Joins Oracle JDBC drivers do not support the outer join syntax. show ("{ts '1998-10-22 16:22:34'}").deptno(+) ORDER BY ename").. public class Foo { static oracle. dname FROM emp b.deptno} ORDER BY ename").jdbc. and timestamp literals. } A-10 Oracle Database JDBC Developer's Guide and Reference . Use Oracle SQL syntax: Statement stmt = conn.Embedded SQL92 Syntax Note: If you want to use the backslash character (\) as an escape character.jdbc. dept a WHERE a.) } SQL92 to SQL Syntax Example You can write a simple program to translate SQL92 syntax to standard SQL syntax. date literals.. argument2..createStatement ().createStatement ().deptno = emp. public static void main (String args[]) throws Exception { show ("{call foo(?. show ("{t '16:22:34'}"). The workaround is to use Oracle outer join syntax: Instead of: Statement stmt = conn.

'HH24:MI:SS') {ts '1998-10-22 16:22:34'} => TO_TIMESTAMP ('1998-10-22 16:22:34'. :2).processSqlEscapes(s)). because there is no convenient way to map them to Oracle constructs. END. END. 'YYYY-MM-DD') {t '16:22:34'} => TO_DATE ('16:22:34'. See Also: "Accessing PL/SQL Index-by Tables" on page 4-5 Reference Information A-11 . ?)} => BEGIN foo(:1. Use Oracle SQL syntax with + instead. BOOLEAN. This section covers the following topics: ■ ■ ■ ■ ■ ■ ■ CursorName SQL92 Outer Join Escapes PL/SQL TABLE.Oracle JDBC Notes and Limitations public static void show (String s) throws Exception { System. 'YYYY-MM-DD HH24:MI:SS. or table with non-scalar element types.out.println (s + " => " + driver. } } The following code is the output that prints the comparable SQL syntax. See Also: "Oracle ROWID Type" on page 4-13 for more information about how to use and manipulate ROWIDs. :3). Oracle recommends using ROWID instead.FF') Oracle JDBC Notes and Limitations The following limitations exist in the Oracle JDBC implementation. Oracle JDBC drivers support PL/SQL index-by table of scalar element types. and RECORD Types It is not feasible for Oracle JDBC drivers to support calling arguments or return values of the PL/SQL RECORD. {call foo(?. See Also: "Embedded SQL92 Syntax" on page A-6 PL/SQL TABLE. BOOLEAN. {d '1998-10-22'} => TO_DATE ('1998-10-22'. SQL92 Outer Join Escapes Oracle JDBC drivers do not support SQL92 outer join escapes. However. but all of them are either insignificant or have easy workarounds. {? = call bar (?. BOOLEAN. and RECORD Types IEEE 754 Floating Point Compliance Catalog Arguments to DatabaseMetaData Calls SQLWarning Class Binding Named Parameters CursorName Oracle JDBC drivers do not support the get getCursorName and setCursorName methods. ?)} => BEGIN :1 := bar (:2.

See Also: "DatabaseMetaData TABLE_REMARKS Reporting" on page 23-19 for information about how Oracle JDBC drivers treat the catalog argument. BOOLEAN. but it does have packages. and plus infinity exactly. SQLWarning Class The java. Catalog Arguments to DatabaseMetaData Calls Certain DatabaseMetaData methods define a catalog parameter.SQLWarning class provides information about a database access warning. accepts a BOOLEAN argument from the original procedure and passes it as a CHAR or NUMBER to JDBC.prepareStatement A-12 Oracle Database JDBC Developer's Guide and Reference . This parameter is one of the selection criteria for the method. It represents zero. the named variable EmpId would be bound to the integer 314159. See Also: "Boolean Parameters in PL/SQL Stored Procedures" on page D-2 for an example of a workaround for BOOLEAN. See Also: "Processing SQL Exceptions" on page 2-15 Binding Named Parameters Binding by name is not supported when using the setXXX methods. to wrap a stored procedure that uses PL/SQL records. such as CHAR and NUMBER. break the data into components or perhaps use Oracle collection types. but the SQLWarning instance is created on the client. for an output parameter. or non-scalar table types. Therefore. IEEE 754 Floating Point Compliance The arithmetic for the Oracle NUMBER type does not comply with the IEEE 754 standard for floating-point arithmetic. create a stored procedure that handles a record in its individual components. It represents every positive number between 10-30 and (1 – 10-38) * 10126 to full 38-digit precision. to wrap a stored procedure that uses PL/SQL boolean. Warnings are silently chained to the object whose method caused it to be reported.sql. Oracle JDBC drivers generally do not support SQLWarning. As an exception to this. In the following statement. To wrap a stored procedure that uses PL/SQL tables. it represents a negative number of the same absolute value. or in a structured object type. minus infinity. Oracle stores numbers in a format compatible with decimal arithmetic and guarantees 38 decimal digits of precision. PreparedStatement p = conn. Oracle does not have multiple catalogs. Similarly. Under certain circumstances. create a stored procedure that takes a character or number from JDBC and passes it to the original procedure as BOOLEAN or.Oracle JDBC Notes and Limitations As a workaround to PL/SQL RECORD. create container procedures that handle the data as types supported by JDBC. scrollable result set operations do generate SQL warnings. there can be small disagreements between the results of computations performed by Oracle and the same computations performed by Java. not in the database. For example. previous versions of Oracle JDBC drivers have allowed binding statement variables by name when using the setXXX methods. Warnings typically contain a description of the warning and a code that identifies the warning. For each positive number it represents.

or otherwise modifies the stream. p. p. bind by name is supported using the setXXXAtName methods. See Also: "Interface oracle.0..setDate(1. changing the bound value before calling the execute method could change the bound value. the second execute will return the correct value. d. Starting from Oracle Database 10g.Oracle JDBC Notes and Limitations ("SELECT name FROM emp WHERE id = :EmpId"). Oracle JDBC drivers did not retain bound values from one call of execute to the next as specified in JDBC 1. Starting from Oracle Database 10g JDBC drivers. For example. The JDBC drivers can throw a SQLException or produce unexpected results.execute(). d). Unless the application code resets. and Oracle does not support it..jdbc.executeUpdate(). This code snippet inserts Date(0) in the database instead of Date(1181676033917L) because the bound values are not copied by JDBC driver implementation for performance reasons. If the retained bound value is a stream. 425260)..setTime(0). repositions. Reference Information A-13 . p. So. then Oracle JDBC drivers will not reset the stream. 314159). Retaining Bound Values Before Oracle9i Database.OraclePreparedStatement" on page 4-22 The bound values are not copied by the drivers until you call the execute method. Date d = new Date(1181676033917L).setInt(1. "SALES").execute(). p.setInt(1.prepareStatement ("SELECT name FROM emp WHERE id = ? AND dept = ?"). retaining the binding of the second argument to the string SALES. 314159).jdbc. consider the folllowing code snippet: PreparedStatement p. All releases after Oracle9i Database have retained bound values. For example: PreparedStatement p = conn. the subsequent calls to execute will send NULL as the value of the argument. ResultSet r2 = p.. This capability to bind by name using the setXXX methods is not part of the JDBC specification. Previously.OracleCallableStatement" on page 4-22 and "Interface oracle. ResultSet r1 = p..setInt(1. p.. a SQLException would be thrown by the second execute call because no value was bound to the second argument. p. .setString(2.

Oracle JDBC Notes and Limitations A-14 Oracle Database JDBC Developer's Guide and Reference .

B Coding Tips This appendix describes methods to optimize a Java Database Connectivity (JDBC) application or applet. for example. you are repeating the same statement with different bind variables. and are highly optimized for. By default. If multiple threads must share a connection. Avoid allowing multiple threads to access a connection simultaneously. is both necessary and encouraged. Controlled serial access to a connection. However. It includes the following topics: ■ ■ ■ JDBC and Multithreading Performance Optimization Transaction Isolation Levels and Access Modes JDBC and Multithreading Oracle JDBC drivers provide full support for. However.sql.Conection or oracle. applications that use Java multithreading. Coding Tips B-1 . use a disciplined begin-using/end-using protocol. you can disable auto-commit mode with the setAutoCommit method of the connection object. Performance Optimization You can significantly enhance the performance of your JDBC programs by using any of these features: ■ ■ ■ ■ ■ Disabling Auto-Commit Mode Standard Fetch Size and Oracle Row Prefetching Standard and Oracle Update Batching Statement Caching Mapping Between Built-in SQL and Java Types Disabling Auto-Commit Mode Auto-commit mode indicates to the database whether to issue an automatic COMMIT operation after every SQL operation. Oracle strongly discourages sharing a database connection among multiple threads. either java. new connection objects are in auto-commit mode. Being in auto-commit mode can be expensive in terms of time and processing effort if.OracleConnection. such as that provided by connection caching.jdbc.

. You can set a value in a connection object that affects each statement produced through that connection. The default value in a connection object is 10. the statement completes when the last row of the Result Set has been retrieved or when the Result Set has been closed.setUser("scott"). Similarly.Performance Optimization In auto-commit mode. then the Oracle connection row-prefetch value is used by default. a result set uses the value for the statement object that produced it. // Create a Statement Statement stmt = conn. Prefetching data into the client reduces the number of round-trips to the server. See Also: "Fetch Size" on page 17-15 Standard and Oracle Update Batching Oracle JDBC drivers allow you to accumulate INSERT. and with more flexibility. Here. whichever comes first. If you disable auto-commit mode with a setAutoCommit(false) call..0 fetch size. and you can override that value in any particular statement object. Standard Fetch Size and Oracle Row Prefetching Oracle JDBC connection and statement objects allow you to specify the number of rows to prefetch into the client with each trip to the database while a result set is being populated during a query. conn represents the Connection object. By default. and stmt represents the Statement object. a single statement can return multiple results as well as output parameter values. This feature reduces round-trips to the server. JDBC 2. ods. . In the case of statements returning a ResultSet object. ods. Connection conn = ods. In the example.setPassword("tiger").getConnection(). and UPDATE operations of prepared statements at the client and send them to the server in batches.setURL("jdbc:oracle:oci:@"). B-2 Oracle Database JDBC Developer's Guide and Reference . this example shows how to disable auto-commit. the COMMIT occurs when all results and output parameter values have been retrieved. ods. or standard update batching.setAutoCommit (false). OracleDataSource ods = new OracleDataSource(). DELETE. Example The following example illustrates loading the driver and connecting to the database. // Connect to the database // You can put a database host name after the @ sign in the connection URL. then you must manually commit or roll back groups of operations using the commit or rollback method of the connection object. the COMMIT operation occurs either when the statement completes or the next execute occurs. // It's faster when auto commit is off conn. both for statement objects (affecting subsequent queries) and for result set objects (affecting row refetches). which typically processes a batch implicitly once a pre-set batch value is reached.createStatement ().0 enables you to specify the number of rows to fetch with each trip. You can either use Oracle update batching. In more complex cases. If you do not set the JDBC 2. where the batch is processed explicitly. Because new connections are in auto-commit mode by default.

CHAR oracle. a statement object is cached when you call the close method.sql.CHAR oracle.sql. multiple caches can exist if you enable Statement caching for multiple physical connections.sql.CLOB oracle. varray.sql.sql. which have user-defined names.NUMBER oracle.ResultSet oracle.NUMBER oracle.sql. such as in a loop or in a method that is called repeatedly.DATE oracle. Table B–1 is a subset of the information presented in Table 11–1.Java Classes Representing SQL Data Types oracle.sql. In JDBC programs that access data of built-in SQL types.Performance Optimization See Also: "Update Batching" on page 23-1 Statement Caching Statement caching improves performance by caching executable statements that are used repeatedly. If you try to enable Statement caching on a logical connection held by a connection cache. See Also: Chapter 20.ARRAY oracle.* representation. the logical connections benefit from the Statement caching that is enabled on the underlying physical connection.NUMBER oracle.BFILE oracle.sql.RAW java.sql.BLOB oracle.sql.RAW oracle.ARRAY SQL Data Type CHAR VARCHAR2 DATE DECIMAL DOUBLE PRECISION FLOAT INTEGER REAL RAW LONG RAW REF CURSOR CLOB LOCATOR BLOB LOCATOR BFILE nested table varray Coding Tips B-3 . because the program context determines the Java type to which a SQL datum will be converted.sql. such as NUMBER. When you enable Statement caching. Table B–1 Mapping of SQL Data Types to Java Classes that Represent SQL Data Types ORACLE Mapping . as opposed to the Oracle objects.sql. Applications use the statement cache to cache statements associated with a particular physical connection.sql.NUMBER oracle. and CHAR. all type conversions are unambiguous. "Statement and Result Set Caching" Mapping Between Built-in SQL and Java Types The SQL built-in types are those types with system-defined names.sql.NUMBER oracle.sql. and nested table types.sql. then this will throw an exception. The table lists the one-to-one type-mapping of the SQL database type to its Java oracle. Because each physical connection has its own cache.sql. When you enable Statement caching on a connection cache.

The most efficient way to access numeric data is as primitive Java types like int.Transaction Isolation Levels and Access Modes Table B–1 (Cont.lang. ■ B-4 Oracle Database JDBC Developer's Guide and Reference . the Oracle server supports only the TRANSACTION_READ_COMMITTED and TRANSACTION_SERIALIZABLE transaction isolation levels.SQLRef. It is information-preserving. Use the following methods of the oracle. setTransactionIsolation: Changes the transaction isolation level. It stores the usual representations of SQL data as byte arrays.Java Classes Representing SQL Data Types If there is no entry for the object value in the type map: ■ oracle. All character data is converted to the UCS2 character set of Java.OracleConnection interface to get and set the level: ■ getTransactionIsolation: Gets this connection's current transaction isolation level.sql. and double. For transactions.sql. or vice versa. float. the range of values of these types do not exactly match the range of values of the SQL NUMBER data type. this can cause a loss of information when two or more characters in the database character set map to a single UCS2 character. but not by Oracle JDBC drivers. there may be some loss of information. typically by extending oracle. This Oracle mapping is the most efficient type-mapping for applications that "shovel" data from SQL to Java. As a result. It avoids re-formatting the data.STRUCT customized Java class If there is an entry for the object value in the type map: ■ REF to SQL object type class that implements oracle. Transaction Isolation Levels and Access Modes Read-only connections are supported by the Oracle server. using one of the TRANSACTION_* values. some characters do map to surrogate pairs.String. long. In worst case.sql. The most efficient way to access character data is as java. However. In Oracle Database 11g.) Mapping of SQL Data Types to Java Classes that Represent SQL Data SQL Data Type SQL object value ORACLE Mapping .REF This mapping provides the most efficient conversion between SQL and Java data representations. However.jdbc. all characters in the character set map to the characters in the UCS2 character set. The default is TRANSACTION_READ_COMMITTED.

See Also: "Processing SQL Exceptions" on page 2-15 General Structure of JDBC Error Messages The general JDBC error message structure allows run-time information to be appended to the end of a message. then lists general JDBC error messages and TTC error messages that Oracle JDBC drivers can return. General JDBC Messages This section lists general JDBC error messages.C JDBC Error Messages This appendix briefly discusses the general structure of Java Database Connectivity (JDBC) error messages. following a colon. and then alphabetically. as follows: <error_message>:<extra_info> For example. the user can find the same information in a stack trace. and then in alphabetic order in the following subsections: ■ ■ JDBC Messages Sorted by ORA Number JDBC Messages Sorted in Alphabetic Order JDBC Messages Sorted by ORA Number The following table lists the JDBC error messages sorted by the ORA number: JDBC Error Messages C-1 . In some cases. a "closed statement" error might be displayed as follows: Closed Statement:next This indicates that the exception was thrown during a call to the next method (of a result set object). first sorted by the ORA number. The appendix is organized as follows: ■ ■ ■ ■ General Structure of JDBC Error Messages General JDBC Messages Native XA Messages TTC Messages Each of the message lists is first sorted by ORA number.

next was not called Statement was cancelled Statement timed out Cursor already initialized Invalid cursor Can only describe a query Invalid row prefetch Missing defines Missing defines at index Unsupported feature No data read Error in defines.General JDBC Messages ORA Number ORA-17001 ORA-17002 ORA-17003 ORA-17004 ORA-17005 ORA-17006 ORA-17007 ORA-17008 ORA-17009 ORA-17010 ORA-17011 ORA-17012 ORA-17014 ORA-17015 ORA-17016 ORA-17017 ORA-17018 ORA-17019 ORA-17020 ORA-17021 ORA-17022 ORA-17023 ORA-17024 ORA-17025 ORA-17026 ORA-17027 ORA-17028 ORA-17029 ORA-17030 ORA-17031 ORA-17032 ORA-17033 ORA-17034 ORA-17035 ORA-17036 ORA-17037 ORA-17038 Message Internal Error Io exception Invalid column index Invalid column type Unsupported column type Invalid column name Invalid dynamic column Closed Connection Closed Statement Closed ResultSet Exhausted ResultSet Parameter Type Conflict ResultSet.isNull () Numeric Overflow Stream has already been closed Can not do new defines until the current ResultSet is closed setReadOnly: Read-only connections not supported READ_COMMITTED and SERIALIZABLE are the only valid transaction levels setAutoClose: Only support auto close mode on cannot set row prefetch to zero Malformed SQL92 string at position Non supported SQL92 token at position Character Set Not Supported !! exception in OracleNumber Fail to convert between UTF8 and UCS2 Byte array not long enough C-2 Oracle Database JDBC Developer's Guide and Reference .

General JDBC Messages ORA Number ORA-17039 ORA-17040 ORA-17041 ORA-17042 ORA-17043 ORA-17044 ORA-17045 ORA-17046 ORA-17047 ORA-17048 ORA-17049 ORA-17050 ORA-17051 ORA-17052 ORA-17053 ORA-17054 ORA-17055 ORA-17056 ORA-17057 ORA-17058 ORA-17059 ORA-17060 ORA-17061 ORA-17062 ORA-17063 ORA-17064 ORA-17065 ORA-17066 ORA-17067 ORA-17068 ORA-17069 ORA-17070 ORA-17071 ORA-17072 ORA-17073 ORA-17074 ORA-17075 Message Char array not long enough Sub Protocol must be specified in connection URL Missing IN or OUT parameter at index: Invalid Batch Value Invalid stream maximum size Internal error: Data array not allocated Internal error: Attempt to access bind values beyond the batch value Internal error: Invalid index for data access Error in Type Descriptor parse Undefined type Inconsistent java and sql object types no such element in vector This API cannot be be used for non-UDT types This ref is not valid The size is not valid The LOB locator is not valid Invalid character encountered in Non supported character set (add orai18n.jar in your classpath environment variable) Closed LOB Internal error: Invalid NLS Conversion ratio Fail to convert to internal representation Fail to construct descriptor Missing descriptor Ref c