Oracle Database JDBC Developer Guide and Reference
Oracle Database JDBC Developer Guide and Reference
Oracle Database JDBC Developer Guide and Reference
December 2003
This book describes how to use the Oracle JDBC drivers to
develop powerful Java database applications.
Oracle Database JDBC Developer's Guide and Reference, 10g Release 1 (10.1)
Contributor: Kuassi Mensah, Magdi Morsi, Ron Peterson, Ekkehard Rohwedder, Ashok Shivarudraiah,
Catherine Wong, Ed Shirk, Tong Zhou, Longxing Deng, Jean de Lavarene, Rosie Chen, Sunil Kunisetty, Joyce
Yang, Mehul Bastawala, Luxi Chidambaran, Srinath Krishnaswamy, Rajkumar Irudayaraj, Scott Urman,
Jerry Schwarz, Steve Ding, Soulaiman Htite, Douglas Surber, Anthony Lai, Paul Lo, Prabha Krishna, Ellen
Barnes, Susan Kraft, Sheryl Maring, Angie Long
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 Corporation, 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 is a registered trademark 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.
1 Overview
What is JDBC?........................................................................................................................................... 1-1
Overview of the Oracle JDBC Drivers ................................................................................................. 1-2
Common Features of Oracle JDBC Drivers .................................................................................... 1-3
JDBC Thin Driver ............................................................................................................................... 1-3
JDBC OCI Driver ................................................................................................................................ 1-3
JDBC Server-Side Thin Driver.......................................................................................................... 1-4
About Permission for the Server-Side Thin Driver................................................................ 1-4
JDBC Server-Side Internal Driver .................................................................................................... 1-5
Choosing the Appropriate Driver.................................................................................................... 1-5
Overview of Application and Applet Functionality ......................................................................... 1-6
Applet Basics....................................................................................................................................... 1-6
Applets and Security .................................................................................................................. 1-6
Applets and Firewalls ................................................................................................................ 1-6
Packaging and Deploying Applets........................................................................................... 1-6
Oracle Extensions ............................................................................................................................... 1-7
Server-Side Basics .................................................................................................................................... 1-7
Session and Transaction Context ..................................................................................................... 1-7
Connecting to the Database .............................................................................................................. 1-7
Environments and Support .................................................................................................................... 1-7
Supported JDK and JDBC Versions................................................................................................. 1-7
Backward Compatibility ............................................................................................................ 1-8
Forward Compatibility .............................................................................................................. 1-8
JNI and Java Environments .............................................................................................................. 1-8
JDBC and IDEs.................................................................................................................................... 1-8
iii
Changes At This Release ........................................................................................................................ 1-8
New Features ...................................................................................................................................... 1-8
Deprecated Features ....................................................................................................................... 1-10
Desupported Features .................................................................................................................... 1-11
Interface Changes............................................................................................................................ 1-11
2 Getting Started
Compatibilities for Oracle JDBC Drivers............................................................................................ 2-1
Backward Compatibility ................................................................................................................... 2-1
Forward Compatibility...................................................................................................................... 2-2
Verifying a JDBC Client Installation.................................................................................................... 2-2
Check Installed Directories and Files .............................................................................................. 2-2
Check the Environment Variables ................................................................................................... 2-3
JDBC OCI Driver......................................................................................................................... 2-4
JDBC Thin Driver ........................................................................................................................ 2-4
Make Sure You Can Compile and Run Java .................................................................................. 2-4
Determine the Version of the JDBC Driver .................................................................................... 2-4
Testing JDBC and the Database Connection: JdbcCheckup ........................................................ 2-5
4 Basic Features
First Steps in JDBC .................................................................................................................................. 4-1
Importing Packages ........................................................................................................................... 4-2
Opening a Connection to a Database .............................................................................................. 4-2
Specifying a Database URL, User Name, and Password ...................................................... 4-2
Specifying a Database URL That Includes User Name and Password ............................... 4-3
Supported Connection Properties ............................................................................................ 4-3
Using Roles for Sys Logon......................................................................................................... 4-5
Configuring To Permit Use of sysdba .............................................................................. 4-6
Bequeath Connection and Sys Logon ...................................................................................... 4-6
iv
Remote Connection..................................................................................................................... 4-7
Properties for Oracle Performance Extensions ....................................................................... 4-8
Example................................................................................................................................. 4-8
Creating a Statement Object ............................................................................................................. 4-9
Executing a Query and Returning a Result Set Object ................................................................. 4-9
Processing the Result Set................................................................................................................... 4-9
Closing the Result Set and Statement Objects................................................................................ 4-9
Making Changes to the Database ................................................................................................. 4-10
Committing Changes...................................................................................................................... 4-11
Closing the Connection .................................................................................................................. 4-11
Sample: Connecting, Querying, and Processing the Results........................................................ 4-12
Datatype Mappings............................................................................................................................... 4-12
Table of Mappings .......................................................................................................................... 4-12
Notes Regarding Mappings........................................................................................................... 4-14
Regarding User-Defined Types ............................................................................................. 4-14
Regarding NUMBER Types ................................................................................................... 4-15
Java Streams in JDBC ........................................................................................................................... 4-15
Streaming LONG or LONG RAW Columns ............................................................................... 4-15
LONG RAW Data Conversions ............................................................................................. 4-16
LONG Data Conversions ........................................................................................................ 4-16
Streaming Example for LONG RAW Data........................................................................... 4-17
Getting a LONG RAW Data Column with getBinaryStream() .................................. 4-17
Getting a LONG RAW Data Column with getBytes()................................................. 4-18
Avoiding Streaming for LONG or LONG RAW................................................................. 4-18
Streaming CHAR, VARCHAR, or RAW Columns .................................................................... 4-19
Data Streaming and Multiple Columns....................................................................................... 4-19
Streaming Example with Multiple Columns ....................................................................... 4-20
Bypassing Streaming Data Columns..................................................................................... 4-20
Streaming LOBs and External Files .............................................................................................. 4-21
Streaming BLOBs and CLOBs................................................................................................ 4-21
Streaming BFILEs..................................................................................................................... 4-21
Closing a Stream.............................................................................................................................. 4-21
Notes and Precautions on Streams ............................................................................................... 4-22
Streaming Data Precautions ................................................................................................... 4-22
Using Streams to Avoid Limits on setBytes() and setString() ........................................... 4-23
Streaming and Row Prefetching ............................................................................................ 4-23
Stored Procedure Calls in JDBC Programs....................................................................................... 4-24
PL/SQL Stored Procedures ........................................................................................................... 4-24
Java Stored Procedures................................................................................................................... 4-25
Processing SQL Exceptions ................................................................................................................. 4-25
Retrieving Error Information ........................................................................................................ 4-25
Printing the Stack Trace ................................................................................................................. 4-26
v
Standard Feature Support................................................................................................................. 5-2
Extended Feature Support ................................................................................................................ 5-2
Standard versus Oracle Performance Enhancement APIs ........................................................... 5-2
Migration from JDK 1.1.x .................................................................................................................. 5-3
JDBC 3.0 Support: JDK 1.4 and Previous Releases............................................................................ 5-3
Overview of Supported JDBC 3.0 Features ......................................................................................... 5-4
Unsupported JDBC 3.0 Features ...................................................................................................... 5-4
Transaction Savepoints............................................................................................................................ 5-4
Creating a Savepoint.......................................................................................................................... 5-4
Rolling back to a Savepoint .............................................................................................................. 5-5
Releasing a Savepoint ........................................................................................................................ 5-5
Checking Savepoint Support............................................................................................................ 5-5
Savepoint Notes.................................................................................................................................. 5-5
Savepoint Interfaces........................................................................................................................... 5-5
Pre-JDK1.4 Savepoint Support ......................................................................................................... 5-6
JDBC 3.0 LOB Interface Methods.......................................................................................................... 5-7
6 Statement Caching
About Statement Caching....................................................................................................................... 6-1
Basics of Statement Caching ............................................................................................................. 6-1
Implicit Statement Caching .............................................................................................................. 6-2
Explicit Statement Caching............................................................................................................... 6-2
Using Statement Caching ....................................................................................................................... 6-3
Enabling and Disabling Statement Caching................................................................................... 6-4
Enabling and Disabling Implicit Statement Caching............................................................. 6-4
Enabling and Disabling Explicit Statement Caching ............................................................. 6-4
Checking for Statement Creation Status ......................................................................................... 6-5
Physically Closing a Cached Statement .......................................................................................... 6-5
Using Implicit Statement Caching ................................................................................................... 6-5
Allocating a Statement for Implicit Caching........................................................................... 6-6
Disabling Implicit Statement Caching for a Particular Statement ....................................... 6-6
Implicitly Caching a Statement................................................................................................. 6-6
Retrieving an Implicitly Cached Statement ............................................................................ 6-6
Using Explicit Statement Caching ................................................................................................... 6-7
Allocating a Statement for Explicit Caching ........................................................................... 6-7
Explicitly Caching a Statement ................................................................................................. 6-7
Retrieving an Explicitly Cached Statement............................................................................. 6-8
vi
Connection Attributes ............................................................................................................................. 7-5
Getting Connections .......................................................................................................................... 7-6
Attribute Matching Rules .......................................................................................................... 7-6
Setting Connection Attributes .......................................................................................................... 7-6
Checking a Returned Connection's Attributes .............................................................................. 7-7
Connection Attribute Example ........................................................................................................ 7-7
Connection Cache Properties ................................................................................................................. 7-8
Limit Properties.................................................................................................................................. 7-8
InitialLimit ................................................................................................................................... 7-8
MaxLimit ...................................................................................................................................... 7-8
MaxStatementsLimit................................................................................................................... 7-8
MinLimit....................................................................................................................................... 7-8
Timeout Properties............................................................................................................................. 7-8
InactivityTimeout........................................................................................................................ 7-8
TimeToLiveTimeout ................................................................................................................... 7-9
AbandonedConnectionTimeout ............................................................................................... 7-9
PropertyCheckInterval............................................................................................................... 7-9
Other Properties ................................................................................................................................. 7-9
AttributeWeights......................................................................................................................... 7-9
ClosestConnectionMatch ........................................................................................................... 7-9
ConnectionWaitTimeout............................................................................................................ 7-9
LowerThresholdLimit ............................................................................................................. 7-10
ValidateConnection ................................................................................................................. 7-10
Connection Property Example ...................................................................................................... 7-10
Connection Cache Manager API ........................................................................................................ 7-10
createCache ...................................................................................................................................... 7-11
removeCache ................................................................................................................................... 7-11
reinitializeCache .............................................................................................................................. 7-11
existsCache ....................................................................................................................................... 7-12
enableCache ..................................................................................................................................... 7-12
disableCache .................................................................................................................................... 7-12
refreshCache .................................................................................................................................... 7-12
purgeCache ...................................................................................................................................... 7-12
getCacheProperties ......................................................................................................................... 7-12
getCacheNameList .......................................................................................................................... 7-13
getNumberOfAvailableConnections............................................................................................ 7-13
getNumberOfActiveConnections ................................................................................................. 7-13
setConnectionPoolDataSource ...................................................................................................... 7-13
Example Of ConnectionCacheManager Use ............................................................................... 7-13
Advanced Topics.................................................................................................................................... 7-14
Attribute Weights And Connection Matching............................................................................ 7-14
ClosestConnectionMatch ........................................................................................................ 7-14
AttributeWeights...................................................................................................................... 7-14
Connection Cache Callbacks ......................................................................................................... 7-15
vii
8 Fast Connection Failover
Introduction............................................................................................................................................... 8-1
What Can Fast Connection Failover Do?........................................................................................ 8-1
Using Fast Connection Failover............................................................................................................. 8-2
Fast Connection Failover Prerequisites........................................................................................... 8-2
Configuring ONS For Fast Connection Failover ........................................................................... 8-2
ONS Configuration File ............................................................................................................. 8-2
Client-side ONS Configuration................................................................................................. 8-3
Using the oncstl Command................................................................................................ 8-3
Server-side ONS Configuration Using racgons...................................................................... 8-4
Other Uses of racgons ......................................................................................................... 8-4
Enabling Fast Connection Failover.................................................................................................. 8-4
Querying Fast Connection Failover Status..................................................................................... 8-5
Understanding Fast Connection Failover ............................................................................................ 8-5
What The Application Sees............................................................................................................... 8-5
What's Happening ............................................................................................................................. 8-6
Comparison of Fast Connection Failover and TAF............................................................................ 8-6
9 Distributed Transactions
Overview .................................................................................................................................................... 9-1
Distributed Transaction Components and Scenarios ................................................................... 9-2
Distributed Transaction Concepts ................................................................................................... 9-2
Switching Between Global and Local Transactions ...................................................................... 9-4
Mode Restrictions On Operations ............................................................................................ 9-4
Oracle XA Packages ........................................................................................................................... 9-5
XA Components........................................................................................................................................ 9-5
XA Datasource Interface and Oracle Implementation.................................................................. 9-5
XA Connection Interface and Oracle Implementation ................................................................. 9-6
XA Resource Interface and Oracle Implementation ..................................................................... 9-7
XA Resource Method Functionality and Input Parameters......................................................... 9-8
Start ............................................................................................................................................... 9-8
End ................................................................................................................................................ 9-9
Prepare....................................................................................................................................... 9-10
Commit ...................................................................................................................................... 9-11
Roll back .................................................................................................................................... 9-11
Forget ......................................................................................................................................... 9-11
Recover ...................................................................................................................................... 9-11
Check for same RM.................................................................................................................. 9-11
XA ID Interface and Oracle Implementation .............................................................................. 9-12
Error Handling and Optimizations.................................................................................................... 9-13
XA Exception Classes and Methods............................................................................................. 9-13
Mapping between Oracle Errors and XA Errors ........................................................................ 9-13
XA Error Handling.......................................................................................................................... 9-14
Oracle XA Optimizations ............................................................................................................... 9-14
Implementing a Distributed Transaction ......................................................................................... 9-15
Summary of Imports for Oracle XA ............................................................................................. 9-15
Oracle XA Code Sample................................................................................................................. 9-15
viii
10 Oracle Extensions
Introduction to Oracle Extensions ..................................................................................................... 10-2
Support Features of the Oracle Extensions ..................................................................................... 10-2
Support for Oracle Datatypes ....................................................................................................... 10-2
Support for Oracle Objects............................................................................................................. 10-3
Support for Schema Naming ......................................................................................................... 10-4
OCI Extensions ................................................................................................................................ 10-4
Oracle JDBC Packages and Classes ................................................................................................... 10-5
Package oracle.sql ........................................................................................................................... 10-5
Classes of the oracle.sql Package ........................................................................................... 10-5
General oracle.sql.* Datatype Support.................................................................................. 10-6
Overview of Class oracle.sql.STRUCT.................................................................................. 10-7
Overview of Class oracle.sql.REF .......................................................................................... 10-8
Overview of Class oracle.sql.ARRAY ................................................................................... 10-8
Overview of Classes oracle.sql.BLOB, oracle.sql.CLOB, oracle.sql.BFILE ...................... 10-9
Classes oracle.sql.DATE, oracle.sql.NUMBER, and oracle.sql.RAW............................... 10-9
Classes oracle.sql.TIMESTAMP, oracle.sql.TIMESTAMPTZ, and
oracle.sql.TIMESTAMPLTZ ......................................................................................... 10-9
Overview of Class oracle.sql.ROWID ................................................................................. 10-11
Class oracle.sql.OPAQUE ..................................................................................................... 10-11
Package oracle.jdbc ....................................................................................................................... 10-11
Interface oracle.jdbc.OracleConnection .............................................................................. 10-13
Client Identifiers ............................................................................................................. 10-13
Interface oracle.jdbc.OracleStatement................................................................................. 10-13
Interface oracle.jdbc.OraclePreparedStatement ................................................................ 10-14
Interface oracle.jdbc.OracleCallableStatement .................................................................. 10-15
Interface oracle.jdbc.OracleResultSet .................................................................................. 10-17
Interface oracle.jdbc.OracleResultSetMetaData................................................................. 10-17
Class oracle.jdbc.OracleTypes.............................................................................................. 10-17
OracleTypes and Registering Output Parameters ..................................................... 10-17
OracleTypes and the setNull() Method ....................................................................... 10-18
Method getJavaSqlConnection() .......................................................................................... 10-19
Oracle Character Datatypes Support ............................................................................................... 10-19
SQL CHAR Datatypes .................................................................................................................. 10-19
SQL NCHAR Datatypes............................................................................................................... 10-20
Class oracle.sql.CHAR.................................................................................................................. 10-21
oracle.sql.CHAR Objects and Character Sets..................................................................... 10-21
Constructing an oracle.sql.CHAR Object ........................................................................... 10-21
oracle.sql.CHAR Conversion Methods............................................................................... 10-22
Additional Oracle Type Extensions ................................................................................................. 10-23
Oracle ROWID Type..................................................................................................................... 10-23
Example: ROWID................................................................................................................... 10-23
Oracle REF CURSOR Type Category ......................................................................................... 10-24
Example: Accessing REF CURSOR Data ............................................................................ 10-25
ix
11 Accessing and Manipulating Oracle Data
Data Conversion Considerations ....................................................................................................... 11-1
Standard Types Versus Oracle Types .......................................................................................... 11-2
Converting SQL NULL Data ........................................................................................................ 11-2
Testing for NULLs .......................................................................................................................... 11-2
Result Set and Statement Extensions ................................................................................................ 11-2
Comparison of Oracle get and set Methods to Standard JDBC .................................................. 11-3
Standard getObject() Method ........................................................................................................ 11-3
Oracle getOracleObject() Method ................................................................................................. 11-4
Example: Using getOracleObject() with a ResultSet........................................................... 11-4
Example: Using getOracleObject() in a Callable Statement............................................... 11-4
Summary of getObject() and getOracleObject() Return Types................................................. 11-5
Other getXXX() Methods................................................................................................................ 11-6
Return Types of getXXX() Methods ...................................................................................... 11-6
Special Notes about getXXX() Methods................................................................................ 11-7
getBigDecimal() Note ....................................................................................................... 11-7
getBoolean() Note ............................................................................................................. 11-8
Datatypes For Returned Objects from getObject and getXXX.................................................. 11-8
Example: Casting Return Values ........................................................................................... 11-8
The setObject() and setOracleObject() Methods ......................................................................... 11-9
Example: Using setObject() and setOracleObject() ............................................................. 11-9
Other setXXX() Methods ................................................................................................................ 11-9
Input Parameter Types of setXXX() Methods .................................................................... 11-10
Setter Method Size Limitations ............................................................................................ 11-11
Setter Methods That Take Additional Input ...................................................................... 11-12
Method setFixedCHAR() for Binding CHAR Data into WHERE Clauses .................... 11-12
Example............................................................................................................................ 11-13
Using Result Set Meta Data Extensions.......................................................................................... 11-13
12 Globalization Support
Providing Globalization Support ...................................................................................................... 12-2
NCHAR, NVARCHAR2, NCLOB and the defaultNChar Property............................................. 12-2
JDBC Methods Dependent On Conversion ..................................................................................... 12-3
x
Retrieving STRUCT Objects and Attributes................................................................................ 13-5
Retrieving an Oracle Object as an oracle.sql.STRUCT Object ........................................... 13-5
Retrieving an Oracle Object as a java.sql.Struct Object ...................................................... 13-6
Retrieving Attributes as oracle.sql Types............................................................................. 13-6
Retrieving Attributes as Standard Java Types..................................................................... 13-6
Binding STRUCT Objects into Statements................................................................................... 13-6
STRUCT Automatic Attribute Buffering ..................................................................................... 13-7
Creating and Using Custom Object Classes for Oracle Objects .................................................. 13-7
Relative Advantages of ORAData versus SQLData .................................................................. 13-8
Understanding Type Maps for SQLData Implementations...................................................... 13-8
Creating a Type Map Object and Defining Mappings for a SQLData Implementation ....... 13-9
Adding Entries to an Existing Type Map ........................................................................... 13-10
Creating a New Type Map ................................................................................................... 13-10
Materializing Object Types not Specified in the Type File .............................................. 13-11
Understanding the SQLData Interface....................................................................................... 13-11
Understanding the SQLInput and SQLOutput Interfaces ............................................... 13-11
Implementing readSQL() and writeSQL() Methods ......................................................... 13-12
Reading and Writing Data with a SQLData Implementation ................................................ 13-13
Reading SQLData Objects from a Result Set...................................................................... 13-13
Retrieving SQLData Objects from a Callable Statement OUT Parameter ..................... 13-14
Passing SQLData Objects to a Callable Statement as an IN Parameter ......................... 13-14
Writing Data to an Oracle Object Using a SQLData Implementation............................ 13-15
Understanding the ORAData Interface ..................................................................................... 13-15
Understanding ORAData Features ..................................................................................... 13-15
Retrieving and Inserting Object Data.................................................................................. 13-16
Reading and Writing Data with a ORAData Implementation ............................................... 13-17
Reading Data from an Oracle Object Using a ORAData Implementation .................... 13-17
Writing Data to an Oracle Object Using a ORAData Implementation .......................... 13-18
Additional Uses for ORAData..................................................................................................... 13-19
The Deprecated CustomDatum Interface.................................................................................. 13-20
Object-Type Inheritance .................................................................................................................... 13-21
Creating Subtypes ......................................................................................................................... 13-21
Implementing Customized Classes for Subtypes..................................................................... 13-22
Use of ORAData for Type Inheritance Hierarchy ............................................................. 13-22
Person.java using ORAData.......................................................................................... 13-22
Student.java extending Person.java ............................................................................. 13-23
ORADataFactory Implementation ............................................................................... 13-24
Use of SQLData for Type Inheritance Hierarchy .............................................................. 13-25
Person.java using SQLData ........................................................................................... 13-25
Student.java extending Student.java............................................................................ 13-26
Student.java using SQLData ......................................................................................... 13-26
JPublisher Utility.................................................................................................................... 13-27
Retrieving Subtype Objects.......................................................................................................... 13-27
Using Default Mapping ........................................................................................................ 13-27
Using SQLData Mapping...................................................................................................... 13-28
Using ORAData Mapping .................................................................................................... 13-29
Creating Subtype Objects............................................................................................................. 13-29
xi
Sending Subtype Objects.............................................................................................................. 13-30
Accessing Subtype Data Fields ................................................................................................... 13-30
Subtype Data Fields from the getAttribute() Method ...................................................... 13-30
Subtype Data Fields from the getOracleAttribute() Method........................................... 13-30
Inheritance Meta Data Methods.................................................................................................. 13-31
Using JPublisher to Create Custom Object Classes ..................................................................... 13-32
JPublisher Functionality............................................................................................................... 13-32
JPublisher Type Mappings .......................................................................................................... 13-33
Categories of SQL Types....................................................................................................... 13-33
Type-Mapping Modes........................................................................................................... 13-33
Mapping the Oracle object type to Java.............................................................................. 13-34
Mapping Attribute Types to Java ........................................................................................ 13-34
Summary of SQL Type Categories and Mapping Settings .............................................. 13-35
Describing an Object Type ................................................................................................................ 13-35
Functionality for Getting Object Meta Data .............................................................................. 13-35
Steps for Retrieving Object Meta Data ....................................................................................... 13-36
Example ................................................................................................................................... 13-37
xii
Retrieving BFILE Locators.................................................................................................... 14-15
Example: Getting a BFILE locator from a Result Set ................................................ 14-15
Example: Getting a BFILE Locator from a Callable Statement ................................ 14-16
Passing BFILE Locators......................................................................................................... 14-16
Example: Passing a BFILE Locator to a Prepared Statement ................................... 14-16
Example: Passing a BFILE Locator to a Callable Statement ..................................... 14-16
Reading BFILE Data...................................................................................................................... 14-16
Example: Reading BFILE Data ............................................................................................. 14-17
Creating and Populating a BFILE Column................................................................................ 14-17
Creating a BFILE Column in a New Table ......................................................................... 14-17
Populating a BFILE Column................................................................................................. 14-18
Accessing and Manipulating BFILE Data.................................................................................. 14-19
Additional BFILE Features .......................................................................................................... 14-20
xiii
Creating and Using Arrays .................................................................................................................. 16-7
Creating ARRAY Objects and Descriptors .................................................................................. 16-8
Steps in Creating ArrayDescriptor and ARRAY Objects ................................................... 16-8
Creating Multi-Level Collections........................................................................................... 16-9
Using ArrayDescriptor Methods ......................................................................................... 16-10
Serializable ARRAY Descriptors ......................................................................................... 16-10
Retrieving an Array and Its Elements ........................................................................................ 16-11
Retrieving the Array ............................................................................................................. 16-11
Data Retrieval Methods ........................................................................................................ 16-11
getOracleArray() ............................................................................................................. 16-11
getResultSet()................................................................................................................... 16-12
getArray()......................................................................................................................... 16-12
Comparing the Data Retrieval Methods............................................................................. 16-12
Retrieving Elements of a Structured Object Array According to a Type Map ............. 16-13
Retrieving a Subset of Array Elements ............................................................................... 16-13
Retrieving Array Elements into an oracle.sql.Datum Array ........................................... 16-14
Accessing Multi-Level Collection Elements....................................................................... 16-15
Passing Arrays to Statement Objects.......................................................................................... 16-16
Passing an Array to a Prepared Statement......................................................................... 16-16
Passing an Array to a Callable Statement .......................................................................... 16-17
Using a Type Map to Map Array Elements .................................................................................... 16-17
Custom Collection Classes with JPublisher .................................................................................. 16-18
xiv
first() Method..................................................................................................................... 17-9
last() Method ..................................................................................................................... 17-9
absolute() Method............................................................................................................. 17-9
relative() Method .............................................................................................................. 17-9
Methods for Checking the Current Position ...................................................................... 17-10
Processing a Scrollable Result Set ............................................................................................... 17-10
Backward versus Forward Processing................................................................................ 17-10
Presetting the Fetch Direction .............................................................................................. 17-11
Updating Result Sets .......................................................................................................................... 17-11
Performing a DELETE Operation in a Result Set ..................................................................... 17-12
Performing an UPDATE Operation in a Result Set ................................................................. 17-12
Example ................................................................................................................................... 17-13
Performing an INSERT Operation in a Result Set.................................................................... 17-14
Example ................................................................................................................................... 17-15
Update Conflicts............................................................................................................................ 17-15
Fetch Size .............................................................................................................................................. 17-15
Setting the Fetch Size .................................................................................................................... 17-16
Use of Standard Fetch Size versus Oracle Row-Prefetch Setting ........................................... 17-16
Refetching Rows.................................................................................................................................. 17-16
Seeing Database Changes Made Internally and Externally........................................................ 17-17
Seeing Internal Changes............................................................................................................... 17-18
Seeing External Changes .............................................................................................................. 17-18
Visibility versus Detection of External Changes ...................................................................... 17-19
Summary of Visibility of Internal and External Changes ....................................................... 17-20
Oracle Implementation of Scroll-Sensitive Result Sets............................................................ 17-20
Summary of New Methods for Result Set Enhancements .......................................................... 17-21
Modified Connection Methods ................................................................................................... 17-21
New Result Set Methods .............................................................................................................. 17-21
Statement Methods ....................................................................................................................... 17-23
Database Meta Data Methods ..................................................................................................... 17-24
18 Row Set
Introduction............................................................................................................................................ 18-1
Row Set Setup and Configuration ..................................................................................................... 18-2
Runtime Properties for Row Set......................................................................................................... 18-2
Row Set Listener.................................................................................................................................... 18-2
Traversing Through the Rows............................................................................................................. 18-3
Cached Row Set ..................................................................................................................................... 18-4
CachedRowSet Constraints ........................................................................................................... 18-7
JDBC Row Set ........................................................................................................................................ 18-8
xv
Importing the oracle.jdbc.pool and oracle.jdbc.oci Packages ........................................... 19-3
Creating an OCI Connection Pool ......................................................................................... 19-4
Setting the OCI Connection Pool Parameters ...................................................................... 19-4
Checking the OCI Connection Pool Status........................................................................... 19-5
Connecting to an OCI Connection Pool....................................................................................... 19-6
Statement Handling and Caching................................................................................................. 19-7
JNDI and the OCI Connection Pool.............................................................................................. 19-7
OCI Driver Transparent Application Failover................................................................................. 19-8
Failover Type Events ...................................................................................................................... 19-8
TAF Callbacks.................................................................................................................................. 19-8
Java TAF Callback Interface .......................................................................................................... 19-9
Handling the FO_ERROR Event............................................................................................ 19-9
Handling the FO_ABORT Event............................................................................................ 19-9
OCI HeteroRM XA ................................................................................................................................ 19-9
Configuration and Installation .................................................................................................... 19-10
Exception Handling ...................................................................................................................... 19-10
HeteroRM XA Code Example ..................................................................................................... 19-10
Accessing PL/SQL Index-by Tables ................................................................................................. 19-10
Overview ........................................................................................................................................ 19-10
Binding IN Parameters ................................................................................................................. 19-11
Receiving OUT Parameters.......................................................................................................... 19-13
Registering the OUT Parameters ......................................................................................... 19-13
Accessing the OUT Parameter Values ................................................................................ 19-14
JDBC Default Mappings ................................................................................................ 19-14
Oracle Mappings............................................................................................................. 19-14
Java Primitive Type Mappings ..................................................................................... 19-15
22 Performance Extensions
Update Batching .................................................................................................................................... 22-1
Overview of Update Batching Models......................................................................................... 22-2
Oracle Model versus Standard Model .................................................................................. 22-2
Types of Statements Supported ............................................................................................. 22-2
xvi
Oracle Update Batching ................................................................................................................. 22-3
Oracle Update Batching Characteristics and Limitations .................................................. 22-4
Setting the Connection Batch Value ...................................................................................... 22-4
Setting the Statement Batch Value......................................................................................... 22-4
Checking the Batch Value....................................................................................................... 22-5
Overriding the Batch Value ................................................................................................... 22-5
Committing the Changes in Oracle Batching ...................................................................... 22-6
Update Counts in Oracle Batching........................................................................................ 22-7
Standard Update Batching............................................................................................................. 22-8
Limitations in the Oracle Implementation of Standard Batching..................................... 22-8
Adding Operations to the Batch ............................................................................................ 22-9
Executing the Batch ................................................................................................................. 22-9
Committing the Changes in the Oracle Implementation of Standard Batching........... 22-10
Clearing the Batch.................................................................................................................. 22-10
Update Counts in the Oracle Implementation of Standard Batching ............................ 22-11
Error Handling in the Oracle Implementation of Standard Batching............................ 22-12
Intermixing Batched Statements and Non-Batched Statements ..................................... 22-13
Premature Batch Flush ................................................................................................................. 22-14
Additional Oracle Performance Extensions ................................................................................... 22-15
Oracle Row Prefetching................................................................................................................ 22-15
Setting the Oracle Prefetch Value ........................................................................................ 22-15
Oracle Row-Prefetching Limitations................................................................................... 22-17
Defining Column Types ............................................................................................................... 22-17
DatabaseMetaData TABLE_REMARKS Reporting.................................................................. 22-20
Considerations for getProcedures() and getProcedureColumns() Methods................. 22-20
23 Advanced Topics
JDBC Client-Side Security Features .................................................................................................. 23-1
JDBC Support for Oracle Advanced Security ............................................................................. 23-1
OCI Driver Support for Oracle Advanced Security............................................................ 23-1
Thin Driver Support for Oracle Advanced Security........................................................... 23-2
JDBC Support for Login Authentication...................................................................................... 23-2
JDBC Support for Data Encryption and Integrity ...................................................................... 23-2
OCI Driver Support for Encryption and Integrity .............................................................. 23-3
Thin Driver Support for Encryption and Integrity ............................................................. 23-4
Setting Encryption and Integrity Parameters in Java ......................................................... 23-5
Complete example ............................................................................................................ 23-6
JDBC in Applets .................................................................................................................................... 23-7
Connecting to the Database through the Applet........................................................................ 23-7
Connecting to a Database on a Different Host Than the Web Server ..................................... 23-8
Using the Oracle Connection Manager................................................................................. 23-8
Installing and Running the Oracle Connection Manager ........................................... 23-9
Writing the URL that Targets the Connection Manager........................................... 23-10
Connecting through Multiple Connection Managers ............................................... 23-10
Using Signed Applets............................................................................................................ 23-10
Using Applets with Firewalls ..................................................................................................... 23-11
Configuring a Firewall for Applets that use the JDBC Thin Driver ............................... 23-11
xvii
Writing a URL to Connect through a Firewall .................................................................. 23-12
Packaging Applets ........................................................................................................................ 23-13
Specifying an Applet in an HTML Page .................................................................................... 23-14
CODE, HEIGHT, and WIDTH ............................................................................................. 23-14
CODEBASE............................................................................................................................. 23-14
ARCHIVE................................................................................................................................ 23-14
JDBC in the Server: the Server-Side Internal Driver ................................................................... 23-15
Connecting to the Database with the Server-Side Internal Driver ........................................ 23-15
Connecting with the OracleDriver Class defaultConnection() Method ........................ 23-16
Connecting with the OracleDataSource.getConnection() Method ................................. 23-16
Exception-Handling Extensions for the Server-Side Internal Driver .................................... 23-17
Example ................................................................................................................................... 23-17
Session and Transaction Context for the Server-Side Internal Driver................................... 23-18
Testing JDBC on the Server ......................................................................................................... 23-18
Loading an Application into the Server..................................................................................... 23-19
Loading Class Files into the Server ..................................................................................... 23-19
Loading Source Files into the Server................................................................................... 23-19
Server-Side Character Set Conversion of oracle.sql.CHAR Data........................................... 23-20
24 Reference Information
Valid SQL-JDBC Datatype Mappings............................................................................................... 24-1
Supported SQL and PL/SQL Datatypes............................................................................................ 24-4
Embedded SQL92 Syntax .................................................................................................................... 24-7
Disabling Escape Processing ......................................................................................................... 24-7
Time and Date Literals ................................................................................................................... 24-8
Date Literals.............................................................................................................................. 24-8
Time Literals ............................................................................................................................. 24-8
Timestamp Literals .................................................................................................................. 24-9
Scalar Functions............................................................................................................................... 24-9
LIKE Escape Characters ................................................................................................................. 24-9
Outer Joins...................................................................................................................................... 24-10
Function Call Syntax..................................................................................................................... 24-10
SQL92 to SQL Syntax Example ................................................................................................... 24-10
Oracle JDBC Notes and Limitations................................................................................................ 24-11
CursorName................................................................................................................................... 24-11
SQL92 Outer Join Escapes............................................................................................................ 24-11
PL/SQL TABLE, BOOLEAN, and RECORD Types ................................................................ 24-11
IEEE 754 Floating Point Compliance.......................................................................................... 24-12
Catalog Arguments to DatabaseMetaData Calls ...................................................................... 24-12
SQLWarning Class ........................................................................................................................ 24-12
Binding Named Parameters ........................................................................................................ 24-12
Retaining Bound Values ....................................................................................................... 24-12
25 Proxy Authentication
Middle-Tier Authentication Through Proxy Connections............................................................ 25-1
xviii
26 Coding Tips and Troubleshooting
JDBC and Multithreading ................................................................................................................... 26-1
Performance Optimization .................................................................................................................. 26-4
Disabling Auto-Commit Mode ..................................................................................................... 26-4
Example: Disabling AutoCommit ........................................................................................ 26-5
Standard Fetch Size and Oracle Row Prefetching ...................................................................... 26-5
Standard and Oracle Update Batching ........................................................................................ 26-5
Mapping Between Built-in SQL and Java Types ........................................................................ 26-6
Common Problems................................................................................................................................ 26-7
Memory Consumption for CHAR Columns Defined as OUT or IN/OUT Variables .......... 26-7
Memory Leaks and Running Out of Cursors.............................................................................. 26-7
Boolean Parameters in PL/SQL Stored Procedures................................................................... 26-7
Opening More Than 16 OCI Connections for a Process............................................................ 26-8
Basic Debugging Procedures .............................................................................................................. 26-8
Oracle Net Tracing to Trap Network Events .............................................................................. 26-8
Client-Side Tracing ................................................................................................................. 26-9
TRACE_LEVEL_CLIENT ............................................................................................... 26-9
TRACE_DIRECTORY_CLIENT ..................................................................................... 26-9
TRACE_FILE_CLIENT .................................................................................................. 26-10
TRACE_UNIQUE_CLIENT ......................................................................................... 26-10
Server-Side Tracing ............................................................................................................... 26-10
TRACE_LEVEL_SERVER ............................................................................................. 26-10
TRACE_DIRECTORY_SERVER .................................................................................. 26-11
TRACE_FILE_SERVER .................................................................................................. 26-11
Third Party Debugging Tools ..................................................................................................... 26-11
Transaction Isolation Levels and Access Modes ........................................................................... 26-11
Index
xix
List of Tables
3–1 Standard Datasource Properties .............................................................................................. 3-3
3–2 Oracle Extended Datasource Properties ................................................................................. 3-4
3–3 Supported Database Specifiers ................................................................................................ 3-9
4–1 Import Statements for JDBC Driver ........................................................................................ 4-2
4–2 Connection Properties Recognized by Oracle JDBC Drivers .............................................. 4-3
4–3 Default Mappings Between SQL Types and Java Types................................................... 4-13
4–4 LONG and LONG RAW Data Conversions ....................................................................... 4-17
4–5 Bind-Size Limitations By........................................................................................................ 4-23
5–1 JDBC 3.0 Feature Support ......................................................................................................... 5-3
5–2 Key Areas of JDBC 3.0 Functionality ...................................................................................... 5-4
5–3 BLOB Method Equivalents ....................................................................................................... 5-7
5–4 CLOB Method Equivalents....................................................................................................... 5-7
6–1 Comparing Methods Used in Statement Caching................................................................. 6-3
6–2 Methods Used in Statement Allocation and Implicit Statement Caching ......................... 6-7
6–3 Methods Used to Retrieve Explicitly Cached Statements.................................................... 6-8
8–1 onsctl commands........................................................................................................................ 8-4
9–1 Connection Mode Transitions .................................................................................................. 9-4
9–2 Oracle-XA Error Mapping ..................................................................................................... 9-14
10–1 Oracle Datatype Classes......................................................................................................... 10-5
10–2 Key Interfaces and Classes of the oracle.jdbc Package.................................................... 10-12
11–1 getObject() and getOracleObject() Return Types ............................................................... 11-5
11–2 Summary of getXXX() Return Types.................................................................................... 11-6
11–3 Summary of setXXX() Input Parameter Types ................................................................. 11-10
11–4 Size Limitations for setBytes() and setString() Methods ................................................. 11-11
13–1 JPublisher SQL Type Categories, Supported Settings, and Defaults ............................ 13-35
17–1 Visibility of Internal and External Changes for Oracle JDBC......................................... 17-20
18–1 The JDBC and Cached Row Sets Compared ....................................................................... 18-8
19–1 PL/SQL Types and Corresponding JDBC Types............................................................. 19-11
19–2 Arguments of the setPlsqlIndexTable () Method ............................................................. 19-12
19–3 Arguments of the registerIndexTableOutParameter () Method .................................... 19-13
19–4 Argument of the getPlsqlIndexTable () Method .............................................................. 19-14
19–5 Argument of the getOraclePlsqlIndexTable () Method................................................... 19-15
19–6 Arguments of the getPlsqlIndexTable () Method............................................................. 19-16
20–1 OCI Instant Client Shared Libraries ..................................................................................... 20-1
22–1 Valid Column Type Specifications ..................................................................................... 22-20
23–1 Client/Server Negotiations for Encryption or Integrity ................................................... 23-3
23–2 OCI Driver Client Parameters for Encryption and Integrity ............................................ 23-4
23–3 Thin Driver Client Parameters for Encryption and Integrity ........................................... 23-5
24–1 Valid SQL Datatype-Java Class Mappings.......................................................................... 24-1
24–2 Support for SQL Datatypes ................................................................................................... 24-4
24–3 Support for ANSI-92 SQL Datatypes ................................................................................... 24-4
24–4 Support for SQL User-Defined Types.................................................................................. 24-5
24–5 Support for PL/SQL Datatypes ............................................................................................ 24-5
26–1 Mapping of SQL Datatypes to Java Classes that Represent SQL Datatypes.................. 26-6
xx
Send Us Your Comments
Oracle Database JDBC Developer's Guide and Reference, 10g Release 1 (10.1)
Part No. B10979-01
Oracle welcomes your comments and suggestions on the quality and usefulness of this
publication. Your input is an important part of the information used for revision.
■ Did you find any errors?
■ Is the information clearly presented?
■ Do you need more information? If so, where?
■ Are the examples correct? Do you need more examples?
■ What features did you like most about this manual?
If you find any errors or have any other suggestions for improvement, please indicate
the title and part number of the documentation and the chapter, section, and page
number (if available). You can send comments to us in the following ways:
■ Electronic mail: [email protected]
■ FAX: (650) 506-7225 Attn: Java Platform Group, Information Development
Manager
■ Postal service:
Oracle Corporation
Java Platform Group, Information Development Manager
500 Oracle Parkway, Mailstop 4op9
Redwood Shores, CA 94065
USA
If you would like a reply, please give your name, address, telephone number, and
electronic mail address (optional).
If you have problems with the software, please contact your local Oracle Support
Services.
xxi
xxii
Preface
This preface introduces you to the Oracle Database JDBC Developer's Guide and Reference
discussing the intended audience, structure, and conventions of this document. A list
of related Oracle documents is also provided.
This Preface contains these topics:
■ Intended Audience
■ Documentation Accessibility
■ Structure
■ Related Documents
■ Conventions
Intended Audience
Oracle Database JDBC Developer's Guide and Reference is intended for developers of
JDBC-based applications and applets. This book can be read by anyone with an
interest in JDBC programming, but assumes at least some prior knowledge of the
following:
■ Java
■ Oracle PL/SQL
■ Oracle databases
Documentation Accessibility
Our goal is to make Oracle products, services, and supporting documentation
accessible, with good usability, to the disabled community. To that end, our
documentation includes features that make information available to users of assistive
technology. This documentation is available in HTML format, and contains markup to
facilitate access by the disabled community. Standards will continue to evolve over
time, 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. For additional information, visit the Oracle Accessibility Program Web site
at
http://www.oracle.com/accessibility/
xxiii
Accessibility of Code Examples in Documentation JAWS, a Windows screen reader,
may not always correctly read the code examples in this document. The conventions
for writing code require that closing braces should appear on an otherwise empty line;
however, JAWS may not always read a line of text that consists solely of a bracket or
brace.
Structure
This document contains the following chapters and appendices:
■ Chapter 1, "Overview"—Provides an overview of the Oracle implementation of
JDBC and the Oracle JDBC driver architecture.
■ Chapter 2, "Getting Started"—Introduces the Oracle JDBC drivers and some
scenarios of how you can use them. This chapter also guides you through the
basics of testing your installation and configuration.
■ Chapter 3, "Datasources and URLs"—Discusses connecting applications to
databases using JDBC datasources, as well as the URLs that describe databases.
■ Chapter 4, "Basic Features"—Covers the basic steps in creating any JDBC
application. It also discusses additional basic features of Java and JDBC supported
by the Oracle JDBC drivers.
■ Chapter 5, "JDBC Standards Support"—Presents an overview of JDBC 2.0 and 3.0
features and describes how these features are supported different versions of the
JDK.
■ Chapter 6, "Statement Caching"—Describes Oracle extension statements for
caching.
■ Chapter 7, "Implicit Connection Caching"—Describes the new implicit connection
cache.
■ Chapter 8, "Fast Connection Failover"—Describes the fast connection failover
mechanism, which depends on the implicit connection cache.
■ Chapter 9, "Distributed Transactions"—Covers distributed transactions, otherwise
known as global transactions, and standard XA functionality. (Distributed
transactions are sets of transactions, often to multiple databases, that have to be
committed in a coordinated manner.)
■ Chapter 10, "Oracle Extensions"—Provides an overview of the JDBC extension
classes supplied by Oracle.
■ Chapter 11, "Accessing and Manipulating Oracle Data"—Describes data access
using the Oracle datatype formats rather than Java formats.
■ Chapter 12, "Globalization Support"—Describes support for multi-byte character
sets and other globalization issues.
■ Chapter 13, "Working with Oracle Object Types"—Explains how to map Oracle
object types to Java classes by using either standard JDBC or Oracle extensions.
■ Chapter 14, "Working with LOBs and BFILEs"—Covers the Oracle extensions to
the JDBC standard that let you access and manipulate LOBs and LOB data.
xxiv
■ Chapter 15, "Using Oracle Object References"—Describes the Oracle extensions to
standard JDBC that let you access and manipulate object references.
■ Chapter 16, "Working with Oracle Collections"—Discusses the Oracle extensions to
standard JDBC that let you access and manipulate arrays and their data.
■ Chapter 17, "Result Set Enhancements"—This chapter discusses JDBC 2.0 result set
enhancements such as scrollable result sets and updatable result sets.
■ Chapter 18, "Row Set"—Describes JDBC cached and web row sets.
■ Chapter 19, "JDBC OCI Extensions"—Describes extensions specific to the OCI
driver.
■ Chapter 20, "OCI Instant Client"—Describes OCI support for Instant Client.
■ Chapter 21, "End-To-End Metrics Support"—Describes JDBC support for
end-to-end database metrics.
■ Chapter 22, "Performance Extensions"—Describes Oracle extensions to the JDBC
standard that enhance the performance of your applications.
■ Chapter 23, "Advanced Topics"—Describes advanced JDBC topics such as
globalization support, working with applets, the server-side driver, and embedded
SQL92 syntax.
■ Chapter 24, "Reference Information"—Contains detailed JDBC reference
information.
■ Chapter 25, "Proxy Authentication"—Describes middle-tier authentication using
proxies.
■ Chapter 26, "Coding Tips and Troubleshooting"—Includes coding tips and general
guidelines for troubleshooting your JDBC applications.
■ Appendix A, "JDBC Error Messages"—Lists JDBC error messages and the
corresponding ORA error numbers.
Related Documents
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. Information that pertains to the
Oracle Java platform as a whole, rather than to a particular product (such as JDBC)
is in this book. This book also discusses Java stored procedures, which were
formerly discussed in a standalone book.
■ 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. If you are developing JDBC
applications that use object types, VARRAY types, nested table types, or object
reference types, then JPublisher can generate custom Java classes to map to them.
The following OC4J documents, for Oracle Application Server releases, are also
available from the Oracle Java Platform group:
■ Oracle Application Server Containers for J2EE User’s Guide
xxv
This book provides some overview and general information for OC4J; primer
chapters for servlets, JSP pages, and EJBs; and general configuration and
deployment instructions.
■ 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. It includes a general overview of JSP standards and programming
considerations, as well as discussion of Oracle value-added features and steps for
getting started in the OC4J environment.
■ 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, JavaBeans, and other Java utilities provided with
OC4J.
■ 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. It also documents relevant OC4J configuration
files.
■ Oracle Application Server Containers for J2EE Services Guide
This book provides information about basic Java services supplied with OC4J,
such as JTA, JNDI, and the Oracle Application Server Java Object Cache.
■ Oracle Application Server Containers for J2EE Enterprise JavaBeans Developer’s Guide
This book provides information about the EJB implementation and EJB container
in OC4J.
The following documents are from the Oracle Server Technologies group:
■ Oracle Database Application Developer's Guide - Fundamentals
■ PL/SQL Packages and Types Reference
■ PL/SQL User's Guide and Reference
■ Oracle Database SQL Reference
■ Oracle Net Services Administrator's Guide
■ Oracle 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 Enterprise Manager Administrator's Guide
■ Oracle HTTP Server Administrator’s Guide
■ 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.0.4)
xxvi
The following are available from the JDeveloper group:
■ Oracle JDeveloper online help
■ Oracle JDeveloper documentation on the Oracle Technology Network:
http://otn.oracle.com/products/jdev/content.html
It is recommended, however, that you request only the daily digest of the posted
e-mails. To do this add the following line to the message body as well:
set jsp-interest digest
xxvii
Conventions
This section describes the conventions used in the text and code examples of this
documentation set. It describes:
■ Conventions in Text
■ Conventions in Code Examples
■ Conventions for Windows Operating Systems
Conventions in Text
We use various conventions in text to help you more quickly identify special terms.
The following table describes those conventions and provides examples of their use.
xxviii
The following table describes typographic conventions used in code examples and
provides examples of their use.
xxix
Conventions for Windows Operating Systems
The following table describes conventions for Windows operating systems and
provides examples of their use.
xxx
Convention Meaning Example
ORACLE_HOME In releases prior to Oracle8i release 8.1.3, Go to the ORACLE_BASE\ORACLE_
and ORACLE_ when you installed Oracle components, all HOME\rdbms\admin directory.
BASE subdirectories were located under a top
level ORACLE_HOME directory that by
default used one of the following names:
■ C:\orant for Windows NT
■ C:\orawin98 for Windows 98
This release complies with Optimal
Flexible Architecture (OFA) guidelines. All
subdirectories are not under a top level
ORACLE_HOME directory. There is a top
level directory called ORACLE_BASE that
by default is C:\oracle. If you install the
latest Oracle release on a computer with no
other Oracle software installed, then the
default setting for the first Oracle home
directory is C:\oracle\orann, where nn
is the latest release number. The Oracle
home directory is located directly under
ORACLE_BASE.
All directory path examples in this guide
follow OFA conventions.
Refer to Oracle Database Platform Guide for
Windows for additional information about
OFA compliances and for information
about installing Oracle products in
non-OFA compliant directories.
xxxi
xxxii
1
Overview
This chapter provides an overview of the Oracle implementation of JDBC, covering the
following topics:
■ What is JDBC?
■ Overview of the Oracle JDBC Drivers
■ Overview of Application and Applet Functionality
■ Server-Side Basics
■ Environments and Support
■ Changes At This Release
What is JDBC?
JDBC (Java Database Connectivity) is a standard Java interface for connecting from
Java to relational databases. The JDBC standard was defined by Sun Microsystems,
allowing individual providers to implement and extend the standard with their own
JDBC drivers.
JDBC is based on the X/Open SQL Call Level Interface and complies with the SQL92
Entry Level standard.
In addition to supporting the standard JDBC API, Oracle drivers have extensions to
support Oracle-specific datatypes and to enhance performance.
Overview 1-1
Overview of the Oracle JDBC Drivers
Oracle
Oracle9i
Note: When the JDBC Thin driver is used with an applet, the
client browser must have the capability to support Java sockets.
For applets, the Thin driver can be downloaded into a browser along with the Java
applet being run. The HTTP protocol is stateless, but the Thin driver is not. The initial
HTTP request to download the applet and the Thin driver is stateless. Once the Thin
driver establishes the database connection, the communication between the browser
and the database is stateful.
Using the Thin driver inside an Oracle server is considered separately, under "JDBC
Server-Side Thin Driver" below.
Overview 1-3
Overview of the Oracle JDBC Drivers
The OCI driver supports all installed Oracle Net adapters, including IPC, named
pipes, TCP/IP, and IPX/SPX.
The OCI driver, written in a combination of Java and C, converts JDBC invocations to
calls to the Oracle Call Interface (OCI), using native methods to call C-entry points.
These calls are then sent over Oracle Net to the Oracle database server. The OCI driver
communicates with the server using the Oracle-developed TTC protocol.
The OCI driver uses the OCI libraries, C-entry points, Oracle Net, CORE libraries, and
other necessary files on the client machine on which it is installed. At this release, the
OCI driver supports Instant Client deployment; see Chapter 20, "OCI Instant Client"
for details.
The Oracle Call Interface (OCI) is an application programming interface (API) that
allows you to create applications that use the native procedures or function calls of a
third-generation language to access an Oracle database server and control all phases of
SQL statement execution.
The JDBC OCI driver has the following functionality:
■ Uses OCI
■ Connection Pooling
■ OCI optimized fetch
■ Prefetching
■ Client-side object cache
■ Transparent Application Failover (TAF)
■ Middle-tier authentication
■ Advanced security
To use the JDBC server-side Thin driver, the connecting user must be granted with the
appropriate permission. This is an example of how the permission can be granted for
user SCOTT:
create role jdbcthin;
call dbms_java.grant_permission('JDBCTHIN',
'java.net.SocketPermission',
'*', 'connect' );
grant jdbcthin to scott;
Note that JDBCTHIN in the grant_permission call must be in upper case. The '*' is
a pattern. It is possible to limit the permission to allow connecting to specific machines
or ports. See the Javadoc for complete details on the java.net.SocketPermission
class. Also, refer to the Oracle Database Java Developer's Guide for further discussion of
Java security inside the Oracle server.
Overview 1-5
Overview of Application and Applet Functionality
■ If your code will run inside the target Oracle server, then use the JDBC server-side
internal driver to access that server. (You can also access remote servers using the
server-side Thin driver.)
Applet Basics
You can use only the Oracle JDBC Thin driver for an applet.
For more about applets and a discussion of relevant firewall, browser, and security
issues, see "JDBC in Applets" on page 23-7.
Oracle Extensions
A number of Oracle extensions are available to Oracle JDBC application and applet
programmers, in the following categories:
■ type extensions (such as ROWIDs and REF CURSOR types)
■ wrapper classes for SQL types (the oracle.sql package)
■ support for custom Java classes to map to user-defined types
■ extended LOB support
■ extended connection, statement, and result set functionality
■ performance enhancements
See Chapter 10, "Oracle Extensions" for an overview of type extensions and extended
functionality, and succeeding chapters for further detail. See Chapter 22, "Performance
Extensions" regarding Oracle performance enhancements.
Server-Side Basics
By using the Oracle JDBC server-side internal driver, code that runs in an Oracle
database, such as in Java stored procedures or Enterprise JavaBeans, can access the
database in which it runs.
For a complete discussion of the server-side driver, see "JDBC in the Server: the
Server-Side Internal Driver" on page 23-15.
Overview 1-7
Changes At This Release
Backward Compatibility
The Oracle JDBC drivers are certified to work with currently-supported versions of the
database. For example:
■ The 10g Release 1 (10.1) JDBC drivers are certified to work with 10.0.x, 9.2.x,
9.0.1.x, and 8.1.7.x database releases.
■ The 9.2 Oracle JDBC drivers are certified to work with 9.2.x, 9.0.1.x, and 8.1.7
database releases.
■ The 9.2 Oracle JDBC drivers are not certified to work with older, unsupported
database releases, such as 8.0.x and 7.x.
Forward Compatibility
Existing supported JDBC drivers (Oracle8i 8.1.7.4 and Oracle9i JDBC drivers) are
certified to work against Oracle Database 10g; known limitations will be documented.
New Features
■ Support for the Oracle datatypes TIMESTAMP, TIMESTAMP WITH TIME ZONE,
and TIMESTAMP WITH LOCAL TIME ZONE. See Table 24–1, " Valid SQL
Datatype-Java Class Mappings" on page 24-1.
■ A new statement cache API; the old API is now deprecated. See Chapter 6,
"Statement Caching".
■ Improved Performance in the JDBC Drivers. The JDBC Thin, OCI, and
server-side internal drivers have been completely restructured to improve
performance.
■ Compliance with the JDBC3.0 and J2EE 1.3 standards. See Chapter 5, "JDBC
Standards Support".
■ Support for Oracle 10g database features, including support for EEE double,
VARRAY enhancements, INTERVAL-DAY-TO-SECOND, LONG-to-LOB
conversion, UNLIMITED LSIZE LOBs and native IEEE float.
■ Improved Connection Caching. The Implicit Connection Cache is an improved
JDBC3.0-compliant connection cache implementation for DataSource. Java and
J2EE applications now benefit from transparent access to the cache, support for
multiple users, and the ability to request connections based on user-defined
profiles. See Chapter 7, "Implicit Connection Caching".
■ Updated Globalization Support. A new globalization file, orai18n.jar,
supersedes the old nls_charset files. See Chapter 12, "Globalization Support".
■ Named SQL Parameter Support. PreparedStatement and
CallableStatement now support referring to SQL parameters by name as well
as by numeric position. See "Interface oracle.jdbc.OracleCallableStatement" on
page 10-15 and "Interface oracle.jdbc.OraclePreparedStatement" on page 10-14.
■ Two New Encryption Algorithms. The JDBC Thin driver now supports 3DES112
and 3DES168 as values for the connection property SQLNET.ENCRYPTION_
TYPES_CLIENT in the JDBC Thin driver.
■ Thin Driver PL/SQL Index Table. You can now send and receive PL/SQL tables
using the Thin driver. For example, you can exchange Java collections with
PL/SQL collections.
■ Instant Client For JDBC-OCI Driver. The JDBC drivers now support Easy Instant
Client for OCI. See Chapter 20, "OCI Instant Client" for details.
■ String Length Increased in LONG Columns.
OraclePreparedStatement.setString() now accepts Strings up to 32766
characters long and can insert these Strings into LONG columns. If you specify a
longer string, an ORA-17157 error is thrown.
■ Two new JAR files, ojdbc14dms.jar and ojdbc14dms_g.jar, have been
added to the release. If your application uses JDBC1.4 features and DMS, you
must add one of these files to your CLASSPATH. Use ojdbc14dms.jar if you use
both JDK1.4 and DMS; use jdbc14dms_g.jar if you use JDK1.4 and DMS and
need debugging features.
Note: These two JAR files are only available as part of Oracle
Application Server 10g.
Overview 1-9
Changes At This Release
Deprecated Features
The class OracleConnectionCacheImpl. The new Implicit Connection Cache replaces
this class. You should migrate your application to the new connection cache as quickly
as possible, because the new implementation is more powerful and easier to use.
Desupported Features
■ ZIP files. All class libraries are now supplied in JAR format only.
■ Support for JDK1.1. 10g Release 1 (10.1) of JDBC does not support JDK1.1. The
files classes111.zip, classes111.jar, classes111_g.zip, and
classes111_g.jar are not included in this release.
■ The multi-language globalization files nls_charset11.zip, nls_
charset11.jar, nls_charset12.zip, and nls_charset12.jar. To
support globalization, add orai18n.jar to your CLASSPATH. See Chapter 12,
"Globalization Support".
■ OracleLog is deprecated when using ojdbc14.jar. If your application uses
OracleLog and ojdbc14_g.jar, you should be aware of the following issues:
■ OracleLog.setTraceEnable() is supported and must be called to turn on
tracing.
■ OracleLog.setLogStream() is supported, but
OracleLog.setLogWriter() is not supported.
■ No other OracleLog() methods are supported.
We recommend that you use the standard Java logging facilities in
java.util.logging.
■ NLS_LANG dependency removal. The NLS_LANG variable is now completely
desupported; setting NLS_LANG now has no effect.
Interface Changes
This release contains the following changes to the interfaces of existing methods:
■ The interface for OracleStatement.defineColumnType() has changed; see
"Defining Column Types" on page 22-17.
■ Handling of international character sets has changed. See Chapter 12,
"Globalization Support" for details.
■ CallableStatement instances that invoke PL/SQL procedures must register all
out parameters using CallableStatement.registerOutParameter(). If a
CallableStatement invokes a procedure without registering its out
parameters, a NullPointerException may be thrown.
■ As of this release, you must supply the size parameter when invoking
OracleStatement.defineColumnType() on a CHAR or VARCHAR column. In
previous releases, the size parameter was interpreted in bytes; it is now
interpreted in Java chars. When using the Thin driver, it is best to avoid using
defineColumnType(). No benefit is derived from using this method; it can
cause problems if the arguments are not optimal. If defineColumnType() is not
used, the Thin driver behaves exactly as if the optimal arguments were used.
Overview 1-11
Changes At This Release
Backward Compatibility
The JDBC drivers are certified to work with the currently supported versions of the
database. (You can find a complete up-to-date list of supported databases at
http://metalink.oracle.com, Note 203849.1.) For example, the 10g Release 1
(10.1) JDBC Thin drivers are certified to work with the 9.2.x, 9.0.1.x, and 8.1.7 database
releases. The 10g Release 1 (10.1) JDBC thin drivers are not certified to work with
older, unsupported database releases, such as 8.0.x and 7.x.
Forward Compatibility
Existing supported JDBC drivers (Oracle8i 8.1.7.4 and Oracle9i JDBC drivers) are
certified to work against Oracle Database 10g; known limitations will be documented.
Notes: ■Starting with 10g Release 1 (10.1), the Oracle JDBC drivers
Ensure that there is only one JDBC class file (such as classes12.jar, classes12_
g.jar, or ojdbc14.jar), and one globalization classes file (orai18n.jar) in your
CLASSPATH.
Note: If you use JTA features or JNDI features, then you must also
put jta.jar and jndi.jar in your CLASSPATH.
class JDBCVersion
{
public static void main (String args[])
throws SQLException
{
OracleDataSource ods = new OracleDataSource();
ods.setURL("jdbc:oracle:thin:scott/tiger@host:port/service");
Connection conn = ods.getConnection();
// You need to import the java.sql and JDBC packages to use JDBC
import java.sql.*;
import oracle.jdbc.*;
import oracle.jdbc.pool.OracleDataSource;
class JdbcCheckup
{
public static void main(String args[])
throws SQLException, IOException
{
System.out.println("Connecting...");
// Open an OracleDataSource and get a connection
OracleDataSource ods = new OracleDataSource();
ods.setURL("jdbc:oracle:oci:@" + database);
ods.setUser(user);
ods.setPassword(password);
Connection conn = ods.getConnection();
System.out.println("connected.");
// Create a statement
Statement stmt = conn.createStatement();
while (rset.next())
System.out.println(rset.getString(1));
// close the result set, the statement and connect
rset.close();
stmt.close();
conn.close();
System.out.println("Your JDBC installation is correct.");
}
int c = System.in.read();
while (c != '\n' && c != -1)
{
buffer.append((char)c);
c = System.in.read();
}
return buffer.toString().trim();
}
catch(IOException e)
{
return "";
}
}
}
Datasources
The JDBC 2.0 extension API introduced the concept of datasources, which are standard,
general-use objects for specifying databases or other resources to use. Datasources can
optionally be bound to Java Naming and Directory Interface (JNDI) entities so that
you can access databases by logical names, for convenience and portability.
This functionality is a more standard and versatile alternative to the connection
functionality described under "Opening a Connection to a Database" on page 4-2. The
datasource facility provides a complete replacement for the previous JDBC
DriverManager facility.
You can use both facilities in the same application, but ultimately we encourage you to
transition your application to datasources. Eventually, Sun Microsystems will probably
deprecate DriverManager and related classes and functionality.
For further introductory and general information about datasources and JNDI, refer to
the Sun Microsystems specification for the JDBC 2.0 Optional Package.
DataSource Properties
The OracleDataSource class, as with any class that implements the DataSource
interface, provides a set of properties that can be used to specify a database to connect
to. These properties follow the JavaBeans design pattern.
Table 3–1 and Table 3–2 document OracleDataSource properties. The properties in
Table 3–1 are standard properties according to the Sun Microsystems specification. (Be
aware, however, that Oracle does not implement the standard roleName property.)
The properties in Table 3–2 are Oracle extensions.
networkProtocol String network protocol for communicating with the server; for
Oracle, this applies only to the OCI drivers and defaults
to tcp
(Other possible settings include ipc. See the Oracle Net
Services Administrator's Guide for more information.)
password String login password for the user name
portNumber int number of the port where the server listens for requests
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 that there is no getPassword() method, for security reasons.
loginTimeout int The maximum time in seconds that this data source
will wait while attempting to connect to a database.
logWriter java.io.Pr Log writer for this datasource.
intWriter
maxStatements int The maximum number of statements in the
application cache.
serviceName String Database service name for this datasource.
■ Settings for user and password are required, either directly, through the URL
setting, or through the getConnection() call. The user and password settings
in a getConnection() call take precedence over any property settings.
■ If the url property is set, then any tnsEntry, driverType, portNumber,
networkProtocol, serverName, and databaseName property settings are
ignored.
■ If the tnsEntry property is set (which presumes the url property is not set), then
any databaseName, serverName, portNumber, and networkProtocol
settings are ignored.
■ If you are using an OCI driver (which presumes the driverType property is set
to oci) and the networkProtocol is set to ipc, then any other property settings
are ignored.
ods.setDriverType("oci");
ods.setServerName("dlsun999");
ods.setNetworkProtocol("tcp");
ods.setDatabaseName("816");
ods.setPortNumber(1521);
ods.setUser("scott");
ods.setPassword("tiger");
ods.setDriverType("oci");
ods.setServerName("dlsun999");
ods.setNetworkProtocol("tcp");
ods.setDatabaseName("816");
ods.setPortNumber(1521);
ods.setUser("scott");
ods.setPassword("tiger");
...
Calling the JNDI InitialContext() constructor creates a Java object that references
the initial JNDI naming context. System properties that are not shown instruct JNDI
which service provider to use.
The ctx.bind() call binds the OracleDataSource instance to a logical JNDI name.
This means that anytime after the ctx.bind() call, you can use the logical name
jdbc/sampledb in opening a connection to the database described by the properties
of the OracleDataSource instance ods. The logical name jdbc/sampledb is
logically bound to this database.
The JNDI name space has a hierarchy similar to that of a file system. In this example,
the JNDI name specifies the subcontext jdbc under the root naming context and
specifies the logical name sampledb within the jdbc subcontext.
The Context interface and InitialContext class are in the standard
javax.naming package.
Open a Connection
To perform a lookup and open a connection to the database logically bound to the
JNDI name, use the logical JNDI name. Doing this requires casting the lookup result
(which is otherwise simply a Java Object) to a new OracleDataSource instance
and then using its getConnection() method to open the connection.
Here is an example:
...
OracleDataSource odsconn = (OracleDataSource)ctx.lookup("jdbc/sampledb");
Connection conn = odsconn.getConnection();
...
Notes:
■ When a datasource instance is created, logging is disabled by
default (the log stream name is initially null).
■ Messages written to a log stream registered to a datasource
instance are not written to the same log stream used by
DriverManager.
■ An OracleDataSource instance obtained from a JNDI name
lookup will not have its PrinterWriter set, even if the
PrintWriter was set when a datasource instance was first
bound to this JNDI name.
pair is optional.
■ kprb, the internal server-side driver, uses an implicit
connection; database URLs for the server-side driver end after
the driver_type. See "Connecting to the Database with the
Server-Side Internal Driver" on page 23-15.
■ The Thin driver does not support OS authentication in making
the connection, and therefore does not support special logins.
The first part of the URL specifies which JDBC driver is to be used. The supported
driver_type values are thin, oci, and kprb.
The remainder of the URL contains an optional username and password separated by
a slash, an @, and the database specifier, which uniquely identifies the database to which
the application is connected. Some database specifiers are valid only for the Thin
driver, some only for the OCI driver, and some for both.
Database Specifiers
Table 3–2, " Oracle Extended Datasource Properties", shows the possible database
specifiers, listing which JDBC drivers support each specifier.
(10.1).
■ The Thin driver does not support Oracle Names.
Note: Because the JDBC Thin driver can be used in applets that do
not depend on an Oracle client installation, you cannot use a
TNSNAMES entry to set up a Thin driver connection.
This chapter covers the most basic steps taken in any JDBC application. It also
describes additional basic features of Java and JDBC supported by the Oracle JDBC
drivers.
The following topics are discussed:
■ First Steps in JDBC
■ Sample: Connecting, Querying, and Processing the Results
■ Datatype Mappings
■ Java Streams in JDBC
■ Stored Procedure Calls in JDBC Programs
■ Processing SQL Exceptions
Importing Packages
Regardless of which Oracle JDBC driver you use, include the import statements
shown in Table 4–1 at the beginning of your program:
The Oracle packages listed as optional provide access to the extended functionality
provided by the Oracle drivers, but are not required for the example presented in this
section. For an overview of the Oracle extensions to the JDBC standard, see
Chapter 10, "Oracle Extensions".
See Table 23–2, " OCI Driver Client Parameters for Encryption and Integrity" and
Table 23–3, " Thin Driver Client Parameters for Encryption and Integrity" for
descriptions of encryption and integrity drivers.
complete description of this connection property.) To logon as sys, set the internal_
logon connection property to sysdba or sysoper.
Note: The ability to specify a role is supported only for sys user
name.
For a bequeath connection, we can get a connection as "sys" by setting the internal_
logon property. For a remote connection, we need additional password file setting
procedures.
Remote Connection
Password file pre-procedures are needed for getting connected to a remote database as
user SYS, because the Oracle database security system requires a password file for
remote connections as an administrator.
1. Set a password file on the server side, or on the remote database, using the
password utility orapwd. You can add a password file for user sys as follows:
(UNIX) orapwd file=$ORACLE_HOME/dbs/orapw password=sys entries=200
(WINDOWS) orapwd file=$ORACLE_HOME\database\PWDsid_name.ora
password=sys entries=200
Please refer to the Oracle Database Administrator's Guide for its details. file must
be the name of the password file. password is the password for the user sys. It can
be altered using "alter user ..." in SQLPlus. You should set entries higher
than the number of entries you expect.
The syntax for the password file name is different on Windows than on Unix.
2. Enable remote login as sysdba. This step grants SYSDBA and SYSOPER system
privileges to individual users and lets them connect as themselves.
Stop the database. Then add the following line to (UNIX) initservice_
name.ora (Windows) init.ora:
remote_login_passwordfile=exclusive
Example The following example shows how to use the put() method of the
java.util.Properties class, in this case to set Oracle performance extension
parameters.
//import packages and register the driver
import java.sql.*;
import java.math.*;
import oracle.jdbc.*;
import oracle.jdbc.pool.OracleDataSource;
Note that there is nothing Oracle-specific about this statement; it follows standard
JDBC syntax.
Again, there is nothing Oracle-specific about this statement; it follows standard JDBC
syntax.
Once again, this is standard JDBC syntax. The next() method returns false when it
reaches the end of the result set. The employee names are materialized as Java strings.
could occur. You could also run out of cursors in the database. Closing both the result
set and the statement releases the corresponding cursor in the database; if you close
only the result set, the cursor is not released.
For example, if your ResultSet object is rset and your Statement object is stmt,
close the result set and statement with these lines:
rset.close();
stmt.close();
When you close a Statement object that a given Connection object creates, the
connection itself remains open.
Committing Changes
By default, DML operations (INSERT, UPDATE, DELETE) are committed automatically as
soon as they are executed. This is known as auto-commit mode. You can, however,
disable auto-commit mode with the following method call on the Connection object:
conn.setAutoCommit(false);
(For further discussion of auto-commit mode and an example of disabling it, see
"Disabling Auto-Commit Mode" on page 26-4.)
If you disable auto-commit mode, then you must manually commit or roll back
changes with the appropriate method call on the Connection object:
conn.commit();
or:
conn.rollback();
A COMMIT or ROLLBACK operation affects all DML statements executed since the last
COMMIT or ROLLBACK.
Important:
■ If auto-commit mode is disabled and you close the connection
without explicitly committing or rolling back your last changes,
then an implicit COMMIT operation is executed.
■ Any DDL operation, such as CREATE or ALTER, always includes
an implicit COMMIT. If auto-commit mode is disabled, this
implicit COMMIT will not only commit the DDL statement, but
also any pending DML operations that had not yet been
explicitly committed or rolled back.
class JdbcTest {
public static void main (String args []) throws SQLException {
// Create DataSource and connect to the local database
OracleDataSource ods = new OracleDataSource();
ods.setURL("jdbc:oracle:thin:@//myhost:1521/orcl");
ods.setUser("scott");
ods.setPassword("tiger");
Connection conn = ods.getConnection();
If you want to adapt the code for the OCI driver, replace the
OracleDataSource.setURL() invocation with the following:
ods.setURL("jdbc:oracle:oci:@MyHostString");
Datatype Mappings
The Oracle JDBC drivers support standard JDBC types as well as Oracle-specific BFILE
and ROWID datatypes and types of the REF CURSOR category.
This section documents standard and Oracle-specific SQL-Java default type mappings.
Table of Mappings
For reference, Table 4–3 shows the default mappings between SQL datatypes, JDBC
typecodes, standard Java types, and Oracle extended types.
The SQL Datatypes column lists the SQL types that exist in the 10g Release 1 (10.1)
database.
The JDBC Typecodes column lists data typecodes supported by the JDBC standard
and defined in the java.sql.Types class, or by Oracle in the
oracle.jdbc.OracleTypes class. For standard typecodes, the codes are identical in
these two classes.
The Standard Java Types column lists standard types defined in the Java language.
The Oracle Extension Java Types column lists the oracle.sql.* Java types that
correspond to each SQL datatype in the database. These are Oracle extensions that let
you retrieve all SQL data in the form of a oracle.sql.* Java type. Mapping SQL
datatypes into the oracle.sql datatypes lets you store and retrieve data without
losing information. Refer to "Package oracle.sql" on page 10-5 for more information on
the oracle.sql.* package.
Table 4–3 Default Mappings Between SQL Types and Java Types
Oracle Extension Java
SQL Datatypes JDBC Typecodes Standard Java Types Types
STANDARD JDBC 1.0 TYPES:
CHAR java.sql.Types.CHAR java.lang.String oracle.sql.CHAR
VARCHAR2 java.sql.Types.VARCHAR java.lang.String oracle.sql.CHAR
LONG java.sql.Types.LONGVARCHAR java.lang.String oracle.sql.CHAR
NUMBER java.sql.Types.NUMERIC java.math.BigDecimal oracle.sql.NUMBER
NUMBER java.sql.Types.DECIMAL java.math.BigDecimal oracle.sql.NUMBER
NUMBER java.sql.Types.BIT boolean oracle.sql.NUMBER
NUMBER java.sql.Types.TINYINT byte oracle.sql.NUMBER
NUMBER java.sql.Types.SMALLINT short oracle.sql.NUMBER
NUMBER java.sql.Types.INTEGER int oracle.sql.NUMBER
NUMBER java.sql.Types.BIGINT long oracle.sql.NUMBER
NUMBER java.sql.Types.REAL float oracle.sql.NUMBER
NUMBER java.sql.Types.FLOAT double oracle.sql.NUMBER
NUMBER java.sql.Types.DOUBLE double oracle.sql.NUMBER
RAW java.sql.Types.BINARY byte[] oracle.sql.RAW
RAW java.sql.Types.VARBINARY byte[] oracle.sql.RAW
LONGRAW java.sql.Types.LONGVARBINARY byte[] oracle.sql.RAW
DATE java.sql.Types.DATE java.sql.Date oracle.sql.DATE
DATE java.sql.Types.TIME java.sql.Time oracle.sql.DATE
TIMESTAMP java.sql.Types.TIMESTAMP javal.sql.Timestamp oracle.sql.TIMESTAMP (see
Note)
STANDARD JDBC 2.0 TYPES:
BLOB java.sql.Types.BLOB java.sql.Blob oracle.sql.BLOB
CLOB java.sql.Types.CLOB java.sql.Clob oracle.sql.CLOB
user-defined java.sql.Types.STRUCT java.sql.Struct oracle.sql.STRUCT
object
Table 4–3 (Cont.) Default Mappings Between SQL Types and Java Types
Oracle Extension Java
SQL Datatypes JDBC Typecodes Standard Java Types Types
user-defined java.sql.Types.REF java.sql.Ref oracle.sql.REF
reference
user-defined java.sql.Types.ARRAY java.sql.Array oracle.sql.ARRAY
collection
ORACLE EXTENSIONS:
BFILE oracle.jdbc.OracleTypes.BFILE n/a oracle.sql.BFILE
ROWID oracle.jdbc.OracleTypes.ROWID n/a oracle.sql.ROWID
REF CURSOR oracle.jdbc.OracleTypes.CURSOR java.sql.ResultSet oracle.jdbc.OracleResultSet
type
TIMESTAMP oracle.jdbc.OracleTypes.TIMESTAM java.sql.Timestamp oracle.sql.TIMESTAMP
P
TIMESTAMP oracle.jdbc.OracleTypes.TIMESTAM java.sql.Timestamp oracle.sql.TIMESTAMPTZ
WITH TIME PTZ
ZONE
TIMESTAMP oracle.jdbc.OracleTypes.TIMESTAM java.sql.Timestamp oracle.sql.TIMESTAMPLTZ
WITH LOCAL PLTZ
TIME ZONE
Note: For database versions, such as 8.1.7, that do not support the
TIMESTAMP datatype, this is mapped to DATE.
For a list of all the Java datatypes to which you can validly map a SQL datatype, see
"Valid SQL-JDBC Datatype Mappings" on page 24-1.
See Chapter 10, "Oracle Extensions", for more information on type mappings. In
Chapter 10 you can also find more information on the following:
■ packages oracle.sql and oracle.jdbc
■ type extensions for the Oracle BFILE and ROWID datatypes and user-defined types
of the REF CURSOR category
Classes for Oracle Objects" on page 13-7. (Although these sections focus on custom
Java classes for user-defined objects, there is some general information about other
kinds of custom Java classes as well.)
driver. For more information about globalization support, see "JDBC Methods
Dependent On Conversion" on page 12-3.
Note: Do not create tables with LONG columns. Use LOB columns
(CLOB, NCLOB, BLOB) instead. LONG columns are supported only for
backward compatibility. Oracle Corporation also recommends that
you convert existing LONG columns to LOB columns. LOB columns
are subject to far fewer restrictions than LONG columns. Further,
LOB functionality is enhanced in every release, whereas LONG
functionality has been static for several releases.
Table 4–4 summarizes LONG and LONG RAW data conversions for each stream type.
Getting a LONG RAW Data Column with getBinaryStream() This Java example writes the
contents of a LONG RAW column to a file on the local file system. In this case, the driver
fetches the data incrementally.
The following code creates the table that stores a column of LONG RAW data associated
with the name LESLIE:
-- SQL code:
create table streamexample (NAME varchar2 (256), GIFDATA long raw);
insert into streamexample values ('LESLIE', '00010203040506070809');
The following Java code snippet writes the data from the LESLIE LONG RAW column
into a file called leslie.gif:
ResultSet rset = stmt.executeQuery
("select GIFDATA from streamexample where NAME='LESLIE'");
finally
{
if file != null()
file.close();
}
}
In this example the contents of the GIFDATA column are transferred incrementally in
chunk-sized pieces between the database and the client. The InputStream object
returned by the call to getBinaryStream() reads the data directly from the database
connection.
Getting a LONG RAW Data Column with getBytes() This version of the example gets the
content of the GIFDATA column with getBytes() instead of getBinaryStream(). In
this case, the driver fetches all the data in one call and stores it in a byte array. The
previous code snippet can be rewritten as:
ResultSet rset2 = stmt.executeQuery
("select GIFDATA from streamexample where NAME='LESLIE'");
Because a LONG RAW column can contain up to 2 gigabytes of data, the getBytes()
example will probably use much more memory than the getBinaryStream()
example. Use streams if you do not know the maximum size of the data in your LONG
or LONG RAW columns.
If you redefine column types with defineColumnType(), you must declare the types
of all columns in the query. If you do not, executeQuery() will fail. In addition, you
must cast the Statement object to an oracle.jdbc.OracleStatement object.
As an added benefit, using defineColumnType() saves the driver two round trips to
the database when executing the query. Without defineColumnType(), the JDBC
driver has to request the datatypes of the column types.
Using the example from the previous section, the Statement object stmt is cast to the
OracleStatement and the column containing LONG RAW data is redefined to be of the
type VARBINARAY. The data is not streamed—instead, it is returned in a byte array.
//cast the statement stmt to an OracleStatement
oracle.jdbc.OracleStatement ostmt =
(oracle.jdbc.OracleStatement)stmt;
If you try to get a CHAR, VARCHAR, or RAW column as a data stream without redefining
the column type, the JDBC driver will return a Java InputStream, but no real
streaming occurs. In the case of these datatypes, the JDBC driver fully fetches the data
into an in-memory buffer during a call to the executeQuery() method or next()
method. The getXXXStream() entry points return a stream that reads data from this
buffer.
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 iterator, you must complete any processing of the
stream column before reading the number column.
An exception to this behavior is LOB data, which is also transferred between server
and client as a Java stream. For more information on how the driver treats LOB data,
see "Streaming LOBs and External Files" on page 4-21.
while rset.next()
{
//get the date
java.sql.Date date = rset.getDate(1);
is.close();
Streaming BFILEs
An external file, or BFILE, is used to store a locator to a file outside the database,
stored somewhere on the filesystem of the data server. The locator points to the actual
location of the file.
When a query selects one or more BFILE columns, the JDBC driver transfers to the
client the file pointed to by the locator. The transfer is performed in a Java stream. To
manipulate BFILE data from JDBC, use methods in the Oracle extension class
oracle.sql.BFILE. This class provides functionality such as reading from the BFILE
into an input stream, writing from an output stream into a BFILE, determining the
length of a BFILE, and closing a BFILE.
For a complete discussion of how to use streaming BFILE data, see "Reading BFILE
Data" on page 14-16.
Closing a Stream
You can discard the data from a stream at any time by calling the stream's close()
method. You can also close and discard the stream by closing its result set or
connection object. You can find more information about the close() method for data
If you get the stream but do not use it before you get the NUMBER column, the stream
still closes automatically:
As an example of using Oracle syntax, here is a PL/SQL code snippet that creates a
stored function. 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';
end;
This would print output such as the following for an error originating in the JDBC
driver:
exception: Invalid column type
(There is no ORA number message prefix for errors originating in the JDBC driver,
although you can get the ORA number with a getErrorCode() call.)
The following code fragment illustrates how you can catch SQL exceptions and print
the stack trace.
try { <some code> }
catch(SQLException e) { e.printStackTrace (); }
To illustrate how the JDBC drivers handle errors, assume the following code uses an
incorrect column index:
// Iterate through the result and print the employee names
// of the code
try {
while (rset.next ())
System.out.println (rset.getString (5)); // incorrect column index
}
catch(SQLException e) { e.printStackTrace (); }
Assuming the column index is incorrect, executing the program would produce the
following error text:
java.sql.SQLException: Invalid column index
at oracle.jdbc.dbaccess.DBError.check_error(DBError.java:235)
at oracle.jdbc.OracleStatement.prepare_for_new_get(OracleStatement.java:1560)
at oracle.jdbc.OracleStatement.getStringValue(OracleStatement.java:1653)
at oracle.jdbc.OracleResultSet.getString(OracleResultSet.java:175)
at Employee.main(Employee.java:41)
Oracle JDBC supports several different versions of JDBC, including JDBC 2.0 and 3.0.
This chapter provides an overview of JDBC 2.0 and 3.0 support in the Oracle JDBC
drivers. The following topics are discussed:
■ Introduction
■ JDBC 2.0 Support: JDK 1.2.x and Higher Versions
■ JDBC 3.0 Support: JDK 1.4 and Previous Releases
■ Overview of Supported JDBC 3.0 Features
■ Transaction Savepoints
■ JDBC 3.0 LOB Interface Methods
Introduction
The Oracle JDBC drivers provide substantial support for the JDBC 3.0 specification.
Oracle makes supported JDBC 3.0 features are available in JDK1.2 through Oracle
extensions. The following changes have been made as part of this support:
■ The oracle.jdbc2 package has been removed.
■ JDK1.1.x is no longer supported.
The Oracle JDBC drivers support most JDBC 3.0 features, including:
■ Using global and distributed transactions on the same connection (see "Oracle XA
Packages" on page 9-4)
■ Transaction savepoints (see "Transaction Savepoints" on page 5-4)
■ Re-use of prepared statements by connection pools (also known as statement
caching; see Chapter 6, "Statement Caching")
■ Full support for JDK1.4 (see "JDBC 3.0 Support: JDK 1.4 and Previous Releases" in
this chapter)
All of these features are provided in the packages oracle.jdbc and oracle.sql.
These packages support all JDK releases from 1.2 through 1.4; JDBC 3.0 features that
depend on JDK1.4 are made available to earlier JDK versions through Oracle
extensions.
Datatype Support
Oracle JDBC fully supports JDK 1.2.x, which includes standard JDBC 2.0 functionality
through implementation of interfaces in the standard java.sql package. These
interfaces are implemented as appropriate by classes in the oracle.sql and
oracle.jdbc packages.
■ update batching
■ fetch size / row prefetching
In each case, you have the option of using the standard model or the Oracle model. Do
not, however, try to mix usage of the standard model and Oracle model within a single
application for either of these features.
For more information, see the following sections:
■ "Update Batching" on page 22-1
■ "Fetch Size" on page 17-15
■ "Oracle Row Prefetching" on page 22-15
Transaction Savepoints
The JDBC 3.0 specification supports savepoints, which offer finer demarcation within
transactions. Applications can set a savepoint within a transaction and then roll back
(but not commit) all work done after the savepoint. 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, but code operating
within the transaction can preserve partial states.
JDK1.4 specifies a standard savepoint API. Oracle JDBC provides two different
savepoint interfaces: one (java.sql.Savepoint) for JDK1.4 and one
(oracle.jdbc.OracleSavepoint) that works across all supported JDK versions.
JDK1.4 adds savepoint-related APIs to java.sql.Connection; the Oracle JDK
version-independent interface oracle.jdbc.OracleConnection provides
equivalent functionality.
Creating a Savepoint
You create a savepoint using either Connection.setSavepoint(), which returns a
java.sql.Savepoint instance, or
Releasing a Savepoint
You remove a savepoint using Connection.releaseSavepoint(Savepoint
svpt) or OracleConnection.oracleReleaseSavepoint(OracleSavepoint
svpt).
Savepoint Notes
■ After a savepoint has been released, attempting to reference it in a rollback
operation will cause an SQLException to be thrown.
■ When a transaction is committed or rolled back, all savepoints created in that
transaction are automatically released and become invalid.
■ Rolling a transaction back to a savepoint automatically releases and makes invalid
any savepoints created after the savepoint in question.
Savepoint Interfaces
The following methods are used to get information from savepoints. These methods
are defined within both the java.sql.Connection and
oracle.jdbc.OracleSavepoint interfaces:
public int getSavepointId() throws SQLException;
Return the savepoint ID for an unnamed savepoint.
Exceptions:
This chapter describes the benefits and use of statement caching, an Oracle JDBC
extension.
This following topics are discussed:
■ About Statement Caching
■ Using Statement Caching
You can prevent a particular statement from being implicitly cached; see "Disabling
Implicit Statement Caching for a Particular Statement" on page 6-6.
With explicit statement caching, you use specialized Oracle "WithKey" methods to
cache and retrieve statement objects.
Implicit statement caching uses the SQL string of a prepared or callable statement as
the key, requiring no action on your part. Explicit statement caching requires you to
provide a Java string, which it uses as the key.
During implicit statement caching, if the JDBC driver cannot find a statement in cache,
it will automatically create one. During explicit statement caching, if the JDBC driver
cannot find a matching statement in cache, it will return a null value.
Table 6–1 compares the different methods employed in implicit and explicit statement
caching.
Notes:
■ You enable implicit and explicit caching for a particular
physical connection independently. Therefore, it is possible to
do statement caching both implicitly and explicitly during the
same session.
■ Implicit and explicit statement caching share the same cache.
Remember this when you set the statement cache size.
If you call the creationState() method on the pstmt statement object, the method
returns IMPLICIT. If the pstmt statement object was not in cache, then the
creationState() method returns NEW to indicate a new statement was recently
created by the JDBC driver.
Table 6–2 describes the methods used to allocate statements and retrieve implicitly
cached statements.
Table 6–2 Methods Used in Statement Allocation and Implicit Statement Caching
Method Functionality for Implicit Statement Caching
prepareStatement() Triggers 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
prepareCall() Triggers 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
If you call the creationState() method on the pstmt statement object, the method
returns EXPLICIT.
Table 6–3 describes the methods used to retrieve explicitly cached statements.
Turning Caching On
An application turns the implicit connection cache on by invoking
OracleDataSource.setConnectionCachingEnabled(true). After implicit
caching is turned on, the first connection request to the OracleDataSource
transparently creates a connection cache.
Here is a simple example using the implicit connection cache.
For details on the connection cache API, see the Javadoc for OracleDataSource and
OracleConnectionCacheManager.
Opening a Connection
After you have turned connection caching on, whenever you retrieve a connection
through an OracleDataSource.getConnection(), the JDBC drivers check to see
if a connection is available in the cache.
The getConnection() method checks if there are any free physical connections in
the cache that match the specified criteria. If a match is found, a logical connection is
returned wrapping the physical connection. If no physical connection match is found,
a new physical connection is created, wrapped in a logical connection, and returned.
There are four variations on getConnection(), two that make no reference to the
connection cache, and two that specify which sorts of connections the cache may
return. The non-cache-specific getConnection() methods behave as normal.
The connection-cache-specific variations are:
■ getConnection(java.util.Properties
cachedConnectionAttributes)—requests a database connection that
matches the specified cachedConnectionAttributes (see "Other Properties"
on page 7-9 for a discussion of connection attributes)
■ getConnection(java.lang.String user, java.lang.String passwd,
java.util.Properties cachedConnectionAttributes)—requests a
database connection from the Implicit Connection Cache that matches the
specified user, passwd and cachedConnectionAttributes
Closing A Connection
An application returns a connection to the cache by invoking close(). There are two
variants on the close method: one with no arguments, and one that takes a connection
attribute argument, discussed in "Setting Connection Attributes" on page 7-6.
...
// create a DataSource
OracleDataSource ods = new OracleDataSource();
ods.close();
Connection Attributes
Each connection obtained from a datasource can have attributes. Attributes are
specified by the application developer, and are java.lang.Properties
name/value pairs.
Developers use attributes to supply additional semantics to identify connection state.
These semantics can include details like the language used by the connection, whether
the connection is serializable, and so on. The connection cache enforces no restrictions
on the value of connection attributes.
The methods that get and set connection attributes are found on OracleConnection.
Getting Connections
The first connection you retrieve has no attributes; you must set them. After you have
set attributes on a connection, you can request those connections by attribute using the
specialized forms of getConnection:
■ getConnection(java.util.Properties
cachedConnectionAttributes)—requests a database connection that
matches the specified cachedConnectionAttributes
■ getConnection(java.lang.String user, java.lang.String passwd,
java.util.Properties cachedConnectionAttributes)—requests a
database connection from the Implicit Connection Cache that matches the
specified user, passwd and cachedConnectionAttributes. If null values are
passed for user and password, the DataSource defaults are used.
The rules for what constitutes an attribute match are discussed in the next section.
For this reason, applications should always check the attributes of a returned
connection. To do this, use the method java.util.Properties
getUnMatchedConnectionAttributes(), which returns a list of any attributes
that were not matched in retrieving the connection. If the return value of this method
is null, you know that you must set all the connection attributes.
Limit Properties
These properties control the size of the cache.
InitialLimit
Sets how many connections are created in the cache when it is created or reinitialized.
When this property is set to an integer value greater than 0, creating or reinitializing
the cache automatically creates the specified number of connections, filling the cache
in advance of need.
Default: 0
MaxLimit
Sets the maximum number of connection instances the cache can hold. The default
value is Integer.MAX_VALUE, meaning that there is no limit enforced by the
connection cache, so that the number of connections is limited only by the number of
database sessions configured for the database.
Default: Integer.MAX_VALUE (no limit)
MaxStatementsLimit
Sets the maximum number of statements that a connection keeps open. When a cache
has this property set, reinitializing the cache or closing the datasource automatically
closes all cursors beyond the specified MaxStatementsLimit.
Default: 0
MinLimit
Sets the minimum number of connections the cache maintains. This guarantees that
the cache will not shrink below this minimum limit.
Setting the MinLimit property does not initialize the cache to contain the minimum
number of connections. To do this, use the InitialLimit property. See "InitialLimit".
Default
0
Timeout Properties
These properties control the lifetime of an element in the cache.
InactivityTimeout
Sets the maximum time a physical connection can remain idle in a connection cache.
An idle connection is one that is not active and does not have a logical handle
TimeToLiveTimeout
Sets the maximum time in seconds that a logical connection can remain open. When
TimeToLiveTimeout expires, the logical connection is unconditionally closed, the
relevant statement handles are canceled, and the underlying physical connection is
returned to the cache for reuse.
Default: 0 (no timeout in effect)
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.
When AbandonedConnectionTimeout is set, JDBC monitors SQL database activity
on each logical connection. For example, when stmt.execute() is invoked on the
connection, a heartbeat is registered to convey that this connection is active. The
heartbeats are set at each database execution. If a connection has been inactive for the
specified amount of time, the underlying connection is reclaimed and returned to the
cache for reuse.
Default: 0 (no timeout in effect)
PropertyCheckInterval
Sets the time interval at which the cache manager inspects and enforces all specified
cache properties. PropertyCheckInterval is set in seconds.
Default: 900 seconds (15 minutes)
Other Properties
These properties control miscellaneous cache behaviors.
AttributeWeights
See "AttributeWeights" on page 7-14.
ClosestConnectionMatch
See "ClosestConnectionMatch" on page 7-14.
ConnectionWaitTimeout
Specifies cache behavior when a connection is requested and there are already
MaxLimit connections active. If ConnectionWaitTimeout is greater than zero (0),
each connection request waits for the specified number of seconds, or until a
connection is returned to the cache. If no connection is returned to the cache before the
timeout elapses, the connection request returns null.
Default: 0 (no timeout)
LowerThresholdLimit
Sets the lower threshold limit on the cache. The default is 20% of the MaxLimit on the
connection cache. This property is used whenever a releaseConnection() cache
callback method is registered. For details, see "Connection Cache Callbacks" on
page 7-15.
ValidateConnection
Setting ValidateConnection to true causes the connection cache to test every
connection it retrieves against the underlying database.
Default: false
■ refreshCache
■ purgeCache
■ getCacheProperties
■ getCacheNameList
■ getNumberOfAvailableConnections
■ getNumberOfActiveConnections
■ setConnectionPoolDataSource
createCache
This method exists in two signature variants:
void createCache(String cacheName, javax.sql.DataSource ds,
java.util.Properties cacheProps)
Creates a new cache identified by a unique cache name. The newly-created cache
is bound to the specified DataSource object. Cache properties, when specified,
are applied to the cache that gets created. When cache creation is successful, the
Connection Cache Manager adds the new cache to the list of caches managed.
Creating a cache with a user defined cache name facilitates specifying more
meaningful names. For example, DMS metrics collected on a per cache basis could
display metrics attached to a meaningful cache name. createCache throws an
exception, if a cache already exists for the DataSource object passed in.
String createCache(javax.sql.DataSource ds, java.util.Properties cacheProps
Creates a new cache using a generated unique cache name and returns this cache
name. The standard convention used in cache name generation is
DataSourceName#HexRepresentationOfNumberOfCaches. The semantics
are otherwise identical to the previous form.
removeCache
void removeCache(String cacheName, int timeout)
Removes the cache specified by cacheName. All its resources are closed and freed.
The second parameter is a wait timeout value that is specified in seconds. If the wait
timeout value is 0, then all in-use or checked out connections are reclaimed (similar to
TimeToLive timeout) without waiting for the connections in-use to be done. When
invoked with a wait timeout value greater than 0, the operation waits for the specified
period of time for checked out connections to be closed before removing the
connection cache. This includes connections that are closed based on timeouts
specified. Connection cache removal is not reversible.
reinitializeCache
void reinitializeCache(String cacheName, java.util.properties
cacheProperties)
Reinitializes the cache using the specified new set of cache properties. This supports
dynamic reconfiguration of caches; the new properties take effect on all newly-created
connections, as well as on existing connections that are not in use. When the
reinitializeCache() method is called, all in-use connections are closed. The new
cache properties are then applied to all the connections in the cache.
existsCache
boolean existsCache(String CacheName)
Checks whether a specific connection cache exists among the list of caches that the
Connection Cache Manager handles. Returns true if the cache exists, false
otherwise.
enableCache
void enableCache(String cacheName)
disableCache
void disableCache(String cacheName)
Temporarily disables the cache specified by cacheName. This means that, temporarily,
connection requests will not be serviced from this cache. However, in-use connections
will continue to work uninterrupted.
refreshCache
void refreshCache(String cacheName, int mode)
Refreshes the cache specified by cacheName. There are two modes supported,
REFRESH_INVALID_CONNECTIONS and REFRESH_ALL_CONNECTIONS. When
invoked with REFRESH_INVALID_CONNECTIONS, each Connection in the cache is
checked for validity. If an invalid Connection is found, that connection's resources
are removed and replaced with a new Connection. The test for validity is basically a
simple query to the dual table: select 1 from dual. When invoked with
REFRESH_ALL_CONNECTIONS, all available connections in the cache are closed and
replaced with new valid physical connections.
purgeCache
void purgeCache(String cacheName, boolean cleanupCheckedOutConnections)
Removes connections from the connection cache, but does not remove the cache itself.
If the cleanupCheckedOutConnections parameter is set to true, then the checked
out connections are cleaned up, as well as the available connections in the cache. If the
cleanupCheckedOutConnections parameter is set to false, only the available
connections are cleaned up.
getCacheProperties
java.util.properties getCacheProperties(String cacheName)
getCacheNameList
String[] getCacheNameList()
Returns all the connection cache names that are known to the Connection Cache
Manager. The cache names may then be used to manage connection caches using the
Connection Cache Manager APIs.
getNumberOfAvailableConnections
int getNumberOfAvailableConnections(String cacheName)
Returns the number of connections in the connection cache, that are available for use.
The value returned is a snapshot of the number of connections available in the
connection cache at the time the API was processed; it may become invalid quickly.
getNumberOfActiveConnections
int getNumberOfActiveConnections(String cacheName)
Returns the number of checked out connections, connections that are active or busy,
and hence not available for use. The value returned is a snapshot of the number of
checked out connections in the connection cache at the time the API was processed; it
may become invalid quickly.
setConnectionPoolDataSource
void setConnectionPoolDataSource(String cacheName, ConnectionPoolDataSource ds)
Allows connections to be created from an external
OracleConnectionPoolDataSource, instead of the default DataSource, for the
given connection cache. When such a ConnectionPoolDataSource is set, all
DataSource properties, such as url, are derived from this new DataSource.
System.out.println(occm.getNumberOfActiveConnections(cacheName)
+ " connections are active");
Advanced Topics
This section discusses cache functionality that is useful for advanced users, but is not
essential to understanding or using the Implicit Connection Cache. This is divided into
the following sections:
■ Attribute Weights And Connection Matching
■ Connection Cache Callbacks
ClosestConnectionMatch
Setting ClosestConnectionMatch to true causes the connection cache to retrieve
the connection with the closest approximation to the specified connection attributes.
This can be used in combination with AttributeWeights to specify what is
considered a "closest match".
Default: false
AttributeWeights
Sets the weights for each connectionAttribute. Used when
ClosestConnectionMatch is set to true to determine which attributes are given
highest priority when searching for matches. An attribute with a high weight is given
more importance in determining a match than an attribute with a low weight.
AttributeWeights contains a set of Key/Value pairs that set the weights for each
connectionAttribute for which the user intends to request a connection. The Key
is a connectionAttribute and the Value is the weight; a weight must be an
integer value greater than 0. The default weight is 1.
For example, TRANSACTION_ISOLATION could be assigned a weight of 10 and ROLE
a weight of 5. If ClosestConnectionMatch is set to true, when a
connectionAttribute based connection request is made on the cache, connections
with a matching TRANSACTION_ISOLATION will be favored over connections with a
matching ROLE.
Default: No AttributeWeights
The Fast Connection Failover mechanism depends on the Implicit Connection Cache
documented in Chapter 7, "Implicit Connection Caching". As a result, for Fast
Connection Failover to be available, implicit connection caching must be enabled.
This chapter is divided into the following sections:
■ Introduction
■ Using Fast Connection Failover
■ Understanding Fast Connection Failover
■ Comparison of Fast Connection Failover and TAF
Introduction
Fast Connection Failover offers a driver-independent way for your JDBC application
to take advantage of the connection failover facilities offered by 10g Release 1 (10.1).
The advantages of Fast Connection Failover include:
■ Driver independence. Fast Connection Failover supports both the Thin and OCI
JDBC drivers.
■ Integration with the Implicit Connection Cache. The two features work together
synergistically to improve application performance and high availability.
■ Integration with RAC for superior RAC/HA event notification mechanisms.
■ Easy integration with application code. You simply enable Fast Connection
Failover and forget it.
The second value is remoteport, the port that ONS binds to on all interfaces for
talking to other ONS daemons. An example of the remoteport configuration is:
remoteport=4200
The third value specifies nodes, a list of other ONS daemons to talk to. Node values
are given as a comma-separated list of either hostnames or IP addresses plus ports.
Note that the port value that is given is the remote port that each ONS instance is
listening on. In order to maintain an identical file on all nodes, the host:port of the
current ONS node can also be listed in the nodes list. It will be ignored when reading
the list.
The nodes listed in the nodes line correspond to the individual nodes in the RAC
cluster. Listing the nodes ensures that the mid-tier node can communicate with the
RAC nodes. At least one mid-tier node and one node in the RAC cluster must be
configured to see one another. As long as one node on each side is aware of the other,
all nodes are visible. You need not list every single cluster and mid-tier node in each
RAC node's ONS config file. In particular, if one RAC cluster node is aware of the
mid-tier, all nodes in the cluster are aware of it.
An example of the nodes configuration is:
nodes=myhost.example.com:4200,123.123.123.123:4200
There are also several optional values that can be provided in ons.config.
The first optional value is a loglevel. This specifies the level of messages that should
be logged by ONS. This value is an integer that ranges from 1 (least messages logged)
to 9 (most messages logged, use only for debugging purposes). The default value is 3.
An example is:
loglevel=3
The second optional value is a logfile name. This specifies a log file that ONS
should use for logging messages. The default value for logfile is $ORACLE_
HOME/opmn/logs/ons.log. An example is:
logfile=/private/oraclehome/opmn/logs/myons.log
The third optional value is a walletfile name. A wallet file is used by the Oracle
SSL layer to store SSL certificates. If a wallet file is specified to ONS, 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. This means that if you
want to turn on SSL for one ONS instance, you must turn it on for all instances that are
connected. This value should point to the directory where your ewallet.p12 file is
located. An example is:
walletfile=/private/oraclehome/opmn/conf/ssl.wlt/default
One optional value is reserved for use on the server side. useocr=on is used to tell
ONS to store all RAC nodes and port numbers in Oracle Cluster Registry (OCR)
instead of in the ONS configuration file. Do not use this option on the client side.
The ons.config file allows blank lines and comments on lines that begin with #.
After configuring ONS, you start the ONS daemon with the onsctl command. It is
the user's responsibility to make sure that an ONS daemon is running at all times.
stop stops the ONS daemon onsctl: shutting down ons daemon...
The add_config version adds the listed hostname(s), the remove_config version
removes them. Both commands propagate the changes among all instances in a cluster.
If multiple port numbers are configured for a host, the specified port number is
removed from hostname. If only hostname is specified, all port numbers for that
host are removed.
Other Uses of racgons You should run racgons whenever you add a new node to the
cluster.
}
...
Note: The application should not try to roll back the transaction; the
transaction was already rolled back in the database by the time the
application received the exception.
What's Happening
Under Fast Connection Failover, each connection in the cache maintains a mapping to
a service, instance, database, and hostname.
When a database generates a RAC event, that event is forwarded to the virtual
machine in which JDBC is running. A daemon thread inside the virtual machine
receives the RAC event and passes it on to the connection cache manager. The
connection cache manager then throws SQL exceptions to the applications affected by
the RAC event.
A typical failover scenario might work like this:
1. A database instance fails, leaving several stale connections in the cache.
2. The RAC mechanism in the database generates a RAC event which is sent to the
virtual machine containing JDBC.
3. The daemon thread inside the virtual machine finds all the connections affected by
the RAC event, notifies them of the closed connection via SQL exceptions, and
rolls back any open transactions.
4. Each individual connection receives a SQL exception and must retry.
For further introductory and general information about distributed transactions, refer
to the Sun Microsystems specifications for the JDBC 2.0 Optional Package and the Java
Transaction API (JTA).
For information on the OCI-specific HeteroRM XA feature, see "OCI HeteroRM XA" on
page 19-9.
Overview
A distributed transaction, sometimes referred to as a global transaction, is a set of two or
more related transactions that must be managed in a coordinated way. The
transactions that constitute a distributed transaction might be in the same database,
but more typically are in different databases and often in different locations. Each
individual transaction of a distributed transaction is referred to as a transaction branch.
For example, a distributed transaction might consist of money being transferred from
an account in one bank to an account in another bank. You would not want either
transaction committed without assurance that both will complete successfully.
In the JDBC 2.0 extension API, distributed transaction functionality is built on top of
connection pooling functionality. This distributed transaction functionality is also built
upon the open XA standard for distributed transactions. (XA is part of the X/Open
standard and is not specific to Java.)
JDBC is used to connect to database resources. However, to include all changes to
multiple databases within a transaction, you must use the JDBC connections within a
JTA global transaction. The process of including database SQL updates within a
transaction is referred to as enlisting a database resource.
The remainder of this overview covers the following topics:
■ Distributed Transaction Components and Scenarios
■ Distributed Transaction Concepts
■ Switching Between Global and Local Transactions
■ Oracle XA Packages
For further introductory and general information about distributed transactions and
XA, refer to the Sun Microsystems specifications for the JDBC 2.0 Optional Package
and the Java Transaction API.
If none of the rules above is applicable, the mode does not change.
Oracle XA Packages
Oracle supplies the following three packages that have classes to implement
distributed transaction functionality according to the XA standard:
■ oracle.jdbc.xa (OracleXid and OracleXAException classes)
■ oracle.jdbc.xa.client
■ oracle.jdbc.xa.server
Classes for XA datasources, XA connections, and XA resources are in both the client
package and the server package. (An abstract class for each is in the top-level
package.) The OracleXid and OracleXAException classes are in the top-level
oracle.jdbc.xa package, because their functionality does not depend on where the
code is running.
In middle-tier scenarios, you will import OracleXid, OracleXAException, and the
oracle.jdbc.xa.client package.
If you intend your XA code to run in the target Oracle database, however, you will
import the oracle.jdbc.xa.server package instead of the client package.
If code that will run inside a target database must also access remote databases, then
do not import either package—instead, 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). Class names are duplicated
between these packages.
XA Components
This section discusses the XA components—standard XA interfaces specified in the
JDBC 2.0 Optional Package, and the Oracle classes that implement them. The
following topics are covered:
■ XA Datasource Interface and Oracle Implementation
■ XA Connection Interface and Oracle Implementation
■ XA Resource Interface and Oracle Implementation
■ XA Resource Method Functionality and Input Parameters
■ XA ID Interface and Oracle Implementation
Notes:
■ Because there must always be a one-to-one correlation between
XA connection instances and XA resource instances, an XA
resource instance is implicitly closed when the associated XA
connection instance is closed.
■ If a transaction is opened by a given XA resource instance, it
must also be closed by the same XA resource instance.
Start
Start work on behalf of a transaction branch, associating the transaction branch with a
distributed transaction.
void start(Xid xid, int flags)
End
End work on behalf of the transaction branch specified by xid, disassociating the
transaction branch from its distributed transaction.
void end(Xid xid, int flags)
Notes:
■ Instead of using the end() method with TMSUSPEND, the
transaction manager can cast to an OracleXAResource
instance and use the suspend(Xid xid) method, an Oracle
extension.
■ This XA functionality to suspend a transaction provides a way
to switch between various transactions within a single JDBC
connection. You can use the XA classes to accomplish this, even
if you are not in a distributed transaction environment and
would otherwise have no need for the XA classes.
■ If you use TMSUSPEND, you must also use TMNOMIGRATE, as in
end(xid, XAResource.TMSUSPEND |
OracleXAResource.TMNOMIGRATE);. This prevents the
application's receiving the error ORA 1002: fetch out of
sequence.
■ In order to avoid Error ORA 1002: fetch out of
sequence, include the TMNOMIGRATE flag as part of the end
method. For example:
end(xid, XAResource.TMSUSPEND |
OracleXAResource.TMNOMIGRATE);
Prepare
Prepare the changes performed in the transaction branch specified by xid. This is the
first phase of a two-phase COMMIT operation, to ensure that the database is accessible
and that the changes can be committed successfully.
int prepare(Xid xid)
Notes:
■ Always call the end() method on a branch before calling the
prepare() method.
■ If there is only one transaction branch in a distributed
transaction, then there is no need to call the prepare()
method. You can call the XA resource commit() method
without preparing first.
Commit
Commit prepared changes in the transaction branch specified by xid. This is the
second phase of a two-phase COMMIT and is performed only after all transaction
branches have been successfully prepared.
void commit(Xid xid, boolean onePhase)
Roll back
Rolls back prepared changes in the transaction branch specified by xid.
void rollback(Xid xid)
Forget
Tells the resource manager to forget about a heuristically completed transaction
branch.
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.
public Xid[] recover(int flag)
The resource manager returns zero or more Xids for the transaction branches that are
currently in a prepared or heuristically completed state. If an error occurs during the
operation, the resource manager throws the appropriate XAException.
the other XA resource instance as input. In the following example, presume xares1
and xares2 are OracleXAResource instances:
boolean sameRM = xares1.isSameRM(xares2);
A transaction manager can use this method regarding certain Oracle optimizations, as
"Oracle XA Optimizations" on page 9-14 explains.
Note: Oracle does not require the use of OracleXid for Oracle
XA resource calls. Instead, use any class that implements the
javax.transaction.xa.Xid interface.
Where fId is an integer value for the format identifier, gId[] is a byte array for the
global transaction identifier, and bId[] is a byte array for the branch qualifier.
The Xid interface specifies the following getter methods:
■ public int getFormatId()
■ public byte[] getGlobalTransactionId()
■ public type[] getBranchQualifier()
or:
public OracleXAException(int error)
The error value is an error code that combines an Oracle SQL error value and an XA
error value. (The JDBC driver determines exactly how to combine the Oracle and XA
error values.)
The OracleXAException class has the following methods:
■ public int getOracleError()
This method returns the Oracle SQL error code pertaining to the exception—a
standard ORA error number (or 0 if there is no Oracle SQL error).
■ public int getXAError()
This method returns the XA error code pertaining to the exception. XA error
values are defined in the javax.transaction.xa.XAException class; refer to
its Javadoc at the Sun Microsystems Web site for more information.
XA Error Handling
The following example uses the OracleXAException class to process an XA
exception:
try {
...
...Perform XA operations...
...
} catch(OracleXAException oxae) {
int oraerr = oxae.getOracleError();
System.out.println("Error " + oraerr);
}
catch(XAException xae)
{...Process generic XA exception...}
In case the XA operations did not throw an Oracle-specific XA exception, the code
drops through to process a generic XA exception.
Oracle XA Optimizations
Oracle JDBC has functionality to improve performance if two or more branches of a
distributed transaction use the same database instance—meaning that the XA resource
instances associated with these branches are associated with the same resource
manager.
In such a circumstance, the prepare() method of only one of these XA resource
instances will return XA_OK (or failure); the rest will return XA_RDONLY, even if
updates are made. This allows the transaction manager to implicitly join all the
transaction branches and commit (or roll back, if failure) the joined transaction
through the XA resource instance that returned XA_OK (or failure).
The transaction manager can use the OracleXAResource class isSameRM() method
to determine if two XA resource instances are using the same resource manager. This
way it can interpret the meaning of XA_RDONLY return values.
(And if you intend to access only the database in which the code runs, you would not
need the oracle.jdbc.xa.client classes.)
The client and server packages each have versions of the OracleXADataSource,
OracleXAConnection, and OracleXAResource classes. Abstract versions of these
three classes are in the top-level oracle.jdbc.xa package.
class XA4
{
public static void main (String args [])
throws SQLException
{
try
{
String URL1 = "jdbc:oracle:oci:@";
// You can put a database name after the @ sign in the connection URL.
String URL2 ="jdbc:oracle:thin:@(description=(address=(host=dlsun991)
(protocol=tcp)(port=5521))(connect_data=(sid=rdbms2)))";
// Create first DataSource and get connection
OracleDataSource ods1 = new OracleDataSource();
ods1.setURL(URL1);
ods1.setUser("scott");
ods1.setPassword("tiger");
Connection conna = ods1.getConnection();
try
{
// Drop the test table
stmta.execute ("drop table my_table");
}
catch (SQLException e)
{
// Ignore an error here
}
try
{
// Create a test table
stmta.execute ("create table my_table (col1 int)");
}
catch (SQLException e)
{
// Ignore an error here too
try
{
// Drop the test table
stmtb.execute ("drop table my_tab");
}
catch (SQLException e)
{
// Ignore an error here
}
try
{
// Create a test table
stmtb.execute ("create table my_tab (col1 char(30))");
}
catch (SQLException e)
{
// Ignore an error here too
}
oxds2.setURL("jdbc:oracle:thin:@(description=(address=(host=dlsun991)
(protocol=tcp)(port=5521))(connect_data=(sid=rdbms2)))");
oxds2.setUser("scott");
oxds2.setPassword("tiger");
oxar1.end(xid1, XAResource.TMSUCCESS);
oxar2.end(xid2, XAResource.TMSUCCESS);
if (prp1 == XAResource.XA_OK)
if (do_commit)
oxar1.commit (xid1, false);
else
oxar1.rollback (xid1);
if (prp2 == XAResource.XA_OK)
if (do_commit)
oxar2.commit (xid2, false);
else
oxar2.rollback (xid2);
// Close connections
conn1.close();
conn1 = null;
conn2.close();
conn2 = null;
pc1.close();
pc1 = null;
pc2.close();
pc2 = null;
rset.close();
rset = null;
rset.close();
rset = null;
stmta.close();
stmta = null;
stmtb.close();
stmtb = null;
conna.close();
conna = null;
connb.close();
connb = null;
Oracle's extensions to the JDBC standard include Java packages and interfaces that let
you access and manipulate Oracle datatypes and use Oracle performance extensions.
Compared to standard JDBC, the extensions offer you greater flexibility in how you
can manipulate the data. This chapter presents an overview of the packages and
classes included in Oracle's extensions to standard JDBC. It also describes some of the
key support features of the extensions.
This chapter includes these topics:
■ Introduction to Oracle Extensions
■ Support Features of the Oracle Extensions
■ Oracle JDBC Packages and Classes
■ Oracle Character Datatypes Support
■ Additional Oracle Type Extensions
To create custom Java classes to correspond to your Oracle objects, Oracle recommends
that you use the Oracle JPublisher utility to create the classes. To do this, you must
define attributes according to how you want to store the data. Oracle JPublisher
performs this task seamlessly with command-line options and can generate either
SQLData or ORAData implementations.
For SQLData implementations, a type map defines the correspondence between Oracle
object datatypes and Java classes. Type maps are objects that specify which Java class
corresponds to each Oracle object datatype. 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.
JPublisher automatically defines getXXX() methods of the custom Java classes, which
retrieve data into your Java application. For more information on the JPublisher utility,
see the Oracle Database JPublisher User's Guide.
Chapter 13, "Working with Oracle Object Types" describes Oracle JDBC support for
Oracle objects.
Where schema_name is the name of the schema and sql_type_name is the SQL type
name of the object. Notice that schema_name and sql_type_name are separated by
a dot (".").
To specify an object type in JDBC, you use its fully qualified name (that is, a schema
name and SQL type name). It is not necessary to enter a schema name if the type name
is in current naming space (that is, the current schema). Schema naming follows these
rules:
■ Both the schema name and the type name may or may not be quoted. However, if
the SQL type name has a dot in it, such as CORPORATE.EMPLOYEE, the type name
must be quoted.
■ The JDBC driver looks for the first unquoted dot in the object's name and uses the
string before the dot as the schema name and the string following the dot as the
type name. If no dot is found, the JDBC driver takes the current schema as default.
That is, you can specify only the type name (without indicating a schema) instead
of specifying the fully qualified name if the object type name belongs to the
current schema. This also explains why you must quote the type name if the type
name has a dot in it.
For example, assume that user Scott creates a type called person.address and
then wants to use it in his session. Scott might want to skip the schema name and
pass in person.address to the JDBC driver. In this case, if person.address is
not quoted, then the dot will be detected, and the JDBC driver will mistakenly
interpret person as the schema name and address as the type name.
■ JDBC passes the object type name string to the database unchanged. That is, the
JDBC driver will not change the character case even if it is quoted.
For example, if ScOtT.PersonType is passed to the JDBC driver as an object
type name, the JDBC driver will pass the string to the database unchanged. As
another example, if there is white space between characters in the type name
string, then the JDBC driver will not remove the white space.
OCI Extensions
See Chapter 19, "JDBC OCI Extensions" for the following OCI driver-specific
information:
■ OCI Driver Connection Pooling
■ OCI Driver Transparent Application Failover
■ OCI HeteroRM XA
Package oracle.sql
The oracle.sql package supports direct access to data in SQL format. This package
consists primarily of classes that provide Java mappings to SQL datatypes.
Essentially, the classes act as Java wrappers for SQL data. The characters are converted
to Java chars (in the UCS2 character set), then into bytes in the UCS2 character set.
Each of the oracle.sql.* datatype classes extends oracle.sql.Datum, a
superclass that encapsulates functionality common to all the datatypes. Some of the
classes are for JDBC 2.0-compliant datatypes. These classes, as Table 10–1 indicates,
implement standard JDBC 2.0 interfaces in the java.sql package, as well as
extending the oracle.sql.Datum class.
You can find more detailed information about each of these classes later in this chapter.
Additional details about use of the Oracle extended types (STRUCT, REF, ARRAY,
BLOB, CLOB, BFILE, and ROWID) are described in the following locations:
■ "Oracle Character Datatypes Support" on page 10-19
■ "Additional Oracle Type Extensions" on page 10-23
■ Chapter 14, "Working with LOBs and BFILEs"
■ Chapter 13, "Working with Oracle Object Types"
■ Chapter 15, "Using Oracle Object References"
■ Chapter 16, "Working with Oracle Collections"
Notes:
■ For information about retrieving data from a result set or
callable statement object into oracle.sql.* types, as
opposed to Java types, see Chapter 11, "Accessing and
Manipulating Oracle Data".
■ The LONG and LONG RAW SQL types and REF CURSOR type
category have no oracle.sql.* classes. Use standard JDBC
functionality for these types. For example, retrieve LONG or
LONG RAW data as input streams using the standard JDBC result
set and callable statement methods getBinaryStream() and
getCharacterStream(). Use the getCursor() method for
REF CURSOR types.
In addition to the datatype classes, the oracle.sql package includes the following
support classes and interfaces, primarily for use with objects and collections:
■ oracle.sql.ArrayDescriptor class: Used in constructing
oracle.sql.ARRAY objects; describes the SQL type of the array. (See "Creating
ARRAY Objects and Descriptors" on page 16-8.)
■ oracle.sql.StructDescriptor class: Used in constructing
oracle.sql.STRUCT objects, which you can use as a default mapping to Oracle
objects in the database. (See "Creating STRUCT Objects and Descriptors" on
page 13-3.)
■ oracle.sql.ORAData and oracle.sql.ORADataFactory interfaces: Used in
Java classes implementing the Oracle ORAData scenario of Oracle object support.
(The other possible scenario is the JDBC-standard SQLData implementation.) See
"Understanding the ORAData Interface" on page 13-15 for more information on
ORAData.
■ oracle.sql.OpaqueDescriptor class: Used to obtain the meta data for an
instance of the oracle.sql.OPAQUE class.
■ a getBytes() method, which returns the SQL data as a byte array (in the raw
format in which JDBC received the data from the database)
■ 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 datatypes that are not part of the
JDBC specification, such as ROWID; the driver returns the object in the
corresponding oracle.sql.* format. For example, it returns an Oracle ROWID
as an oracle.sql.ROWID.
■ appropriate xxxValue() methods to convert SQL data to Java typed—for
example: stringValue(), intValue(), booleanValue(), dateValue(),
bigDecimalValue()
■ additional conversion, getXXX() and setXXX() methods as appropriate for the
functionality of the datatype (such as methods in the 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)
Refer to the Oracle JDBC Javadoc for additional information about these classes. See
"Class oracle.sql.CHAR" on page 10-21 to learn how the oracle.sql.CHAR class
supports character data.
Notes:
■ Elements of the values array, although of the generic Datum
type, actually contain data associated with the relevant
oracle.sql.* type appropriate for the given attribute. You
can cast the element to the appropriate oracle.sql.* type as
desired. For example, a CHAR data attribute within the STRUCT
is materialized as oracle.sql.Datum. To use it as CHAR data,
you must cast it to the oracle.sql.CHAR type.
■ Nested objects in the values array of a STRUCT object are
materialized by the JDBC driver as instances of STRUCT.
In some cases, you might want to manually create a STRUCT object and pass it to a
prepared statement or callable statement. To do this, you must also create a
StructDescriptor object.
For more information about working with Oracle objects using the
oracle.sql.STRUCT and StructDescriptor classes, see "Using the Default
STRUCT Class for Oracle Objects" on page 13-2.
The following code shows how the TimeZone and Calendar objects are created for
US_PACIFIC, which is a time zone name not defined in the JDK:
TimeZone tz = TimeZone.getDefault();
tz.setID("US_PACIFIC");
GregorianCalendar gcal = new GregorianCalendar(tz);
Class oracle.sql.OPAQUE
The oracle.sql.OPAQUE class gives you the name and characteristics of the
OPAQUE type and any attributes. OPAQUE types provide access only to the
uninterrupted bytes of the instance.
Package oracle.jdbc
The interfaces of the oracle.jdbc package provide Oracle-specific extensions to
allow access to raw SQL format data by using oracle.sql.* objects.
For the oracle.jdbc package, Table 10–2 lists key interfaces and classes used for
connections, statements, and result sets.
The remainder of this section describes the interfaces and classes of the oracle.jdbc
package. For more information about using these interfaces and classes to access
Oracle type extensions, see Chapter 11, "Accessing and Manipulating Oracle Data".
Interface oracle.jdbc.OracleConnection
This interface extends standard JDBC connection functionality to create and return
Oracle statement objects, set flags and options for Oracle performance extensions,
support type maps for Oracle objects, and support client identifiers.
"Additional Oracle Performance Extensions" on page 22-15 describes the performance
extensions, including row prefetching and update batching.
Client Identifiers In a connection pooling environment, the client identifier can be used
to identify which light-weight user is currently using the database session. A client
identifier can also be used to share the Globally Accessed Application Context
between different database sessions. The client identifier set in a database session is
audited when database auditing is turned on.
Interface oracle.jdbc.OracleStatement
This interface extends standard JDBC statement functionality and is the superinterface
of the OraclePreparedStatement and OracleCallableStatement classes.
Extended functionality includes support for setting flags and options for Oracle
performance extensions on a statement-by-statement basis, as opposed to the
OracleConnection interface that sets these on a connection-wide basis.
Interface oracle.jdbc.OraclePreparedStatement
This interface extends the OracleStatement interface and extends standard JDBC
prepared statement functionality. Also, the
oracle.jdbc.OraclePreparedStatement interface is extended by the
OracleCallableStatement interface. Extended functionality consists of setXXX()
methods for binding oracle.sql.* types and objects into prepared statements, and
methods to support Oracle performance extensions on a statement-by-statement basis.
"Additional Oracle Performance Extensions" on page 22-15 describes the performance
extensions, including database update batching.
character name in the SQL string. The SQL parameter is a SQL identifier preceded
by a colon (:). For example, :id in
ps = conn.prepareStatement("select * from tab where id = :id");
((OraclePreparedStatement)ps).setIntByName("id", 42);
■ setORAData(): Binds an ORAData object (for use in mapping Oracle object types
to Java) into a prepared statement.
■ setNull(): Sets the value of the object specified by its SQL type name to NULL.
For setNull(param_index, type_code, sql_type_name), if type_code is
REF, ARRAY, or STRUCT, then sql_type_name is the fully qualified name
(schema.sql_type_name) of the SQL type.
■ setFormOfUse(): Sets which form of use this method is going to use. There are
two constants that specify the form of use: FORM_CHAR and FORM_NCHAR, where
FORM_CHAR is the default, meaning that the regular database character set is used.
If the form of use is set to FORM_NCHAR, the JDBC driver will represent the
provided data in the national character set of the server. The following code show
how the FORM_NCHAR is used:
pstmt.setFormOfUse
(parameter index,
oracle.jdbc.OraclePreparedStatement.FORM_NCHAR)
Interface oracle.jdbc.OracleCallableStatement
This interface extends the OraclePreparedStatement interface (which extends the
OracleStatement interface) and incorporates standard JDBC callable statement
functionality.
you can pass the string "bar" to this procedure in one of two ways:
cs.setString(1,"bar"); // JDBC standard
// or...
cs.setString("myparameter","bar"); // Oracle extension
■ setNull(): Sets the value of the object specified by its SQL type name to NULL.
For setNull(param_index, type_code, sql_type_name), if type_code is
REF, ARRAY, or STRUCT, then sql_type_name is the fully qualified
(schema.type) name of the SQL type.
■ setFormOfUse(): Sets which form of use this method is going to use. There are
two constants that specify the form of use: FORM_CHAR and FORM_NCHAR, where
FORM_CHAR is the default. If the form of use is set to FORM_NCHAR, the JDBC
driver will represent the provided data in the national character set of the server.
The following code show how FORM_NCHAR is used:
pstmt.setFormOfUse
(parameter index,
oracle.jdbc.OraclePreparedStatement.FORM_NCHAR)
■ registerOutParameter(): Registers the SQL typecode of the statement's
output parameter. JDBC requires this for any callable statement with an OUT
parameter. It takes an integer parameter index (the position of the output variable
in the statement, relative to the other parameters) and an integer SQL type (the
type constant defined in oracle.jdbc.OracleTypes).
This is an overloaded method. One version of this method is for named types
only—when the SQL typecode is OracleTypes.REF, STRUCT, or ARRAY. In this
case, in addition to a parameter index and SQL type, the method also takes a
String SQL type name (the name of the Oracle user-defined type in the database,
such as EMPLOYEE).
■ close(): Closes the current result set, if any, and the current statement.
Interface oracle.jdbc.OracleResultSet
This interface extends standard JDBC result set functionality, implementing getXXX()
methods for retrieving data into oracle.sql.* objects.
Key methods include:
■ getOracleObject(): This is a generic getXXX() method for retrieving data
into an oracle.sql.Datum object. It can be cast to the specific oracle.sql.*
type as necessary.
■ getXXX(): These methods, such as getCLOB(), are for retrieving data into
oracle.sql.* objects.
Interface oracle.jdbc.OracleResultSetMetaData
This interface extends standard JDBC result set metadata functionality to retrieve
information about Oracle result set objects. See "Using Result Set Meta Data
Extensions" on page 11-13 for information on the functionality of the
OracleResultSetMetadata interface.
Class oracle.jdbc.OracleTypes
The OracleTypes class defines constants that JDBC uses to identify SQL types. Each
variable in this class has a constant integer value. The oracle.jdbc.OracleTypes
class duplicates the typecode definitions of the standard Java java.sql.Types class
and contains these additional typecodes for Oracle extensions:
■ OracleTypes.BFILE
■ OracleTypes.ROWID
■ OracleTypes.CURSOR (for REF CURSOR types)
As in java.sql.Types, all the variable names are in all-caps.
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.
In these signatures, index represents the parameter index, sqlType is the typecode
for the SQL datatype, sql_name is the name given to the datatype (for user-defined
types, when sqlType is a STRUCT, REF, or ARRAY typecode), and scale represents
the number of digits to the right of the decimal point (when sqlType is a NUMERIC or
DECIMAL typecode).
OracleTypes and the setNull() Method The typecodes in Types and OracleTypes identify
the SQL type of the data item, which the setNull() method sets to NULL. The
setNull() method can be found in the java.sql.PreparedStatement interface
and the oracle.jdbc.OraclePreparedStatement interface.
These are the forms that setNull() can take for PreparedStatement and
OraclePreparedStatement objects (assume a standard prepared statement object
ps):
ps.setNull(int index, int sqlType);
In these signatures, index represents the parameter index, sqlType is the typecode
for the SQL datatype, and sql_name is the name given to the datatype (for
user-defined types, when sqlType is a STRUCT, REF, or ARRAY typecode). If you
enter an invalid sqlType, a Parameter Type Conflict exception is thrown.
The following example uses a PreparedStatement to insert a NULL numeric value
into the database. Note the use of OracleTypes.NUMERIC to identify the numeric
object set to NULL (although Types.NUMERIC could have been used as well).
PreparedStatement pstmt =
conn.prepareStatement ("INSERT INTO num_table VALUES (?)");
In this example, the prepared statement inserts a NULL STRUCT object of type
EMPLOYEE into the database.
PreparedStatement pstmt = conn.prepareStatement
Method getJavaSqlConnection()
The getJavaSqlConnection() method of the oracle.sql.* classes returns
java.sql.Connection while the getConnection() method returns
oracle.jdbc.driver.OracleConnection. Because the methods that use the
oracle.jdbc.driver package are deprecated, the getConnection() method is
also deprecated in favor of the getJavaSqlConnection() method.
For the following Oracle datatype classes, the getJavaSqlConnection() method is
available:
■ oracle.sql.ARRAY
■ oracle.sql.BFILE
■ oracle.sql.BLOB
■ oracle.sql.CLOB
■ oracle.sql.OPAQUE
■ oracle.sql.REF
■ oracle.sql.STRUCT
The following shows the getJavaSqlConnection() and the getConnection()
methods in the Array class:
public class ARRAY
{
// New API
//
java.sql.Connection getJavaSqlConnection()
throws SQLException;
// Deprecated API.
//
oracle.jdbc.driver.OracleConnection
getConnection() throws SQLException;
...
}
The usage of SQL NCHAR datatypes is similar to that of the SQL CHAR (CHAR,
VARCHAR2, and CLOB) datatypes. JDBC uses the same classes and methods to access
SQL NCHAR datatypes that are used for the corresponding SQL CHAR datatypes.
Therefore, there are no separate, corresponding classes defined in the oracle.sql
package for SQL NCHAR datatypes. Likewise, there is no separate, corresponding
constant defined in the oracle.jdbc.OracleTypes class for SQL NCHAR
datatypes. The only difference in usage between the two datatypes occur in a data
bind situation: a JDBC program must call the setFormOfUse() method to specify if
the data is bound for a SQL NCHAR datatype.
//
// oracle.jdbc.OraclePreparedStatement.FORM_NCHAR should be used for all NCHAR,
// NVARCHAR2 and NCLOB data types.
//
pstmt.setFormOfUse(2, OraclePreparedStatement.FORM_NCHAR);
pstmt.setFormOfUse(3, OraclePreparedStatement.FORM_NCHAR);
Class oracle.sql.CHAR
The CHAR class is used by Oracle JDBC in handling and converting character data. The
JDBC driver constructs and populates oracle.sql.CHAR objects once character data
has been read from the database.
The CHAR objects constructed and returned by the JDBC driver can be in the database
character set, UTF-8, or ISO-Latin-1 (WE8ISO8859P1). The CHAR objects that are
Oracle object attributes are returned in the database character set.
JDBC application code rarely needs to construct CHAR objects directly, since the JDBC
driver automatically creates CHAR objects as character data are obtained from the
database. There may be circumstances, however, where constructing CHAR objects
directly in application code is useful—for example, to repeatedly pass the same
character data to one or more prepared statements without the overhead of converting
from Java strings each time.
Each character set that Oracle supports has a unique, predefined Oracle ID.
For more information on character sets and character set IDs, see the Oracle
Database Globalization Support Guide.
The CHAR class has multiple constructors—they can take a string, a byte array, or
an object as input along with the CharacterSet object. In the case of a string, the
string is converted to the character set indicated by the CharacterSet object
before being placed into the CHAR object.
See the oracle.sql.CHAR class Javadoc for more information.
Notes:
■ The CharacterSet object cannot be null.
■ The CharacterSet class is an abstract class, therefore it has
no constructor. The only way to create instances is to use the
make() method.
■ The server recognizes the special value
CharacterSet.DEFAULT_CHARSET as the database character
set. For the client, this value is not meaningful.
■ Oracle does not intend or recommend that users extend the
CharacterSet class.
Example: ROWID
The following example shows how to access and manipulate ROWID data.
Statement stmt = conn.createStatement();
// Query the employee names with "FOR UPDATE" to lock the rows.
// Select the ROWID to identify the rows to be updated.
ResultSet rset =
stmt.executeQuery ("SELECT ename, rowid FROM emp FOR UPDATE");
PreparedStatement pstmt =
conn.prepareStatement ("UPDATE emp SET ename = ? WHERE rowid = ?");
To create a cursor variable, begin by identifying a type that belongs to the REF CURSOR
category. For example:
DECLARE TYPE DeptCursorTyp IS REF CURSOR
cstmt.registerOutParameter(1, OracleTypes.CURSOR);
cstmt.execute();
cursor = ((OracleCallableStatement)cstmt).getCursor(1);
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);
If you need the extended functionality provided by the Oracle extensions to JDBC, you
can select the results into a standard ResultSet variable, as above, and then cast that
variable to OracleResultSet later.
Similarly, when you use executeQuery() to execute a stored procedure using a
callable statement, the returned object is an OracleCallableStatement. The type
of the return value of executeQuery() is java.sql.CallableStatement. If your
application needs only the standard JDBC methods, you need not cast the variable.
However, to take advantage of the Oracle extensions, you must cast the variable to an
OracleCallableStatement type. Although the type by which the Java compiler
identifies the object is changed, the object itself is unchanged. Similar rules apply to
prepareStatement(), prepareCall(), and so on.
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. For more information, see the next
section: "Comparison of Oracle get and set Methods to Standard JDBC".
■ 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; they are discussed in "Understanding Type Maps for
SQLData Implementations" on page 13-8. The getObject(parameter_index)
method uses the connection's default type map. 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.
For more information on getObject() return types, see Table 11–1, " getObject() and
getOracleObject() Return Types" on page 11-5.
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.
For more information on getOracleObject() return values, see Table 11–1,
" getObject() and getOracleObject() Return Types" on page 11-5.
For information on type compatibility between all SQL and Java types, see Table 24–1,
" Valid SQL Datatype-Java Class Mappings" on page 24-1.
getBigDecimal() Note
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 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() Note
Because there is no BOOLEAN database type, when you use getBoolean() a datatype
conversion always occurs. The getBoolean() method is supported only for
numeric columns (BIT, TINYINT, SMALLINT, INTEGER, BIGINT, REAL, FLOAT,
DOUBLE, DECIMAL, NUMERIC, CHAR, VARCHAR, or LONGVARCHAR). When applied to
these columns, getBoolean() interprets any zero (0) value as false, and any other
value as true. When applied to any other sort of column, getBoolean() raises the
exception java.lang.NumberFormatException.
Alternatively, you can return the object into a generic oracle.sql.Datum return
variable and cast it later when you use NUMBER-specific methods.
Datum rawdatum = ors.getOracleObject(1);
...
CharacterSet cs = ((NUMBER) rawdatum).FIXME();
This uses the FIXME() method of oracle.sql.NUMBER. The FIXME() method is not
defined on oracle.sql.Datum and would not be reachable without the cast.
For binding Oracle-specific types, using the appropriate specific setXXX() methods
instead of methods for binding standard Java types may offer some performance
advantage.
setAsciiStream() java.io.InputStrea No
(see Notes section) m
setBfile() oracle.sql.BFILE Yes
setBigDecimal() BigDecimal No
setBinaryStream() java.io.InputStrea No
(see Notes section) m
setBlob() java.sql.Blob No
setBoolean() boolean No
setByte() byte No
setBytes() byte[] No
setClob() java.sql.Clob No
setDate() java.sql.Date No
(see Notes section )
setDouble() double No
setInt() int No
setLong() long No
setRef() java.sql.Ref No
setShort() short No
setString() String No
setTime() java.sql.Time No
(see note below)
setTimestamp() java.sql.Timestamp No
(see note below)
setUnicodeStream() java.io.InputStrea No
(see note below) m
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.
Example The following example demonstrates the difference between the setCHAR()
and setFixedCHAR() methods.
/* Schema is :
create table my_table (col1 char(10));
insert into my_table values ('JDBC');
*/
PreparedStatement pstmt = conn.prepareStatement
("select count(*) from my_table where col1 = ?");
((OraclePreparedStatement)pstmt).setFixedCHAR(1, "JDBC");
runQuery (pstmt); // This will print "No of rows are 1"
while (rs.next())
System.out.println("No of rows are " + rs.getInt(1));
rs.close();
rs = null;
}
while (rset.next())
{
OracleResultSetMetaData orsmd = ((OracleResultSet)rset).getMetaData();
int numColumns = orsmd.getColumnCount();
System.out.println("Num of columns = " + numColumns);
The file orai18n.jar is large because it supports a large number of character sets.
You can include only the character set classes you use in your application. To do so,
unpack orai18n.jar, then put only the necessary files in your CLASSPATH.
The character set extension class files are named in the following format:
Name Datatype
lx20OracleCharacterSetId.glb Character set
lx1OracleTerritoryId.glb Territory
lx3OracleLinguisticSortId.glb Collation sequence
lx4OracleMappingId.glb Mapping
After this property is set, your application can access NCHAR, NVARCHAR2, or NCLOB
data without invoking setFormOfUse(). For example:
PreparedStatement pstmt =
conn.prepareStatement("insert into TEST values(?,?,?)");
pstmt.setInt(1, 1); // NUMBER column
pstmt.setString(2, myUnicodeString1); // NVARCHAR2 column
pstmt.setString(3, myUnicodeString2); // NCHAR column
pstmt.execute();
However, if you set defaultNChar to true and then access CHAR columns, the
database will implicitly convert all CHAR data into NCHAR. This conversion has a
substantial performance impact. To avoid this, call
setFormOfUse(4,OraclePreparedStatement.FORM_CHAR) for each CHAR
referred to in the statement. For example:
PreparedStatement pstmt =
conn.prepareStatement("insert into TEST values(?,?,?)");
pstmt.setInt(1, 1); // NUMBER column
pstmt.setString(2, myUnicodeString1); // NVARCHAR2 column
pstmt.setString(3, myUnicodeString2); // NCHAR column
pstmt.setFormOfUse(4, OraclePreparedStatement.FORM_CHAR);
pstmt.setString(4, myString); // CHAR column
pstmt.execute();
This chapter describes JDBC support for user-defined object types. It discusses
functionality of the generic, weakly typed oracle.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.
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
■ Explicitly specify the mappings between Oracle objects and Java classes. This
includes customizing your Java classes for object data. The driver then must be
able to populate instances of the custom object classes that you specify. This
imposes a set of constraints on the Java classes. To satisfy these constraints, you
can define your classes to implement either the JDBC standard
java.sql.SQLData interface or the Oracle extension oracle.sql.ORAData
interface. This is described in "Creating and Using Custom Object Classes for
Oracle Objects" on page 13-7.
You can use the Oracle JPublisher utility to generate custom Java classes.
Note: When you use the SQLData interface, you must use a Java
type map to specify your SQL-Java mapping, unless weakly typed
java.sql.Struct objects will suffice. See "Understanding Type
Maps for SQLData Implementations" on page 13-8.
STRUCT Descriptors
Creating and using a STRUCT object requires a descriptor—an instance of the
oracle.sql.StructDescriptor class—to exist for the SQL type (such as
EMPLOYEE) that will correspond to the STRUCT object. You need only one
StructDescriptor object for any number of STRUCT objects that correspond to the
same SQL type.
STRUCT descriptors are further discussed in "Creating STRUCT Objects and
Descriptors" on page 13-3.
Where sql_type_name is a Java string containing the name of the Oracle object type
(such as EMPLOYEE) and connection is your connection object.
Once you have your StructDescriptor object for the Oracle object type, you can
construct the STRUCT object. To do this, pass in the StructDescriptor, your
connection object, and an array of Java objects containing the attributes you want the
STRUCT to contain.
STRUCT struct = new STRUCT(structdesc, connection, attributes);
Note: The JDBC driver does not verify that the connection object
from the setConnection() method connects to the same
database from which the type descriptor was initially derived.
Another way to return the object as a STRUCT object is to cast the result set to an
OracleResultSet object and use the Oracle extension getSTRUCT() method:
oracle.sql.STRUCT oracleSTRUCT=((OracleResultSet)rs).getSTRUCT(1);
or:
oracle.sql.Datum[] attrs =
((oracle.sql.STRUCT)jdbcStruct).getOracleAttributes();
cast the statement object to an Oracle statement object and use the Oracle extension
setOracleObject() method. For example:
PreparedStatement ps= conn.prepareStatement("text_of_prepared_statement");
STRUCT mySTRUCT = new STRUCT (...);
ps.setObject(1, mySTRUCT, Types.STRUCT);
or:
PreparedStatement ps= conn.prepareStatement("text_of_prepared_statement");
STRUCT mySTRUCT = new STRUCT (...);
((OraclePreparedStatement)ps).setOracleObject(1, mySTRUCT);
When you enable auto-buffering, the oracle.sql.STRUCT object keeps a local copy
of all the converted attributes. This data is retained so that a second access of this
information does not require going through the data format conversion process.
corresponding to the custom object class. If you are using the SQLData interface,
however, you can only use weak reference types in Java (java.sql.Ref or
oracle.sql.REF). The SQLData interface is for mapping SQL objects only.
As an example, assume you have an Oracle object type, EMPLOYEE, in the database
that consists of two attributes: Name (which is type CHAR) and EmpNum (employee
number, which is type NUMBER). You use the type map to specify that the EMPLOYEE
object should map to a custom object class that you call JEmployee. You can
implement either the SQLData or ORAData interface in the JEmployee class.
You can create custom object classes yourself, but the most convenient way to create
them is to employ the Oracle JPublisher utility to create them for you. JPublisher
supports the standard SQLData interface as well as the Oracle-specific ORAData
interface, and is able to generate classes that implement either one. See "Using
JPublisher to Create Custom Object Classes" on page 13-32 for more information.
rs.getObject(int columnIndex);
or:
rs.getObject(int columnIndex, Map map);
For a description of how to create these custom object classes with SQLData, see
"Creating and Using Custom Object Classes for Oracle Objects" on page 13-7.
When using a SQLData implementation, if you do not include a type map entry, then
the object will map to the oracle.sql.STRUCT class by default. (ORAData
implementations, by contrast, have their own mapping functionality so that a type
map entry is not required. When using a ORAData implementation, use the Oracle
getORAData() method instead of the standard getObject() method.)
The type map relates a Java class to the SQL type name of an Oracle object. This
one-to-one mapping is stored in a hash table as a keyword-value pair. When you read
data from an Oracle object, the JDBC driver considers the type map to determine
which Java class to use to materialize the data from the Oracle object type (SQL object
type). When you write data to an Oracle object, the JDBC driver gets the SQL type
name from the Java class by calling the getSQLTypeName() method of the SQLData
interface. The actual conversion between SQL and Java is performed by the driver.
The attributes of the Java class that corresponds to an Oracle object can use either Java
native types or Oracle native types (instances of the oracle.sql.* classes) to store
attributes.
Creating a Type Map Object and Defining Mappings for a SQLData Implementation
When using a SQLData implementation, the JDBC applications programmer is
responsible for providing a type map, which must be an instance of a class that
implements the standard java.util.Map interface.
You have the option of creating your own class to accomplish this, but the standard
class java.util.Hashtable meets the requirement.
Note: If you are migrating from JDK 1.1.x to JDK 1.2.x, you must
ensure that your code uses a class that implements the Map
interface. If you were using the java.util.Hashtable class
under 1.1.x, then no change is necessary.
Hashtable and other classes used for type maps implement a put() method that
takes keyword-value pairs as input, where each key is a fully qualified SQL type name
and the corresponding value is an instance of a specified Java class.
A type map is associated with a connection instance. The standard
java.sql.Connection interface and the Oracle-specific
oracle.jdbc.OracleConnection interface include a getTypeMap() method.
Both return a Map object.
The remainder of this section covers the following topics:
■ Adding Entries to an Existing Type Map
■ Creating a New Type Map
2. Use the type map's put() method to add map entries. 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.
myMap.put(sqlTypeName, classObject);
The sqlTypeName is a string that represents the fully qualified name of the SQL
type in the database. The classObject is the Java class object to which you want
to map the SQL type. Get the class object with the Class.forName() method, as
follows:
myMap.put(sqlTypeName, Class.forName(className));
For example, if you have a PERSON SQL datatype defined in the CORPORATE
database schema, then map it to a Person Java class defined as Person with this
statement:
myMap.put("CORPORATE.PERSON", Class.forName("Person"));
The map has an entry that maps the PERSON SQL datatype in the CORPORATE
database to the Person Java class.
Note: SQL type names in the type map must be all uppercase,
because that is how the Oracle database stores SQL names.
2. Use the put() method of the type map object to add entries to the map. For more
information on the put() method, see Step 2 under "Adding Entries to an
Existing Type Map" on page 13-10. For example, if you have an EMPLOYEE SQL
type defined in the CORPORATE database, then you can map it to an Employee
class object defined by Employee.java, with this statement:
newMap.put("CORPORATE.EMPLOYEE", class.forName("Employee"));
3. When you finish adding entries to the map, use the OracleConnection object's
setTypeMap() method to overwrite the connection's existing type map. For
example:
oraconn.setTypeMap(newMap);
every possible Java type that attributes of an Oracle object might be converted to, such
as readObject(), readInt(), readLong(), readFloat(), readBlob(), and so
on. Each readXXX() method converts SQL data to Java data and returns it into an
output parameter of the corresponding Java type. For example, readInt() returns an
integer.
The SQLOutput implementation is an output stream class, an instance of which must
be passed in to the writeSQL() method. SQLOutput includes a writeXXX()
method for each of these Java types. Each writeXXX() method converts Java data to
SQL data, taking as input a parameter of the relevant Java type. For example,
writeString() would take as input a string attribute from your Java class.
■ The readSQL() method takes as input a SQLInput stream and a string that
indicates the SQL type name of the data (in other words, the name of the Oracle
object type, such as EMPLOYEE).
When your Java application calls getObject(), the JDBC driver creates a
SQLInput stream object and populates it with data from the database. The driver
can also determine the SQL type name of the data when it reads it from the
database. When the driver calls readSQL(), it passes in these parameters.
■ For each Java datatype that maps to an attribute of the Oracle object, readSQL()
must call the appropriate readXXX() method of the SQLInput stream that is
passed in.
For example, if you are reading EMPLOYEE objects that have an employee name as
a CHAR variable and an employee number as a NUMBER variable, you must have a
readString() call and a readInt() call in your readSQL() method. JDBC
calls these methods according to the order in which the attributes appear in the
SQL definition of the Oracle object type.
■ 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.
You must implement writeSQL() as follows:
public void writeSQL(SQLOutput stream) throws SQLException
method. These methods must be called according to the order in which attributes
appear in the SQL definition of the Oracle object type.
■ The writeSQL() method then writes the data converted by the writeXXX()
methods to the SQLOutput stream so that it can be written to the database once
you execute the prepared statement.
The PERSONNEL table contains one column, EMP_COL, of SQL type EMP_OBJECT.
This SQL type is defined in the type map to map to the Java class Employee.
2. 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. The getObject()
method returns the user-defined SQLData object because the type map contains
an entry for Employee.
if (rs.next())
Employee emp = (Employee)rs.getObject(1);
Note that if the type map did not have an entry for the object, then getObject()
would return an oracle.sql.STRUCT object. Cast the output to type STRUCT,
because the getObject() method signature returns the generic
java.lang.Object type.
if (rs.next())
STRUCT empstruct = (STRUCT)rs.getObject(1);
The getObject() call triggers readSQL() and readXXX() calls from the
SQLData interface, as described above.
Note: If you want to avoid using a type map, then use the
getSTRUCT() method. This method always returns a STRUCT
object, even if there is a mapping entry in the type map.
3. If you have get methods in your custom object class, then use them to read data
from your object attributes. For example, if EMPLOYEE has an EmpName (employee
name) of type CHAR, and an EmpNum (employee number) of type NUMBER, then
provide a getEmpName() method that returns a Java String and a
getEmpNum() method that returns an integer (int). Then invoke them in your
Java application, as follows:
String empname = emp.getEmpName();
int empnumber = emp.getEmpNum();
2. Use the getObject() method to retrieve the employee object. The following
code assumes that there is a type map entry to map the Oracle object to Java type
Employee:
Employee emp = (Employee)ocs.getObject(1);
This statement uses the emp object and the empname and empnumber variables
assigned in "Reading SQLData Objects from a Result Set" on page 13-13.
2. Prepare a statement that updates an Oracle object in a row of a database table, as
appropriate, using the data provided in your Java datatype object.
PreparedStatement pstmt = conn.prepareStatement
("INSERT INTO PERSONNEL VALUES (?)");
This method takes as input the column index of the data in your result set, and a
ORADataFactory instance. For example, you can implement a
getORAFactory() method in your custom object class to produce the
ORADataFactory instance to input to getORAData(). The type map is not
required when using Java classes that implement ORAData.
or:
■ Use the standard getObject(index, map) method specified by the
ResultSet interface to retrieve data as instances of ORAData. In this case, 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.
To insert object data:
■ Use the Oracle-specific OraclePreparedStatement class setORAData()
method (assume an OraclePreparedStatement object ops):
ops.setORAData (int bind_index, ORAData custom_obj);
This method takes as input the parameter index of the bind variable and the name
of the object containing the variable.
or:
■ Use the standard setObject() method specified by the PreparedStatement
interface. You can also use this method, in its different forms, to insert ORAData
instances without requiring a type map.
The following sections describe the getORAData() and setORAData() methods.
To continue the example of an Oracle object EMPLOYEE, you might have something
like the following in your Java application:
ORAData datum = ors.getORAData(1, Employee.getORAFactory());
Notes:
■ ORAData and ORADataFactory are defined as separate
interfaces so that different Java classes can implement them if
you wish (such as an Employee class and an
EmployeeFactory class).
■ To use the ORAData interface, your custom object classes must
import oracle.sql.* (or at least ORAData,
ORADataFactory, and Datum).
2. 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. The
getORAData() method returns an oracle.sql.ORAData object, which you can
cast to your specific custom object class.
if (ors.next())
Employee emp = (Employee)ors.getORAData(1, Employee.getORAFactory());
or:
if (ors.next())
ORAData datum = ors.getORAData(1, Employee.getORAFactory());
This example assumes that Employee is the name of your custom object class and
ors is the name of your OracleResultSet object.
In case you do not want to use getORAData(), the JDBC drivers let you use the
getObject() method of a standard JDBC ResultSet to retrieve ORAData data.
However, 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.
For example, if the SQL type name for your object is EMPLOYEE, then the
corresponding Java class is Employee, which will implement ORAData. The
corresponding Factory class is EmployeeFactory, which will implement
ORADataFactory.
Use this statement to declare the EmployeeFactory entry for your type map:
map.put ("EMPLOYEE", Class.forName ("EmployeeFactory"));
Then use the form of getObject() where you specify the map object:
Employee emp = (Employee) rs.getObject (1, map);
If the connection's default type map already has an entry that identifies the factory
class to be used for the given object type, and its corresponding SQL type name,
then you can use this form of getObject():
Employee emp = (Employee) rs.getObject (1);
3. If you have get methods in your custom object class, use them to read data from
your object attributes into Java variables in your application. For example, if
EMPLOYEE has EmpName of type CHAR and EmpNum (employee number) of type
NUMBER, provide a getEmpName() method that returns a Java string and a
getEmpNum() method that returns an integer. Then invoke them in your Java
application as follows:
String empname = emp.getEmpName();
int empnumber = emp.getEmpNum();
These steps assume you have already defined the Oracle object type and created the
corresponding custom object class (or had JPublisher create it for you).
Note: The type map is not used when you are performing
database INSERT and UPDATE operations.
1. If you have set methods in your custom object class, then use them to write data
from Java variables in your application to attributes of your Java datatype object.
emp.setEmpName(empname);
emp.setEmpNum(empnumber);
This statement uses the emp object and the empname and empnumber variables
defined in "Reading Data from an Oracle Object Using a ORAData
Implementation" on page 13-17.
2. Write an Oracle prepared statement that updates an Oracle object in a row of a
database table, as appropriate, using the data provided in your Java datatype
object.
OraclePreparedStatement opstmt = conn.prepareStatement
("UPDATE PERSONNEL SET Employee = ? WHERE Employee.EmpNum = 28959);
The setORAData() method calls the toDatum() method of the custom object
class instance to retrieve an oracle.sql.STRUCT object that can be written to
the database.
In this step you could also use the setObject() method to bind the Java
datatype. For example:
opstmt.setObject(1,emp);
Note: You can use your Java datatype objects as either IN or OUT
bind variables.
It might be useful to provide custom Java classes to wrap oracle.sql.* types and
perhaps implement customized conversions or functionality as well. The following are
some possible scenarios:
■ to perform encryption and decryption or validation of data
■ to perform logging of values that have been read or are being written
■ to parse character columns (such as character fields containing URL information)
into smaller components
■ to map character strings into numeric constants
■ to map data into more desirable Java formats (such as mapping a DATE field to
java.util.Date format)
■ to customize data representation (for example, data in a table column is in feet but
you want it represented in meters after it is selected)
■ to serialize and deserialize Java objects—into or out of RAW fields, for example
For example, 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
create() method in ORADataFactory would have to implement a conversion from
an object of type oracle.sql.RAW to the desired Java object. The toDatum()
method in ORAData would have to implement a conversion from the Java object to an
oracle.sql.RAW object. This can be done, for example, by using Java serialization.
Upon retrieval, the JDBC driver transparently retrieves the raw bytes of data in the
form of an oracle.sql.RAW and calls the ORADataFactory's create() method to
convert the oracle.sql.RAW object to the desired Java class.
When you insert the Java object into the database, you can simply bind it to a column
of type RAW to store it. The driver transparently calls the ORAData.toDatum()
method to convert the Java object to an oracle.sql.RAW object. This object is then
stored in a column of type RAW in the database.
Support for the ORAData interfaces is also highly efficient because the conversions are
designed to work using oracle.sql.* formats, which happen to be the internal
formats used by the JDBC drivers. Moreover, the type map, which is necessary for the
SQLData interface, is not required when using Java classes that implement ORAData.
For more information on why classes that implement ORAData do not need a type
map, see "Understanding the ORAData Interface" on page 13-15.
// implementation:
//
// - Definition of public static fields for
// _SQL_TYPECODE, _SQL_NAME and _SQL_BASETYPE.
// (See Oracle Jdbc documentation for details.)
//
// - Definition of
// public static CustomDatumFactory
// getFactory();
//
}
Object-Type Inheritance
Object-type inheritance allows a new object type to be created by extending another
object type. The new object type is then a subtype of the object type from which it
extends. The subtype automatically inherits all the attributes and methods defined in
the supertype. The subtype can add attributes and methods, and overload or override
methods inherited from the supertype.
Object-type inheritance introduces substitutability. Substitutability is the ability of a slot
declared to hold a value of type T to do so in addition to any subtype of type T. Oracle
JDBC drivers handle substitutability transparently.
A database object is returned with its most specific type without losing information.
For example, if the STUDENT_T object is stored in a PERSON_T slot, the Oracle JDBC
driver returns a Java object that represents the STUDENT_T object.
Creating Subtypes
Create custom object classes if you want to have Java classes that explicitly correspond
to the Oracle object types. (See "Creating and Using Custom Object Classes for Oracle
Objects" on page 13-7.) If you have a hierarchy of object types, you may want a
corresponding hierarchy of Java classes.
The most common way to create a database subtype in JDBC is to pass the extended
SQL CREATE TYPE command to the execute() method of the
java.sql.Statement interface. For example, to create a type inheritance hierarchy
for:
PERSON_T
|
STUDENT_T
|
PARTTIMESTUDENT_T
In the following code, the "foo" member procedure in type ST is overloaded and the
member procedure "print" overwrites the copy it inherits from type T.
CREATE TYPE T AS OBJECT (...,
MEMBER PROCEDURE foo(x NUMBER),
MEMBER PROCEDURE Print(),
...
NOT FINAL;
Once the subtypes have been created, they can be used as both columns of a base table
as well as attributes of a object type. For complete details on the syntax to create
subtypes, see the Oracle Database Application Developer's Guide - Object-Relational
Features for details.
Person.java using ORAData Code for the Person.java class which implements the
ORAData and ORADataFactory interfaces:
class Person implements ORAData, ORADataFactory
{
static final Person _personFactory = new Person();
public Person () {}
Student.java extending Person.java Code for the Student.java class which extends the
Person.java class:
class Student extends Person
{
static final Student _studentFactory = new Student ();
public Student () {}
Customized classes that implement the ORAData interface do not have to mirror the
database object type hierarchy. For example, you could have declared the above class,
Student, without a superclass. In this case, Student would contain fields to hold the
inherited attributes from PERSON_T as well as the attributes declared by STUDENT_T.
ORADataFactory Implementation The JDBC application uses the factory class in querying
the database to return instances of Person or its subclasses, as in the following
example:
ResultSet rset = stmt.executeQuery ("select person from tab1");
while (rset.next())
{
Object s = rset.getORAData (1, PersonFactory.getORADataFactory());
...
}
Person.java using SQLData Code for the Person.java class which implements the
SQLData interface:
import java.sql.*;
public Person () {}
Student.java extending Student.java Code for the Student.java class which extends the
Person.java class:
import java.sql.*;
Customized classes that implement the SQLData interface do not have to mirror the
database object type hierarchy. For example, you could have declared the above class,
Student, without a superclass. In this case, Student would contain fields to hold the
inherited attributes from PERSON_T as well as the attributes declared by STUDENT_T.
Student.java using SQLData Code for the Student.java class which does not extend
the Person.java class, but implements the SQLData interface directly:
import java.sql.*;
public Student () {}
name = stream.readString();
address = stream.readString();
deptid = stream.readInt();
major = stream.readString();
}
JPublisher Utility
Even though you can manually create customized classes that implement the
SQLData, ORAData, and ORADataFactory interfaces, it is recommended that you
use Oracle JPublisher to automatically generate these classes. The customized classes
generated by Oracle JPublisher that implement the SQLData, ORAData, and
ORADataFactory interfaces, can mirror the inheritance hierarchy.
To learn more about JPublisher, see "Using JPublisher to Create Custom Object
Classes" on page 13-32 and the Oracle Database JPublisher User's Guide.
if (s != null)
{
if (s instanceof Person)
System.out.println ("This is a Person");
else if (s instanceof Student)
System.out.println ("This is a Student");
else if (s instanceof ParttimeStudent)
System.out.pritnln ("This is a PartimeStudent");
else
System.out.println ("Unknown type");
}
}
The JDBC drivers check the connection type map for each call to the following:
■ getObject() method of the java.sql.ResultSet and
java.sql.CallableStatement interfaces
■ getAttribute() method of the java.sql.Struct interface
■ getArray() method of the java.sql.Array interface
s is initialized with data fields inherited from PERSON_T and STUDENT_T, and data
fields defined in PARTTIMESTUDENT_T.
if (sqlname.equals ("SCOTT.PERSON")
{
System.out.println ("ssn="+((BigDecimal)attrs[0]).intValue());
System.out.println ("name="+((String)attrs[1]));
System.out.println ("address="+((String)attrs[2]));
}
else if (sqlname.equals ("SCOTT.STUDENT"))
{
System.out.println ("ssn="+((BigDecimal)attrs[0]).intValue());
System.out.println ("name="+((String)attrs[1]));
System.out.println ("address="+((String)attrs[2]));
System.out.println ("deptid="+((BigDecimal)attrs[3]).intValue());
System.out.println ("major="+((String)attrs[4]));
}
else if (sqlname.equals ("SCOTT.PARTTIMESTUDENT"))
{
System.out.println ("ssn="+((BigDecimal)attrs[0]).intValue());
System.out.println ("name="+((String)attrs[1]));
System.out.println ("address="+((String)attrs[2]));
System.out.println ("deptid="+((BigDecimal)attrs[3]).intValue());
System.out.println ("major="+((String)attrs[4]));
System.out.println ("numHours="+((BigDecimal)attrs[5]).intValue());
}
else
throw new Exception ("Invalid type name: "+sqlname);
}
}
rset.close ();
stmt.close ();
conn.close ();
JPublisher Functionality
You can direct JPublisher to create custom object classes that implement either the
SQLData interface or the ORAData interface, according to how you set the JPublisher
type mappings.
If you use the ORAData interface, JPublisher will also create a custom reference class to
map to object references for the Oracle object type. If you use the SQLData interface,
JPublisher will not produce a custom reference class; you would use standard
java.sql.Ref instances instead.
If you want additional functionality, you can subclass the custom object class and add
features as desired. When you run JPublisher, there is a command-line option for
specifying both a generated class name and the name of the subclass you will
implement. For the SQL-Java mapping to work properly, JPublisher must know the
subclass name, which is incorporated into some of the functionality of the generated
class.
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. For a custom object class, uses a SQLData
implementation.
■ Oracle mapping (setting oracle)—Uses corresponding oracle.sql types to
map to SQL types. For a custom object, reference, or collection class, uses a
ORAData implementation.
■ object-JDBC mapping (for numeric types only) (setting objectjdbc)—This is an
extension of JDBC mapping. Where relevant, object-JDBC mapping uses numeric
object types from the standard java.lang package (such as
java.lang.Integer, Float, and Double), instead of primitive Java types
(such as int, float, and double). The java.lang types are nullable, while the
primitive types are not.
■ BigDecimal mapping (for numeric types only) (setting bigdecimal)—Uses
java.math.BigDecimal to map to all numeric attributes; appropriate if you are
dealing with large numbers but do not want to map to the oracle.sql.NUMBER
class.
Table 13–1 JPublisher SQL Type Categories, Supported Settings, and Defaults
SQL Type JPublisher
Category Mapping Option Mapping Settings Default
UDT types -usertypes oracle, jdbc oracle
numeric types -numbertypes oracle, jdbc, objectjdbc, bigdecimal objectjdbc
LOB types -lobtypes oracle, jdbc oracle
built-in types -builtintypes oracle, jdbc jdbc
Example
The following method shows how to retrieve information about the attributes of a
structured object type. This includes the initial step of creating a StructDescriptor
instance.
//
// Print out the ADT's attribute names and types
//
void getAttributeInfo (Connection conn, String type_name) throws SQLException
{
// get the type descriptor
StructDescriptor desc = StructDescriptor.createDescriptor (type_name, conn);
// temporary buffers
String attr_name;
int attr_type;
String attr_typeName;
This chapter describes how you use JDBC and the oracle.sql.* classes to access
and manipulate LOB and BFILE locators and data, covering the following topics:
■ Oracle Extensions for LOBs and BFILEs
■ Working with BLOBs and CLOBs
■ Shortcuts For Inserting and Retrieving CLOB Data
■ Working With Temporary LOBs
■ Using Open and Close With LOBs
■ Working with BFILEs
Notes: ■At 10g Release 1 (10.1), the Oracle JDBC drivers support
access the locators by using standard getter methods, as follows. All the standard and
Oracle-specific getter methods discussed here take either an int column index or a
String column name as input.
■ Under JDK 1.2.x and higher, you can use the standard getBlob() and
getClob() methods, which return java.sql.Blob and Clob objects,
respectively.
If you retrieve or cast the result set or callable statement to an OracleResultSet or
OracleCallableStatement object, then you can use Oracle extensions as follows:
■ You can use getBLOB() and getCLOB(), which return oracle.sql.BLOB and
CLOB objects, respectively.
■ You can also use the getOracleObject() method, which returns an
oracle.sql.Datum object, and cast the output appropriately.
Example: Getting BLOB and CLOB Locators from a Result Set Assume the database has a
table called lob_table with a column for a BLOB locator, blob_col, and a column
for a CLOB locator, clob_col. This example assumes that you have already created
the Statement object, stmt.
First, select the LOB locators into a standard result set, then get the LOB data into
appropriate Java classes:
// Select LOB locator into standard result set.
ResultSet rs =
stmt.executeQuery ("SELECT blob_col, clob_col FROM lob_table");
while (rs.next())
{
// Get LOB locators into Java wrapper classes.
java.sql.Blob blob = (java.sql.Blob)rs.getObject(1);
java.sql.Clob clob = (java.sql.Clob)rs.getObject(2);
(...process...)
}
The output is cast to java.sql.Blob and Clob. As an alternative, you can cast the
output to oracle.sql.BLOB and CLOB to take advantage of extended functionality
offered by the oracle.sql.* classes. For example, you can rewrite the above code to
get the LOB locators as:
// Get LOB locators into Java wrapper classes.
oracle.sql.BLOB blob = (BLOB)rs.getObject(1);
oracle.sql.CLOB clob = (CLOB)rs.getObject(2);
(...process...)
Example: Getting a CLOB Locator from a Callable Statement The callable statement methods
for retrieving LOBs are identical to the result set methods.
For example, if you have an OracleCallableStatement ocs that calls a function
func that has a CLOB output parameter, then set up the callable statement as in the
following example.
This example registers OracleTypes.CLOB as the typecode of the output parameter.
OracleCallableStatement ocs =
(OracleCallableStatement)conn.prepareCall("{? = call func()}");
ocs.registerOutParameter(1, OracleTypes.CLOB);
ocs.execute();
oracle.sql.CLOB clob = ocs.getCLOB(1);
To read and write LOB data, you can use these methods:
■ To read from a BLOB, use the setBinaryStream() method of an
oracle.sql.BLOB object to retrieve the entire BLOB as an input stream. This
returns a java.io.InputStream object.
As with any InputStream object, use one of the overloaded read() methods to
read the LOB data, and use the close() method when you finish.
■ To write to a BLOB, use the setBinaryStream() method of an
oracle.sql.BLOB object to retrieve the BLOB as an output stream. This returns
a java.io.OutputStream object to be written back to the BLOB.
As with any OutputStream object, use one of the overloaded write() methods
to update the LOB data, and use the close() method when you finish.
■ To read from a CLOB, use the getAsciiStream() or getCharacterStream()
method of an oracle.sql.CLOB object to retrieve the entire CLOB as an input
stream. The getAsciiStream() method returns an ASCII input stream in a
java.io.InputStream object. The getCharacterStream() method returns a
Unicode input stream in a java.io.Reader object.
As with any InputStream or Reader object, use one of the overloaded read()
methods to read the LOB data, and use the close() method when you finish.
You can also use the getSubString() method of oracle.sql.CLOB object to
retrieve a subset of the CLOB as a character string of type java.lang.String.
■ To write to a CLOB, use the setAsciiStream() or setCharacterStream()
method of an oracle.sql.CLOB object to retrieve the CLOB as an output stream
to be written back to the CLOB. The setAsciiStream() method returns an
ASCII output stream in a java.io.OutputStream object. The
setCharacterStream() method returns a Unicode output stream in a
java.io.Writer object.
As with any Stream or Writer object, use one of the overloaded write()
methods to update the LOB data, and use the flush() and close() methods
when you finish.
Notes:
■ The stream "write" methods described in this section write
directly to the database when you write to the output stream.
You do not need to execute an UPDATE to write the data. CLOBs
and BLOBs are transaction controlled. After writing to either,
you must commit the transaction for the changes to be
permanent. BFILEs are not transaction controlled. Once you
write to them the changes are permanent, even if the
transaction is rolled back, unless the external file system does
something else.
■ When writing to or reading from a CLOB, the JDBC drivers
perform all character set conversions for you.
The next example reads a vector of data into a byte array, then uses the
setAsciiStream() method to write the array of ASCII data to a CLOB. Because
setAsciiStream() returns an ASCII output stream, you must cast the output to a
oracle.sql.CLOB datatype.
java.io.OutputStream out;
Create a BLOB or CLOB column in a table with the SQL CREATE TABLE statement,
then populate the LOB. This includes creating the LOB entry in the table, obtaining the
LOB locator, creating a file handler for the data (if you are reading the data from a file),
and then copying the data into the LOB.
In this example, the VARCHAR2 column designates a row number, such as 1 or 2, and
the BLOB column stores the locator of the BLOB data.
3. Declare a file handler for the john.gif file, then print the length of the file. This
value will be used later to ensure that the entire file is read into the BLOB. Next,
create a FileInputStream object to read the contents of the GIF file, and an
OutputStream object to retrieve the BLOB as a stream.
File binaryFile = new File("john.gif");
System.out.println("john.gif length = " + binaryFile.length());
FileInputStream instream = new FileInputStream(binaryFile);
OutputStream outstream = blob.setBinaryStream(1L);
5. Use the read() method to read the GIF file to the byte array buffer, then use
the write() method to write it to the BLOB. When you finish, close the input and
output streams.
while ((length = instream.read(buffer)) != -1)
outstream.write(buffer, 0, length);
instream.close();
outstream.close();
Once your data is in the BLOB or CLOB, you can manipulate the data. This is
described in the next section, "Accessing and Manipulating BLOB and CLOB Data".
retrieve the data in oracle.sql.* format. After retrieving the BLOB or CLOB data,
you can manipulate it however you want.
This example is a continuation of the example in the previous section. It uses the SQL
SELECT statement to select the BLOB locator from the table my_blob_table into a
result set. The result of the data manipulation is to print the length of the BLOB in
bytes.
// Select the blob - what we are really doing here
// is getting the blob locator into a result set
BLOB blob;
cmd = "SELECT * FROM my_blob_table";
ResultSet rset = stmt.executeQuery (cmd);
A JDBC driver creates an empty LOB instance without making database round trips.
You can use empty LOBs in the following:
■ setXXX() methods of the OraclePreparedStatement class
■ updateXXX() methods of updatable result sets
■ attributes of STRUCT objects
■ elements of ARRAY objects
pstmt.execute();
The string data is transferred to the database and automatically transformed into a
CLOB which is inserted into the column.
In 10g Release 1 (10.1) an additional method, pstmt(), is added to
OraclePreparedStatement.
OraclePreparedStatement pstmt = (OraclePreparedStatement)(conn.pstmt(
"INSERT INTO MY_CLOB_TAB VALUES ( ? )" ));
pstmt.execute();
In addition, there is a connection property SetBigStringUseClob. Setting this
property forces PreparedStatement.setString() method to use
setStringForClob() if the data is larger than 32765 bytes. Please note that using
this method with VARCHAR and LONG columns may cause large data to be truncated
silently, or cause other errors differing from the normal behavior of setString().
You can use getString() to read a CLOB column.
For both of these operations, the only limit on the size of the string is the limit imposed
by Java Language itself, which is that the length must be a positive Java int. Note,
however, that if the data is extremely large it is may not be wise to handle it this way.
Please read the information provided by your Java Virtual Machine vendor about the
impact of very large data elements on memory management, and consider using the
stream interfaces instead.
CLOB and BLOB data may also be read and written using the same streaming
mechanism as for LONG and LONG RAW data. To read, use
defineColumnType(nn, Types.LONGVARCHAR) or defineColumnType( nn,
Types.LONGVARBINARY) on the column; this produces a direct stream on the data as
Notes:
■ In the OracleResultSet and OracleCallableStatement
classes, getBFILE() and getBfile() both return
oracle.sql.BFILE. There is no java.sql interface for
BFILEs.
■ If using getObject() or getOracleObject(), remember to
cast the output, as necessary. For more information, see
"Datatypes For Returned Objects from getObject and getXXX"
on page 11-8.
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. This
example assumes that you have already created your Statement object stmt.
Select the BFILE locator into a standard result set. If you cast the result set to an
OracleResultSet, you can use getBFILE() to get the BFILE locator:
// Select the BFILE locator into a result set
ResultSet rs = stmt.executeQuery("SELECT bfile_col FROM bfile_table");
while (rs.next())
{
oracle.sql.BFILE my_bfile = ((OracleResultSet)rs).getBFILE(1);
}
Note that as an alternative, you can use getObject() to return the BFILE locator. In
this case, because getObject() returns a java.lang.Object, cast the results to
BFILE. For example:
oracle.sql.BFILE my_bfile = (BFILE)rs.getObject(1);
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. The following code example sets up the callable statement, registers
the output parameter as OracleTypes.BFILE, executes the statement, and retrieves
the BFILE locator:
OracleCallableStatement ocs =
(OracleCallableStatement)conn.prepareCall("{? = call func()}");
ocs.registerOutParameter(1, OracleTypes.BFILE);
ocs.execute();
oracle.sql.BFILE bfile = ocs.getBFILE(1);
Example: Passing a BFILE Locator to a Prepared Statement Assume you want to insert a
BFILE locator into a table, and you have an OraclePreparedStatement object ops
to insert data into a table. The first column is a string (to designate a row number), the
second column is a BFILE, and you have a valid oracle.sql.BFILE object (bfile).
Write the BFILE to the database as follows:
OraclePreparedStatement ops = (OraclePreparedStatement)conn.prepareStatement
("INSERT INTO my_bfile_table VALUES (?,?)");
ops.setString(1,"one");
ops.setBFILE(2, bfile);
ops.execute();
Once you obtain the locator, you can invoke a number of methods on the BFILE
without opening it. For example, you can use the oracle.sql.BFILE methods
fileExists() and isFileOpen() to determine whether the BFILE exists and if it is
open. If you want to read and manipulate the data, however, you must open and close
the BFILE, as follows:
■ Use the openFile() method of the oracle.sql.BFILE class to open a BFILE.
■ When you are done, use the closeFile() method of the BFILE class.
BFILE data is materialized as a Java stream. To read from a BFILE, use the
getBinaryStream() method of an oracle.sql.BFILE object to retrieve the entire
file as an input stream. This returns a java.io.InputStream object.
As with any InputStream object, use one of the overloaded read() methods to read
the file data, and use the close() method when you finish.
Notes:
■ BFILEs are read-only. You cannot insert data or otherwise write
to a BFILE.
■ You cannot use JDBC to create a new BFILE. They are created
only externally.
Use the SQL CREATE TABLE statement to create a table containing a BFILE column,
then execute the statement. In this example, the name of the table is my_bfile_
table.
In this example, the VARCHAR2 column designates a row number, and the BFILE
column stores the locator of the BFILE data.
In this example, the name of the directory alias is test_dir. The locator of the BFILE
file1.data is loaded into the BFILE column on row one, and the locator of the
BFILE jdbcTest.data is loaded into the bfile column on row two.
As an alternative, you might want to create the row for the row number and BFILE
locator now, but wait until later to insert the locator. In this case, 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', null)";
stmt.execute(cmd);
Here, three is inserted into the row number column, and null is inserted as the
place holder. Later in your program, insert the BFILE locator into the table by using a
prepared statement.
First get a valid BFILE locator into the bfile object:
rs = stmt.executeQuery("SELECT b FROM my_bfile_table WHERE x='two'");
rs.next();
oracle.sql.BFILE bfile = ((OracleResultSet)rs).getBFILE(1);
Then, create your prepared statement. Note that because this example uses the
setBFILE() method to identify the BFILE, the prepared statement must be cast to an
OraclePreparedStatement:
OraclePreparedStatement ops = (OraclePreparedStatement)conn.prepareStatement
(UPDATE my_bfile_table SET b=? WHERE x = 'three');
ops.setBFILE(1, bfile);
ops.execute();
Now row two and row three contain the same BFILE.
Once you have the BFILE locators available in a table, you can access and manipulate
the BFILE data. The next section, "Accessing and Manipulating BFILE Data", describes
this.
if (rset.next ())
BFILE bfile = ((OracleResultSet)rset).getBFILE (2);
This chapter describes Oracle extensions to standard JDBC that let you access and
manipulate object references. 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
For more information about custom reference classes, see "Custom Reference Classes
with JPublisher" on page 15-5.
Notes:
■ If you are using the oracle.sql.ORAData interface for
custom object classes, you will presumably use ORAData for
corresponding custom reference classes as well. If you are using
the standard java.sql.SQLData interface for custom object
classes, however, you can only use weak Java types for
references (java.sql.Ref or oracle.sql.REF). The
SQLData interface is for mapping SQL object types only.
■ You cannot create REF objects in your JDBC application; you
can only retrieve existing REF objects from the database.
■ You cannot have a reference to an array, even though arrays,
like objects, are structured types.
The ADDRESS object type has two attributes: a street name and a house number. The
PEOPLE table has three columns: a column for character data, a column for numeric
data, and a column containing a reference to an ADDRESS object.
To retrieve an object reference, follow these general steps:
1. Use a standard SQL SELECT statement to retrieve the reference from a database
table REF column.
2. Use getREF() to get the address reference from the result set into a REF object.
3. Let Address be the Java custom class corresponding to the SQL object type
ADDRESS.
4. Add the correspondence between the Java class Address and the SQL type
ADDRESS to your type map.
5. Use the getValue() method to retrieve the contents of the Address reference.
Cast the output to a Java Address object.
Here is the code for these steps (other than adding Address to the type map), where
stmt is a previously defined statement object. The PEOPLE database table is defined
earlier in this section:
As with other SQL types, you could retrieve the reference with the getObject()
method of your result set. Note that this would require you to cast the output. For
example:
REF ref = (REF)rs.getObject(1);
Where param_index is the parameter index and sql_type is the SQL typecode
(in this case, OracleTypes.REF). The sql_type_name is the name of the
structured object type that this reference is used for. For example, if the OUT
parameter is a reference to an ADDRESS object (as in "Retrieving and Passing an
Object Reference" on page 15-3), then ADDRESS is the sql_type_name that
should be passed in.
3. Execute the call:
ocs.execute();
Then, you can create a Java Address object (this example omits the content for the
constructor of the Address class) that corresponds to the database ADDRESS object.
Use the setValue() method of the REF class to set the value of the database object:
Address addr = new Address(...);
ref.setValue(addr);
Here, the setValue() method updates the database ADDRESS object immediately.
This chapter describes Oracle extensions to standard JDBC that let you access and
manipulate Oracle collections, which map to Java arrays, and their data. The following
topics are discussed:
■ Oracle Extensions for Collections (Arrays)
■ Overview of Collection (Array) Functionality
■ ARRAY Performance Extension Methods
■ Creating and Using Arrays
■ Using a Type Map to Map Array Elements
■ Custom Collection Classes with JPublisher
For more information about custom collection classes, see "Custom Collection Classes
with JPublisher" on page 16-18.
Creating Collections
This section presents background information about creating Oracle collections.
Because Oracle supports only named collections, you must declare a particular
VARRAY type name or nested table type name. "VARRAY" and "nested table" are not
types themselves, but categories of types.
A SQL type name is assigned to a collection when you create it, as in the following
SQL syntax:
CREATE TYPE <sql_type_name> AS <datatype>;
A VARRAY is an array of varying size. It has an ordered set of data elements, and all
the elements are of the same datatype. Each element has an index, which is a number
corresponding to the element's position in the VARRAY. The number of elements in a
VARRAY is the "size" of the VARRAY. You must specify a maximum size when you
declare the VARRAY type. For example:
CREATE TYPE myNumType AS VARRAY(10) OF NUMBER;
This statement defines myNumType as a SQL type name that describes a VARRAY of
NUMBER values that can contain no more than 10-elements.
A nested table is an unordered set of data elements, all of the same datatype. The
database stores a nested table in a separate table which has a single column, and the
type of that column is a built-in type or an object type. If the table is an object type, it
can also be viewed as a multi-column table, with a column for each attribute of the
object type. Create a nested table with this SQL syntax:
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.
Once the multi-level collection types have been created, they can be used as both
columns of a base table as well as attributes of a object type.
See the Oracle Database Application Developer's Guide - Object-Relational Features for the
SQL syntax to create multi-level collections types and how to specify the storage tables
for inner collections.
ARRAY Descriptors
Creating and using an ARRAY object requires the existence of a descriptor—an instance
of the oracle.sql.ArrayDescriptor class—to exist for the SQL type of the
collection being materialized in the array. You need only one ArrayDescriptor
object for any number of ARRAY objects that correspond to the same SQL type.
ARRAY descriptors are further discussed in "Creating ARRAY Objects and Descriptors"
on page 16-8.
When you enable auto-buffering, the oracle.sql.ARRAY object keeps a local copy of
all the converted elements. This data is retained so that a second access of this
information does not require going through the data format conversion process.
Where NUM_VARRAY is the SQL type name for the collection type.
Note: The name of the collection type is not the same as the type
name of the elements. For example:
CREATE TYPE person AS object
(c1 NUMBER(5), c2 VARCHAR2(30));
CREATE TYPE array_of_persons AS varray(10)
OF person;
In the preceding statements, the SQL name of the collection type is
ARRAY_OF_PERSON. The SQL name of the collection elements is
PERSON.
Before you can construct an Array object, an ArrayDescriptor must first exist for
the given SQL type of the array. If an ArrayDescriptor does not exist, then you
must construct one by passing the SQL type name of the collection type and your
Connection object (which JDBC uses to go to the database to gather meta data) to the
constructor.
ArrayDescriptor arraydesc = ArrayDescriptor.createDescriptor
(sql_type_name, connection);
where sql_type_name is the type name of the array and connection is your
Connection object.
Once you have your ArrayDescriptor object for the SQL type of the array, you can
construct the ARRAY object. To do this, pass in the array descriptor, your connection
object, and a Java object containing the individual elements you want the array to
contain.
ARRAY array = new ARRAY(arraydesc, connection, elements);
// some operations
...
In the above example, another implementation is to prepare the elems as a Java array
of oracle.sql.ARRAY[] elements, and each oracle.sql.ARRAY[] element
represents a SCOTT.VARRAY3.
Note: The JDBC driver does not verify that the connection object
from the setConnection() method connects to the same
database from which the type descriptor was initially derived.
getArray() The getArray() method is a standard JDBC method that returns the array
elements into a java.lang.Object instance that you can cast as appropriate (see
"Comparing the Data Retrieval Methods" on page 16-12). The elements are converted
to the Java types corresponding to the SQL type of the data in the original array.
Oracle also provides a getArray(index,count) method to retrieve a subset of the
array elements.
In this case, the result set contains one row for each array element, with two columns
in each row. The first column stores the index into the array; the second column stores
the element value.
If you use getArray() to retrieve an array of primitive datatypes, then a
java.lang.Object that contains the element values is returned. The elements of
this array are of the Java type corresponding to the SQL type of the elements. For
example:
BigDecimal[] values = (BigDecimal[]) intArray.getArray();
Where arr is an oracle.sql.ARRAY object, index is type long, count is type int,
and map is a java.util.Map object.
Note that if you use getResultSet() to obtain the array, you would first get the
result set object, then use the next() method to iterate through it. Notice the use of
the parameter indexes in the getInt() method to retrieve the element index and the
element value.
ResultSet rset = my_array.getResultSet();
while (rset.next())
{
// The first column contains the element index and the
// second column contains the element value
System.out.println(">> index " + rset.getInt(1)+" = " + rset.getInt(2));
}
while (rset.next())
{
ARRAY varray3 = (ARRAY) rset.getObject (1);
Object varrayElems = varray3.getArray (1);
// access array elements of "varray3"
Datum[] varray3Elems = (Datum[]) varrayElems;
while (varray1Elems.next())
System.out.println ("idx="+varray1Elems.getInt(1)+"
value="+varray1Elems.getInt(2));
}
}
}
rset.close ();
stmt.close ();
conn.close ();
Where param_index is the parameter index, sql_type is the SQL typecode, and
sql_type_name is the name of the array type. In this case, the sql_type is
OracleTypes.ARRAY.
3. Execute the call:
ocs.execute();
If you want to retrieve all the employees belonging to the SALES department into an
array of instances of the custom object class EmployeeObj, then you must add an
entry to the type map to specify mapping between the EMPLOYEE SQL type and the
EmployeeObj custom object class.
To do this, first create your statement and result set objects, then select the EMPLOYEE_
LIST associated with the SALES department into the result set. 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 example below).
The EmployeeObj custom object class in this example implements the SQLData
interface.
Statement s = conn.createStatement();
OracleResultSet rs = (OracleResultSet)s.executeQuery
("SELECT Employees FROM employee_table WHERE DeptName = 'SALES'");
Now that you have the EMPLOYEE_LIST object, get the existing type map and add an
entry that maps the EMPLOYEE SQL type to the EmployeeObj Java type.
// add type map entry to map SQL type
// "EMPLOYEE" to Java type "EmployeeObj"
Map map = conn.getTypeMap();
map.put("EMPLOYEE", Class.forName("EmployeeObj"));
Next, retrieve the SQL EMPLOYEE objects from the EMPLOYEE_LIST. To do this,
invoke the getArray() method of the employeeArray array object. This method
returns an array of objects. The getArray() method returns the EMPLOYEE objects
into the employees object array.
// Retrieve array elements
Object[] employees = (Object[]) employeeArray.getArray();
Finally, create a loop to assign each of the EMPLOYEE SQL objects to the EmployeeObj
Java object emp.
// Each array element is mapped to EmployeeObj object.
for (int i=0; i<employees.length; i++)
{
EmployeeObj emp = (EmployeeObj) employees[i];
...
}
■ They are strongly typed. This can help you find coding errors during compilation
that might not otherwise be discovered until runtime.
■ They can be changeable, or mutable. Custom collection classes produced by
JPublisher, unlike the ARRAY class, allow you to get and set individual elements
using the getElement() and setElement() methods. (This is also something
you could implement in a custom collection class yourself.)
A custom collection class must satisfy three requirements:
■ It must implement the oracle.sql.ORAData interface described under
"Creating and Using Custom Object Classes for Oracle Objects" on page 13-7. Note
that the standard JDBC SQLData interface, which is an alternative for custom
object classes, is not intended for custom collection classes.
■ It, or a companion class, must implement the oracle.sql.ORADataFactory
interface, for creating instances of the custom collection class.
■ It must have a means of storing the collection data. Typically it will directly or
indirectly include an oracle.sql.ARRAY attribute for this purpose (this is the
case with a JPublisher-produced custom collection class).
A JPublisher-generated custom collection class implements ORAData and
ORADataFactory and indirectly includes an oracle.sql.ARRAY attribute. The
custom collection class will have an oracle.jpub.runtime.MutableArray
attribute. The MutableArray class has an oracle.sql.ARRAY attribute.
Standard JDBC 2.0 features in JDK 1.2.x include enhancements to result set
functionality—processing forward or backward, positioning relatively or absolutely,
seeing changes to the database made internally or externally, and updating result set
data and then copying the changes to the database.
This chapter discusses these features, including the following topics:
■ Overview
■ 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
■ Summary of New Methods for Result Set Enhancements
For more general and conceptual information about JDBC 2.0 result set enhancements,
refer to the Sun Microsystems JDBC 2.0 API specification.
Overview
This section provides an overview of JDBC 2.0 result set functionality and categories,
and some discussion of implementation requirements for the Oracle JDBC drivers.
Result Set Functionality and Result Set Categories Supported in JDBC 2.0
Result set functionality in JDBC 2.0 includes enhancements for scrollability and
positioning, sensitivity to changes by others, and updatability.
■ Scrollability, positioning, and sensitivity are determined by the result set type.
■ Updatability is determined by the concurrency type.
Specify the desired result set type and concurrency type when you create the
statement object that will produce the result set.
Together, the various result set types and concurrency types provide for six different
categories of result set.
This section provides an overview of these enhancements, types, and categories.
Updatability
Updatability refers to the ability to update data in a result set and then (presumably)
copy the changes to the database. This includes inserting new rows into the result set
or deleting existing rows.
Updatability might also require database write locks to mediate access to the
underlying database. Because you cannot have multiple write locks concurrently,
updatability in a result set is associated with concurrency in database access.
Result sets can optionally be updatable under JDBC 2.0
Important: Because all rows of any scrollable result set are stored
in the client-side cache, a situation where the result set contains
many rows, many columns, or very large columns might cause the
client-side Java virtual machine to fail. Do not specify scrollability for
a large result set.
Scrollable cursors in the Oracle server, and therefore a server-side cache, will be
supported in a future Oracle release.
/**
* Return the data stored in the i-th row and j-th column.
*/
public Object get (int i, int j) throws IOException;
/**
* Remove the i-th row.
*/
public void remove (int i) throws IOException;
/**
* Remove the data stored in i-th row and j-th column
*/
public void remove (int i, int j) throws IOException;
/**
* Remove all data from the cache.
*/
public void clear () throws IOException;
/**
* Close the cache.
*/
public void close () throws IOException;
}
If you implement this interface with your own class, your application code must
instantiate your class and then use the setResultSetCache() method of an
OracleStatement, OraclePreparedStatement, or
OracleCallableStatement object to set the caching mechanism to use your
implementation. Following is the method signature:
■ void setResultSetCache(OracleResultSetCache cache)
throws SQLException
Call this method prior to executing a query. The result set produced by the query will
then use your specified caching mechanism.
The statement objects created will have the intelligence to produce the appropriate
kind of result sets.
You can specify one of the following static constant values for result set type:
■ ResultSet.TYPE_FORWARD_ONLY
■ ResultSet.TYPE_SCROLL_INSENSITIVE
■ ResultSet.TYPE_SCROLL_SENSITIVE
And you can specify one of the following static constant values for concurrency type:
■ ResultSet.CONCUR_READ_ONLY
■ ResultSet.CONCUR_UPDATABLE
After creating a Statement, PreparedStatement, or CallableStatement object,
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
pstmt.setString(1, "28959");
ResultSet rs = pstmt.executeQuery();
...
Workaround As a workaround for the "SELECT *" limitation, you can use table aliases
as in the following example:
SELECT t.* FROM TABLE t ...
Notes:
■ Criteria that would prevent the JDBC driver from fulfilling the
result set type specifications are listed in "Result Set
Limitations" on page 17-6.
■ Any manipulations of the result set type and concurrency type
by the JDBC driver are independent of each other.
beforeFirst() Method Positions to before the first row of the result set, or has no effect if
there are no rows in the result set.
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.
You are outside the result set bounds after a beforeFirst() call. There is no valid
current row, and you cannot position relatively from this point.
afterLast() Method Positions to after the last row of the result set, or has no effect if there
are no rows in the result set.
This is where you would typically start iterating through a result set to process it going
backward.
You are outside the result set bounds after an afterLast() call. There is no valid
current row, and you cannot position relatively from this point.
first() Method Positions to the first row of the result set, or returns false if there are no
rows in the result set.
last() Method Positions to the last row of the result set, or returns false if there are no
rows in the result set.
absolute() Method Positions to an absolute row from either the beginning or end of the
result set. If you input a positive number, it positions from the beginning; if you input
a negative number, it positions from the end. This method returns false if there are
no rows in the result set.
Attempting to move forward beyond the last row, such as an absolute(11) call if
there are 10 rows, will position to after the last row, having the same effect as an
afterLast() call.
Attempting to move backward beyond the first row, such as an absolute(-11) call
if there are 10 rows, will position to before the first row, having the same effect as a
beforeFirst() call.
relative() Method Moves to a position relative to the current row, either forward if you
input a positive number or backward if you input a negative number, or returns
false if there are no rows in the result set.
The result set must be at a valid current row for use of the relative() method.
Attempting to move forward beyond the last row will position to after the last row,
having the same effect as an afterLast() call.
Attempting to move backward beyond the first row will position to before the first
row, having the same effect as a beforeFirst() call.
A relative(0) call is valid but has no effect.
Important: You cannot position relatively from before the first row
(which is the default initial position) or after the last row.
Attempting relative positioning from either of these positions
would result in a SQLException.
rs.afterLast();
while (rs.previous())
{
System.out.println(rs.getString("empno") + " " + rs.getFloat("sal"));
}
...
Unlike relative positioning, you can (and typically do) use next() from before the
first row and previous() from after the last row. You do not have to be at a valid
current row to use these methods.
Note: In a non-scrollable result set, you can process only with the
next() method. Attempting to use the previous() method will
cause a SQLException.
Presuming the result set is also scrollable, you can position to a row using any of the
available positioning methods (except beforeFirst() and afterLast(), which do
not go to a valid current row), and then delete that row, as in the following example
(presuming a result set rs):
...
rs.absolute(5);
rs.deleteRow();
...
See "Positioning in a Scrollable Result Set" on page 17-8 for information about the
positioning methods.
Important: The deleted row remains in the result set object even
after it has been deleted from the database.
In a scrollable result set, by contrast, a DELETE operation is evident
in the local result set object—the row would no longer be in the
result set after the DELETE. The row preceding the deleted row
becomes the current row, and row numbers of subsequent rows are
changed accordingly.
Refer to "Seeing Internal Changes" on page 17-18 for more
information.
With JDBC 2.0, a result set object has an updateXXX() method for each datatype,
as with the setXXX() methods previously available for updating the database
directly.
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 datatype to set the new value.
Following are a couple of examples for a result set rs:
rs.updateString(1, "mystring");
rs.updateFloat(2, 10000.0f);
2. Call the updateRow() method to copy the changes to the database (or the
cancelRowUpdates() method to cancel the changes).
Once you call updateRow(), the changes are executed and will be made
permanent with the next transaction COMMIT operation. Be aware that by default,
the auto-commit flag is set to true so that any executed operation is committed
immediately.
If you choose to cancel the changes before copying them to the database, call the
cancelRowUpdates() method instead. This will also revert to the original
values for that row in the local result set object. Note that once you call the
updateRow() method, the changes are written to the transaction and cannot be
canceled unless you roll back the transaction (auto-commit must be disabled to
allow a ROLLBACK operation).
Positioning to a different row before calling updateRow() also cancels the
changes and reverts to the original values in the result set.
Before calling updateRow(), you can call the usual getXXX() methods to verify
that the values have been updated correctly. These methods take an int column
index or string column name as input. For example:
float myfloat = rs.getFloat(2);
...process myfloat to see if it's appropriate...
Note: Result set UPDATE operations are visible in the local result
set object for all result set types (forward-only, scroll-sensitive, and
scroll-insensitive).
Refer to "Seeing Internal Changes" on page 17-18 for more
information.
Example
Following is an example of a result set UPDATE operation that is also copied to the
database. The tenth row is updated. (The column number is used to specify column 1,
and the column name—sal— is used to specify column 2.)
Statement stmt = conn.createStatement
(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery("SELECT empno, sal FROM emp");
if (rs.absolute(10)) // (returns false if row does not exist)
{
rs.updateString(1, "28959");
rs.updateFloat("sal", 100000.0f);
rs.updateRow();
}
// Changes are made permanent with the next COMMIT operation.
Note: The result set will remember the current position prior to
the moveToInsertRow() call. Afterward, you can go back to it
with a moveToCurrentRow() call.
(Note that you can specify a string for column name, instead of an integer for
column number.)
3. Copy the changes to the database by calling the result set insertRow() method.
Once you call insertRow(), the insert is executed and will be made permanent
with the next transaction COMMIT operation.
Positioning to a different row before calling insertRow() cancels the insert and
clears the insert-row.
Before calling insertRow() you can call the usual getXXX() methods to verify
that the values have been set correctly in the insert-row. These methods take an
int column index or string column name as input. For example:
float myfloat = rs.getFloat(2);
...process myfloat to see if it's appropriate...
Example
The following example performs a result set INSERT operation, moving to the
insert-row, writing the data, copying the data into the database, and then returning to
what was the current row prior to going to the insert-row. (The column number is used
to specify column 1, and the column name—sal— is used to specify column 2.)
...
Statement stmt = conn.createStatement
(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
rs.moveToInsertRow();
rs.updateString(1, "28959");
rs.updateFloat("sal", 100000.0f);
rs.insertRow();
// Changes will be made permanent with the next COMMIT operation.
rs.moveToCurrentRow(); // Go back to where we came from...
...
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.
■ The drivers do not check for conflicts with a result set DELETE or UPDATE
operation.
A conflict will occur if you try to perform a DELETE or UPDATE operation on a row
updated by another committed transaction.
The Oracle JDBC drivers use the ROWID to uniquely identify a row in a database
table. As long as the ROWID is still valid when a driver tries to send an UPDATE or
DELETE operation to the database, the operation will be executed.
The driver will not report any changes made by another committed transaction. Any
conflicts are silently ignored and your changes will overwrite the previous changes.
To avoid such conflicts, use the Oracle FOR UPDATE feature when executing the query
that produces the result set. This will avoid conflicts, but will also prevent
simultaneous access to the data. Only a single write lock can be held concurrently on a
data item.
Fetch Size
By default, when Oracle JDBC executes a query, it receives the result set 10 rows at a
time from the database cursor. This is the default Oracle row-prefetch value. You can
change the number of rows retrieved with each trip to the database cursor by changing
the row-prefetch value (see "Oracle Row Prefetching" on page 22-15 for more
information).
JDBC 2.0 also allows you to specify the number of rows fetched with each database
round trip for a query, and this number is referred to as the fetch size. In Oracle JDBC,
the row-prefetch value is used as the default fetch size in a statement object. Setting
the fetch size overrides the row-prefetch setting and affects subsequent queries
executed through that statement object.
Fetch size is also used in a result set. When the statement object executes a query, the
fetch size of the statement object is passed to the result set object produced by the
query. However, you can also set the fetch size in the result set object to override the
statement fetch size that was passed to it. (Also note that changes made to a statement
object's fetch size after a result set is produced will have no affect on that result set.)
The result set fetch size, either set explicitly, or by default equal to the statement fetch
size that was passed to it, determines the number of rows that are retrieved in any
subsequent trips to the database for that result set. This includes any trips that are still
required to complete the original query, as well as any refetching of data into the result
set. (Data can be refetched, either explicitly or implicitly, to update a scroll-sensitive or
scroll-insensitive/updatable result set. See "Refetching Rows" on page 17-16.)
Note: Do not mix the JDBC 2.0 fetch size API and the Oracle row
prefetching API in your application. You can use one or the other,
but not both.
Refetching Rows
The result set refreshRow() method is supported for some types of result sets for
refetching data. This consists of going back to the database to re-obtain the database
rows that correspond to N rows in the result set, starting with the current row, where
N is the fetch size (described above in "Fetch Size" on page 17-15). This lets you see the
latest updates to the database that were made outside of your result set, subject to the
isolation level of the enclosing transaction.
Because refetching re-obtains only rows that correspond to rows already in your result
set, it does nothing about rows that have been inserted or deleted in the database since
the original query. 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.
When there is an attempt to refetch a row that has been deleted in the database, the
corresponding row in the result set will maintain its original values.
Following is the refreshRow() method signature:
■ void refreshRow() throws SQLException
You must be at a valid current row when you call this method, not outside the row
bounds and not at the insert-row.
The refreshRow() method is supported for the following result set categories:
■ scroll-sensitive/read-only
■ scroll-sensitive/updatable
■ scroll-insensitive/updatable
Oracle JDBC might support additional result set categories in future releases.
For implementation details of scroll-sensitive result sets, including exactly how and
how soon external updates become visible, see "Oracle Implementation of
Scroll-Sensitive Result Sets" on page 17-20.
JDBC 2.0 DatabaseMetaData objects include the following methods to verify this.
Each takes a result set type as input (ResultSet.TYPE_FORWARD_ONLY,
ResultSet.TYPE_SCROLL_SENSITIVE, or ResultSet.TYPE_SCROLL_
INSENSITIVE).
Table 17–1 Visibility of Internal and External Changes for Oracle JDBC
Can See Can See Can See Can See Can See Can See
Internal Internal Internal External External External
Result Set Type DELETE? UPDATE? INSERT? DELETE? UPDATE? INSERT?
forward-only no yes no no no no
scroll-sensitive yes yes no no yes no
scroll-insensitive yes yes no no no no
For implementation details of scroll-sensitive result sets, including exactly how and
how soon external updates become visible, see "Oracle Implementation of
Scroll-Sensitive Result Sets" on page 17-20.
Notes:
■ Remember that explicit use of the refreshRow() method,
described in "Refetching Rows" on page 17-16, is distinct from
the concept of "visibility" of external changes. This is discussed
in "Seeing External Changes" on page 17-18.
■ Remember that even when external changes are "visible", as
with UPDATE operations underlying a scroll-sensitive result set,
they are not "detected". The result set rowDeleted(),
rowUpdated(), and rowInserted() methods always return
false. This is further discussed in "Visibility versus Detection
of External Changes" on page 17-19.
So external updates are not instantaneously visible in a scroll-sensitive result set; they
are only visible after the automatic refetches just described.
Statement Methods
Following is an alphabetical summary of statement methods for JDBC 2.0 result set
enhancements. These methods are available in generic statement, prepared statement,
and callable statement objects.
■ int getFetchSize() throws SQLException
Check the fetch size to determine how many rows are fetched in each database
round trip when executing a query (also available in result set objects).
■ void setFetchSize(int rows) throws SQLException
Set the fetch size to determine how many rows are fetched in each database round
trip when executing a query (also available in result set objects).
■ void setResultSetCache(OracleResultSetCache cache)
throws SQLException
Use your own client-side cache implementation for scrollable result sets. Create
your own class that implements the OracleResultSetCache interface, then use
the setResultSetCache() method to input an instance of this class to the
statement object that will create the result set.
■ int getResultSetType() throws SQLException
Check the result set type of result sets produced by this statement object (which
was specified when the statement object was created).
■ int getResultSetConcurrency() throws SQLException
Check the concurrency type of result sets produced by this statement object (which
was specified when the statement object was created).
Introduction
A row set is an object which encapsulates a set of rows. These rows are accessible
though the javax.sql.RowSet interface. This interface supports component models
of development, like JavaBeans, and is part of JDBC optional package by JavaSoft.
Three kinds of row set are supported by JavaSoft:
■ Cached row set
■ JDBC row set
■ Web row set
As of 10g Release 1 (10.1), the Oracle JDBC drivers now support Web row set.
The RowSet interface provides a set of properties which can be altered to access the
data in the database through a single interface. It supports properties and events
which forms the core of JavaBeans. It has various properties like connect string, user
name, password, type of connection, the query string itself, and also the parameters
passed to the query. The following code executes a simple query:
...
rowset.setUrl ("jdbc:oracle:oci:@");
rowset.setUsername ("SCOTT");
rowset.setPassword ("TIGER");
rowset.setCommand (
"SELECT empno, ename, sal FROM emp WHERE empno = ?");
In this example, the URL, user name, password, SQL query, and bind parameter
required for the query are set as the command properties to retrieve the employee
name and salary. Also, the row set would contain empno, ename, and sal for the
employee with the empno as 7839 and whose name is KING.
This might also be set in the project properties in case you are using an IDE like
JDeveloper.
Oracle row set implementations are in the oracle.jdbc.rowset package. Import
this package to use any of the Oracle row set implementations.
OracleCachedRowSet, OracleJDBCRowSet, and OracleWebRowset classes all
implement the javax.sql.RowSet interface, which extends
java.sql.ResultSet. Row set not only provides the interfaces of result set, but also
some of the properties of the java.sql.Connection and
java.sql.PreparedStatement interfaces. Connections and prepared statements
are totally abstracted by this interface. Both OracleCachedRowSet and
OracleWebRowSet are serializable. They implement the java.io.Serializable
interface, which enables them to be moved across the network or JVM sessions.
3. rowsetChanged event : Generated when the whole row set is created or changed
The following code shows the registration of a row set listener:
MyRowSetListener rowsetListener =
new MyRowSetListener ();
// adding a rowset listener.
rowset.addRowSetListener (rowsetListener);
Applications which handle only a few events can implement only the required events
by using the OracleRowSetAdapter class, which is an abstract class with empty
implementation for all the event handling methods.
In the following code, only the rowSetChanged event is handled. The remaining
events are not handled by the application.
rowset.addRowSetListener (new OracleRowSetAdapter ()
{
public void rowSetChanged(RowSetEvent event)
{
// your action for rowsetChanged
}
}
);
rowset.populate (rset);
In the above example, a ResultSet object is obtained by executing a query and the
retrieved ResultSet object is passed to the populate() method of the cached row
set to populate the contents of the result set into cached row set.
All the interfaces provided by the ResultSet interface are implemented in RowSet.
The following code shows how to scroll through a row set:
/**
* Scrolling forward, and printing the empno in
* the order in which it was fetched.
*/
// going to the first row of the rowset
rowset.beforeFirst ();
while (rowset.next ())
System.out.println ("empno: " +rowset.getInt (1));
In the example above, the cursor position is initialized to the position before the first
row of the row set by the beforeFirst() method. The rows are retrieved in forward
direction using the next() method.
/**
* Scrolling backward, and printing the empno in
* the reverse order as it was fetched.
*/
//going to the last row of the rowset
rowset.afterLast ();
while (rowset.previous ())
System.out.println ("empno: " +rowset.getInt (1));
In the above example, the cursor position is initialized to the position after the last row
of the RowSet. The rows are retrieved in reverse direction using the previous()
method of RowSet.
Inserting, updating, and deleting rows are supported by the row set feature as they are
in the result set feature. The following code illustrates the insertion of a row at the fifth
position of a row set:
/**
* Inserting a row in the 5th position of the rowset.
*/
// moving the cursor to the 5th position in the rowset
if (rowset.absolute(5))
{
rowset.moveToInsertRow ();
rowset.updateInt (1, 193);
rowset.updateString (2, "Ashok");
rowset.updateInt (3, 7200);
In the above example, a call to the absolute() method with a parameter 5 takes the
cursor to the fifth position of the row set and a call to the moveToInsertRow()
method creates a place for the insertion of a new row into the row set. The
updateXXX() methods are used to update the newly created row. When all the
columns of the row are updated, the insertRow() is called to update the row set.
The changes are committed through acceptChanges() method.
The following code shows how an OracleCachedRowSet object is serialized to a file
and then retrieved:
// writing the serialized OracleCachedRowSet object
{
FileOutputStream fileOutputStream =
new FileOutputStream ("emp_tab.dmp");
ObjectOutputStream ostream = new
ObjectOutputStream (fileOutputStream);
ostream.writeObject (rowset);
ostream.close ();
fileOutputStream.close ();
}
environment which does not have JDBC drivers. Committing the data in the row set
(through the acceptChanges() method) requires the presence of JDBC drivers.
The complete process of retrieving the data and populating it in the
OracleCachedRowSet class is performed on the server and the populated row set is
passed on to the client using suitable architectures like RMI or Enterprise Java Beans
(EJB). The client would be able to perform all the operations like retrieving, scrolling,
inserting, updating, and deleting on the row set without any connection to the
database. Whenever data is committed to the database, the acceptChanges()
method is called which synchronizes the data in the row set to that in the database.
This method makes use of JDBC drivers which require the JVM environment to
contain JDBC implementation. This architecture would be suitable for systems
involving a Thin client like a Personal Digital Assistant (PDA) or a Network Computer
(NC).
After populating the CachedRowSet object, it can be used as a ResultSet object or
any other object which can be passed over the network using RMI or any other
suitable architecture.
Some of the other key-features of cached row set are the following:
■ Cloning a row set
■ Creating a copy of a row set
■ Creating a shared copy of a row set
CachedRowSet Constraints
All the constraints which apply to updatable result set are applicable here, except
serialization, since OracleCachedRowSet is serializable. The SQL query has the
following constraints:
■ References only a single table in the database
■ Contain no join operations
■ Selects the primary key of the table it references
In addition, a SQL query should also satisfy the conditions below if inserts are to be
performed:
■ Selects all of the non-nullable columns in the underlying table
■ Selects all columns that do not have a default value
Properties which apply to the connection cannot be set after populating the row set
since the properties cannot be applied to the connection after retrieving the data from
the same like, transaction isolation and concurrency mode of the result set.
The JDBC row set is a connected row set which has a live connection to the database
and all the calls on the JDBC row set are percolated to the mapping call in JDBC
connection, statement, or result set. A cached row set does not have any connection to
the database open.
JDBC row set requires the presence of JDBC drivers where a cached row set does not
require JDBC drivers during manipulation, but during population of the row set and
the committing the changes of the row set.
The following code shows how a JDBC row set is used:
RowSet rowset = new OracleJDBCRowSet ();
rowset.setUrl ("java:oracle:oci:@");
rowset.setUsername ("SCOTT");
rowset.setPassword ("TIGER");
rowset.setCommand (
"SELECT empno, ename, sal FROM emp");
rowset.execute ();
while (rowset.next ())
{
System.out.println ("empno: " + rowset.getInt (1));
System.out.println ("ename: "
+ rowset.getString (2));
System.out.println ("sal: " + rowset.getInt (3));
}
In the above example, the connection URL, username, password, and the SQL query is
set as the connection properties to the row set and the query is executed through the
execute() method and the rows are retrieved and printed.
* @return
*
* Notes: Choose a userid and password that can act as proxy for the users
* in the getProxyConnection() method.
CONNPOOL_MAX_LIMIT = 1
CONNPOOL_INCREMENT = 0
*/
/*
* This will use the user-id, password and connection pool name values set
LATER using the methods setUser, setPassword, setConnectionPoolName.
* @return
*
* Notes:
The following code shows how an application uses connection pool with
re-configuration:
import oracle.jdbc.oci.*;
import oracle.jdbc.pool.*;
/* create virtual connection objects from the connection pool "cpool." The
poolConfig can be null when using default values of min = 1, max = 1, and
increment = 0, otherwise needs to set the properties mentioned earlier */
OracleOCIConnection conn1 = (OracleOCIConnection) cpool.getConnection
("user1", password1");
connection "conn90" */
...
/* if the throughput is less, increase the pool size */
String newmin = String.valueOf (cpool.getMinLimit);
String newmax = String.valueOf (2*cpool.getMaxLimit());
String newincr = String.valueOf (1 + cpool.getConnectionIncrement());
Properties newproperties = newProperties();
newproperties.put (OracleOCIConnectionPool.CONNPOOL_MIN_LIMIT, newmin);
newproperties.put (OracleOCIConnectionPool.CONNPOOL_MAX_LIMIT, newmax);
newproperties.put (OracleOCIConnectionPool.CONNPOOL_INCREMENT, newincr);
cpool.setPoolConfig (newproperties);
} /* end of main */
} /* end of cpoolTest */
/*
* For getting a connection to the database.
*
* @param us Connection user-id
* @param p Connection password
* @return connection object
*/
public synchronized OracleConnection getConnection(String us, String p)
throws SQLException
Note: TAF does not work with the OCI Connection Pool.
For additional details regarding OCI and TAF, see the Programmer's Guide to the Oracle
Call Interface.
TAF Callbacks
TAF callbacks are used in the event of the failure of one database connection, and
failover to another database connection. TAF callbacks are callbacks that are registered
in case of failover. The callback is called during the failover to notify the JDBC
application of events generated. The application also has some control of failover.
OCI HeteroRM XA
HeteroRM XA is enabled through the use of the tnsEntry and nativeXA properties
of the OracleXADataSource class. Table 3–2, " Oracle Extended Datasource
Properties" on page 3-4 explains these properties in detail.
For a complete discussion of XA, see Chapter 9, "Distributed Transactions".
Exception Handling
When using the HeteroRM XA feature in distributed transactions, it is recommended
that the application simply check for XAException or SQLException, rather than
OracleXAException or OracleSQLException.
See "HeteroRM XA Messages" on page A-9 for a listing of HeteroRM XA messages.
Overview
The Oracle JDBC OCI driver supports PL/SQL index-by tables of scalar datatypes.
Table 19–1 displays the supported scalar types and the corresponding JDBC typecodes.
Note: Oracle JDBC does not support RAW, DATE, and PL/SQL
RECORD as element types.
Typical Oracle JDBC input binding, output registration, and data-access methods do
not support PL/SQL index-by tables. This chapter introduces additional methods to
support these types.
The OraclePreparedStatement and OracleCallableStatement classes define
the additional methods. These methods include the following:
■ setPlsqlIndexTable()
■ registerIndexTableOutParameter()
■ getOraclePlsqlIndexTable()
■ getPlsqlIndexTable()
These methods handle PL/SQL index-by tables as IN, OUT (including function return
values), or IN OUT parameters. For general information about PL/SQL syntax, see the
PL/SQL User's Guide and Reference.
The following sections describe the methods used to bind and register PL/SQL
index-by tables.
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.
synchronized public void setPlsqlIndexTable
(int paramIndex, Object arrayData, int maxLen, int curLen, int elemSqlType,
int elemMaxLen) throws SQLException
funcnone.registerIndexTableOutParameter
(1, maxLen, elemSqlType, elemMaxLen);
The return value is a Java array. The elements of this array are of the default Java type
corresponding to the SQL type of the elements. For example, for an index-by table
with elements of NUMERIC typecode, the element values are mapped to BigDecimal
by the Oracle JDBC driver, and the getPlsqlIndexTable() method returns a
BigDecimal[] array. For a JDBC application, you must cast the return value to a
BigDecimal[] array to access the table element values. (See "Datatype Mappings" on
page 4-12 for a list of default mappings.)
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.getPlsqlIndexTable (1);
The return value is an oracle.sql.Datum array and the elements in the Datum
array will be the default Datum type corresponding to the SQL type of the element.
For example, the element values of an index-by table of numeric elements are mapped
to the oracle.sql.NUMBER type in Oracle mapping, and the
getOraclePlsqlIndexTable() method returns an oracle.sql.Datum array
that contains oracle.sql.NUMBER elements.
The following code example uses the getOraclePlsqlIndexTable() method to
access the elements of a PL/SQL index-by table OUT parameter, using Oracle mapping.
(The code for registration is omitted.)
// Prepare the statement
OracleCallableStatement procout = (OracleCallableStatement)
conn.prepareCall ("begin procout (?); end;");
...
Java Primitive Type Mappings The getPlsqlIndexTable() method with the (int,
Class) signature returns index-by table elements in Java primitive types. The return
value is a Java array.
synchronized public Object getPlsqlIndexTable
(int paramIndex, Class primitiveType) throws SQLException
The following code example uses the getPlsqlIndexTable() method to access the
elements of a PL/SQL index-by table of numbers. In the example, the second
parameter specifies java.lang.Integer.TYPE, so the return value of the
getPlsqlIndexTable() method is an int array.
OracleCallableStatement funcnone = (OracleCallableStatement)
conn.prepareCall ("begin ? := funcnone; end;");
Overview
The Instant Client feature makes it extremely easy to deploy OCI, OCCI, 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 Instant Client
mode is significantly reduced compared to the same application running in a full client
side installation. The Instant Client shared libraries only occupy about one-fourth the
disk space of a full client installation.
Table 20–1 shows the Oracle client-side files required to deploy a JDBC OCI
application:
Release 10.1 library names are used in the table. The number part of library names will
change in future releases to agree with the release.
The opatchinv.out file should be copied along with the patched Instant Client
libraries to the deployment directory. The information in opatchinv.out will
indicate all the patches that have been applied.
The opatch inventory information for Instant Client libraries is not needed on the
Windows platform, so this step can be skipped on Windows.
such as:
url="jdbc:oracle:oci:@//example.com:5521/bjava21
On Windows:
set ORA_TZFILE timezlrg.dat
If the driver is not operating in the Instant Client mode (because the Data Shared
Library is not available), then ORA_TZFILE variable, if set, names a complete path
name as it does in previous Oracle releases.
If TNSNAMES entries are used, then, as mentioned earlier, TNS_ADMIN directory must
contain the TNSNAMES configuration files, and if TNS_ADMIN is not set, then the
ORACLE_HOME/network/admin directory must contain Oracle Net Services
configuration files.
Oracle JDBC now supports end-to-end metrics when used with an Oracle 10g
database. This chapter discusses end-to-end metric support. It contains the following
sections:
■ Introduction
■ JDBC API For End-To-End Metrics
Introduction
JDBC supports four end-to-end metrics, all of which are set on a per-connection basis:
■ Action—String
■ ClientId—String
■ ExecutionContextId—String and short SequenceNumber)
■ Module—String
All of these metrics are set on a per-connection basis. All operations on a given
connection share the same values. Applications normally set these metrics using DMS;
although it is also possible to set metrics using JDBC, metrics set using DMS (Dynamic
Monitoring Service) override metrics set using JDBC. To use DMS directly, you must
be using a DMS-enabled JAR, which is only available as part of Oracle Application
Server.
When a connection is created, the JDBC drivers check DMS for end-to-end metrics. It
only makes this check once during the lifetime of the connection.
■ If DMS metrics are not set, then JDBC never checks DMS for metrics again.
Thereafter, each time JDBC communicates with the database, it sends any updated
metric values to the database. (These metric values would have been updated
through the JDBC interface, not through DMS.)
If DMS metrics are set, then JDBC ignores the end-to-end metric API described in
this chapter. Thereafter, each time JDBC communicates with the database, it checks
with DMS for updated metric values, and, if it finds them, propagates them to the
database.
■ If no metrics are set, then no metrics are sent to the database.
This chapter describes the Oracle performance extensions to the JDBC standard. In the
course of discussing update batching, it also includes a discussion of the standard
update-batching model provided with JDBC 2.0.
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, thereby improving
application performance, by grouping multiple UPDATE, DELETE, or INSERT
statements into a single "batch" and having the whole batch sent to the database and
processed in one trip. This is referred to in this manual as update batching and in the
Sun Microsystems JDBC 2.0 specification as batch updates.
This is especially useful with prepared statements, when you are repeating the same
statement with different bind variables.
statement, there is no statement batch value, and the connection default batch
value is overridden with a value of 1.
Note that because Oracle update batching is vendor-specific, you must actually
use (or cast to) OraclePreparedStatement objects, not general
PreparedStatement objects.
■ To adhere to the JDBC 2.0 standard, Oracle's implementation of standard update
batching supports callable statements (without OUT parameters) and generic
statements, as well as prepared statements. You can migrate standard update
batching syntax into an Oracle JDBC application without difficulty.
■ You can batch only UPDATE, INSERT, or DELETE operations. Executing a batch
that includes an operation that attempts to return a result set will cause an
exception.
Note that with standard update batching, you can use either standard
PreparedStatement, CallableStatement, and Statement objects, or
Oracle-specific OraclePreparedStatement, OracleCallableStatement,
and OracleStatement objects.
Notes:
■ Do not mix standard update batching syntax with Oracle
update batching syntax in the same application. The JDBC
driver will throw an exception when you mix these syntaxes.
■ Disable auto-commit mode if you use either update batching
model. In case an error occurs while you are executing a batch,
this allows you the option of committing or rolling back the
operations that executed successfully prior to the error.
Even though this sets the default batch value for all the prepared statements of the
connection, you can override it by calling setDefaultBatch() on individual Oracle
prepared statements.
The connection batch value will apply to statement objects created after this batch
value was set.
Note that instead of calling setDefaultExecuteBatch(), you can set the
defaultBatchValue Java property if you use a Java Properties object in
establishing the connection. See "Supported Connection Properties" on page 4-3.
If you wish, insert the getExecuteBatch() method at any point in the program
to check the default batch value for the statement:
System.out.println (" Statement Execute Batch Value " +
((OraclePreparedStatement)ps).getExecuteBatch());
3. If you send an execute-update call to the database at this point, then no data will
be sent to the database, and the call will return 0.
// No data is sent to the database by this call to executeUpdate
System.out.println ("Number of rows updated so far: "
+ ps.executeUpdate ());
4. If you enter a set of input values for a second row and an execute-update, then the
number of batch calls to executeUpdate() will be equal to the batch value of 2.
The data will be sent to the database, and both rows will be inserted in a single
round trip.
ps.setInt (1, 11);
ps.setString (2, "Applications");
ps.setString (3, "Indonesia");
ps.close ();
To check the particular statement batch value of an Oracle prepared statement, use the
OraclePreparedStatement class getExecuteBatch() method:
Integer batch_val = ((OraclePreparedStatement)ps).getExecuteBatch();
PreparedStatement ps =
conn.prepareStatement("insert into dept values (?, ?, ?)");
ps.setInt(1, 23);
ps.setString(2, "Sales");
ps.setString(3, "USA");
ps.executeUpdate(); //JDBC queues this for later execution
ps.setInt(1, 24);
ps.setString(2, "Blue Sky");
ps.setString(3, "Montana");
ps.executeUpdate(); //JDBC queues this for later execution
ps.setInt(1, 25);
ps.setString(2, "Applications");
ps.setString(3, "India");
ps.executeUpdate(); //The queue size equals the batch value of 3
//JDBC sends the requests to the database
ps.setInt(1, 26);
ps.setString(2, "HR");
ps.setString(3, "Mongolia");
ps.executeUpdate(); //JDBC queues this for later execution
ps.close();
...
Notes:
■ Do not mix standard update batching syntax with Oracle
update batching syntax in the same application. The Oracle
JDBC driver will throw exceptions when these syntaxes are
mixed.
■ Disable auto-commit mode if you use either update batching
model. In case an error occurs while you are executing a batch,
this allows you the option of committing or rolling back the
operations that executed successfully prior to the error.
pstmt.setInt(1, 2000);
pstmt.setString(2, "Milo Mumford");
pstmt.addBatch();
pstmt.setInt(1, 3000);
pstmt.setString(2, "Sulu Simpson");
pstmt.addBatch();
...
Following is an example that repeats the prepared statement addBatch() calls shown
previously and then executes the batch:
...
PreparedStatement pstmt =
conn.prepareStatement("INSERT INTO employees VALUES(?, ?)");
pstmt.setInt(1, 2000);
pstmt.setString(2, "Milo Mumford");
pstmt.addBatch();
pstmt.setInt(1, 3000);
pstmt.setString(2, "Sulu Simpson");
pstmt.addBatch();
The executeBatch() method returns an int array, typically one element per
batched operation, indicating success or failure in executing the batch and sometimes
containing information about the number of rows affected. This is discussed in
"Update Counts in the Oracle Implementation of Standard Batching" on page 22-11.
Notes:
■ After calling addBatch(), you must call either
executeBatch() or clearBatch() before a call to
executeUpdate(), otherwise there will be a SQL exception.
■ When a batch is executed, operations are performed in the
order in which they were batched.
■ The statement batch is reset to empty once executeBatch()
has returned.
■ An executeBatch() call closes the statement object's current
result set, if one exists.
pstmt.setInt(1, 2000);
pstmt.setString(2, "Milo Mumford");
pstmt.addBatch();
pstmt.setInt(1, 3000);
pstmt.setString(2, "Sulu Simpson");
pstmt.addBatch();
if (...condition...)
{
int[] updateCounts = pstmt.executeBatch();
...
}
else
{
pstmt.clearBatch();
...
}
Notes:
■ After calling addBatch(), you must call either
executeBatch() or clearBatch() before a call to
executeUpdate(), otherwise there will be a SQL exception.
■ A clearBatch() call resets the statement batch to empty.
■ Nothing is returned by the clearBatch() method.
PreparedStatement pstmt =
conn.prepareStatement("INSERT INTO employees VALUES(?, ?)");
pstmt.setInt(1, 2000);
pstmt.setString(2, "Milo Mumford");
pstmt.addBatch();
pstmt.setInt(1, 3000);
pstmt.setString(2, "Sulu Simpson");
pstmt.addBatch();
conn.commit();
pstmt.close();
...
You can process the update counts array to determine if the batch executed
successfully. This is discussed in the next section ("Error Handling in the Oracle
Implementation of Standard Batching").
■ For a generic statement batch or callable statement batch, the update counts array
is only a partial array containing the actual update counts up to the point of the
error. 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.
For example, if there were 20 operations in the batch, the first 13 succeeded, and
the 14th generated an exception, then the update counts array will have 13
elements, containing actual update counts of the successful operations.
You can either commit or roll back the successful operations in this situation, as
you prefer.
In your code, upon failed execution of a batch, you should be prepared to handle
either -3's or true update counts in the array elements when an exception occurs. For a
failed batch execution, you will have either a full array of -3's or a partial array of
positive integers.
pstmt.setInt(1, 2000);
pstmt.setString(2, "Milo Mumford");
pstmt.setInt(1, 3000);
pstmt.setString(2, "Sulu Simpson");
pstmt.addBatch(); // Now start a batch
pstmt.setInt(1, 4000);
pstmt.setString(2, "Stan Leland");
pstmt.addBatch();
pstmt.setInt(1, 5000);
pstmt.setString(2, "Amy Feiner");
COMMIT request will affect all non-batched operations and all successful operations in
executed batches, but will not affect any pending batches.
/*
* Premature batch flush happens here.
*/
pstmt.setInt (1, 22);
pstmt.setString (2, "test22");
int count = pstmt.executeUpdate (); // returns 0
Note: With JDBC 2.0, the ability to preset the fetch size became
standard functionality. For information about the standard
implementation of this feature, see "Fetch Size" on page 17-15.
Notes:
■ Do not mix the JDBC 2.0 fetch size API and the Oracle
row-prefetching API in your application. You can use one or
the other, but not both.
■ Be aware that setting the Oracle row-prefetch value can affect
not only queries, but also: 1) explicitly refetching rows in a
result set through the result set refreshRow() method
available with JDBC 2.0 (relevant for scroll-sensitive/read-only,
scroll-sensitive/updatable, and scroll-insensitive/updatable
result sets); and 2) the "window" size of a scroll-sensitive result
set, affecting how often automatic refetches are performed. The
Oracle row-prefetch value will be overridden, however, by any
setting of the fetch size. See "Fetch Size" on page 17-15 for more
information.
while( rset.next () )
System.out.println( rset.getString (1) );
while( rset.next() )
System.out.println( rset.getString (1) );
stmt.close();
or, if the column is VARCHAR or equivalent and you know the length limit:
stmt.defineColumnType(column_index, typeCode, max_size);
or, for an NVARCHAR column where the original maximum length is desired and
conversion to the database character set is requested:
stmt.defineColumnType(column_index, typeCode, 0,
OraclePreparedStatement.FORM_CHAR );
Set a maximum field size if you do not want to receive the full default length of
the data. Calling the setMaxFieldSize() method of the standard JDBC
Statement class sets a restriction on the amount of data returned. Specifically, the
size of the data returned will be the minimum of:
The following example illustrates the use of this feature. It assumes you have imported
the oracle.jdbc.* interfaces.
As this example shows, you must cast the statement (stmt) to type
OracleStatement in the invocation of the defineColumnType() method. The
connection's createStatement() method returns an object of type
java.sql.Statement, which does not have the defineColumnType() and
clearDefines() methods. These methods are provided only in the
OracleStatement implementation.
The define-extensions use JDBC types to specify the desired types. The allowed define
types for columns depend on the internal Oracle type of the column.
All columns can be defined to their "natural" JDBC types; in most cases, they can be
defined to the Types.CHAR or Types.VARCHAR typecode.
Table 22–1 lists the valid column definition arguments you can use in the
defineColumnType() method.
retrieves procedures and arguments without a package, that is, standalone objects.
A null value means to drop from the selection criteria, that is, return information
about both stand-alone and packaged objects (same as passing in "%"). Otherwise
the catalog parameter should be a package name pattern (with SQL wild cards,
if desired).
■ schemaPattern: All objects within Oracle must have a schema, so it does not
make sense to return information for those objects without one. Thus, the
construct " " (the empty string) is interpreted on input to mean the objects in the
current schema (that is, the one to which you are currently connected). To be
consistent with the behavior of the catalog parameter, null is interpreted to
drop the schema from the selection criteria (same as passing in "%"). It can also be
used as a pattern with SQL wild cards.
■ procedureNamePattern and columnNamePattern: The empty string (" ")
does not make sense for either parameter, because all procedures and arguments
must have names. Thus, the construct " " will raise an exception. To be consistent
with the behavior of other parameters, null has the same effect as passing in "%".
different from any Oracle thick-client situation. Your use of Advanced Security
features is determined by related settings in the SQLNET.ORA file on the client
machine, as discussed in the Oracle Advanced Security Administrator's Guide. Refer to
that manual for information.
This table shows, for example, that if encryption is requested by the client, but rejected
by the server, it is disabled. The same is true for integrity. As another example, if
encryption is accepted by the client and requested by the server, it is enabled. And,
again, the same is true for integrity.
The general settings are further discussed in the Oracle Advanced Security
Administrator's Guide. How to set them for a JDBC application is described in the
following subsections.
Table 23–2 OCI Driver Client Parameters for Encryption and Integrity
Parameter Description Parameter Name Possible Settings
Client encryption level SQLNET.ENCRYPTION_CLIENT REJECTED
ACCEPTED
REQUESTED
REQUIRED
Client encryption selected SQLNET.ENCRYPTION_TYPES_CLIENT RC4_40, RC4_56,
list DES, DES40,
AES128, AES192,
AES256, 3DES112,
3DES168
(see note below)
Client integrity level SQLNET.CRYPTO_CHECKSUM_CLIENT REJECTED
ACCEPTED
REQUESTED
REQUIRED
Client integrity selected list SQLNET.CRYPTO_CHECKSUM_TYPES_CLIENT MD5
These settings, and corresponding settings in the server, are further discussed in
Appendix A of the Oracle Advanced Security Administrator's Guide.
Table 23–3 Thin Driver Client Parameters for Encryption and Integrity
Parameter Parameter
Parameter Name Type Class Possible Settings
oracle.net.encryption_client string static REJECTED
ACCEPTED
REQUESTED
REQUIRED
oracle.net.encryption_types_client string static RC4_40
RC4_56
DES40C
DES56C
3DES112
3DES168
oracle.net.crypto_checksum_client string static REJECTED
ACCEPTED
REQUESTED
REQUIRED
oracle.net.crypto_checksum_types_ string static MD5
client
Notes:
■ Because Oracle Advanced Security support for the Thin driver
is incorporated directly into the JDBC classes JAR file, there is
only one version, not separate domestic and export editions.
Only parameter settings that would be suitable for an export
edition are possible.
■ The "C" in 3DES168 and DES56C refers to CBC (cipher block
chaining) mode.
the Thin driver supports only one possible value in each case; however, in the future,
when multiple values are supported, specifying a list will result in a negotiation
between the server and the client that determines which value is actually used.
Complete example Example 23–1 is a complete class that sets data encryption and
integrity parameters before connecting to a database to perform a query.
Before running this example, you must turn on encryption in the sqlnet.ora file.
For example, the following 4 lines will turn on DES40, DES, 2-DES-112 and 3-DES168
for the encryption and MD5 and SHA1 for the checksum:
SQLNET.ENCRYPTION_SERVER = ACCEPTED
SQLNET.CRYPTO_CHECKSUM_SERVER = ACCEPTED
SQLNET.CRYPTO_CHECKSUM_TYPES_SERVER= (MD5, SHA1)
SQLNET.ENCRYPTION_TYPES_SERVER= (DES40, DES, 3DES112, 3DES168)
SQLNET.CRYPTO_SEED = 12345678901234567890
class Employee
{
public static void main (String args [])
throws Exception
{
try {
FileInputStream defaultStream = new FileInputStream(args[0]);
props.load(defaultStream);
// You can put a database name after the @ sign in the connection URL.
OracleDataSource ods = new OracleDataSource();
ods.setURL("jdbc:oracle:thin:@host.example.com:1521:main");
ods.setConnectionProperties(props);
Connection conn = ods.getConnection();
// Create a Statement
Statement stmt = conn.createStatement ();
conn.close();
}
JDBC in Applets
This section describes some of the basics of working with Oracle JDBC applets.
Aside being mindful of applet connection and security issues, there is essentially no
difference between coding a JDBC applet and a JDBC application.
This section describes what you must do for the applet to connect to a database,
including how to use the Oracle Connection Manager or signed applets if you are
connecting to a database not running on the same host as the Web server. It also
describes how your applet can connect to a database through a firewall. 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
For general information about connecting to the database, see "Opening a Connection
to a Database" on page 4-2.
As with connecting from an application, there are two ways in which you can specify
the connection information to the driver. You can provide it in the form of
host:port:sid or in the form of a TNS keyword-value syntax.
For example, if the database to which you want to connect resides on host prodHost,
at port 1521, and SID ORCL, and you want to connect with user name scott with
password tiger, then use either of the two following connect strings:
using host:port:sid syntax:
String connString="jdbc:oracle:thin:@prodHost:1521:ORCL";
ods.setURL(connString);
ods.setUser("scott");
ods.setPassword("tiger");
Connection conn = ods.getConnection();
(connect_data=(INSTANCE_NAME=ORCL)))";
If you use the TNS keyword-value pair to specify the connection information to the
JDBC Thin driver, then you must declare the protocol as TCP.
However, a Web server and an Oracle database server both require many resources;
you seldom find both servers running on the same machine. Usually, your applet
connects to a database on a host other than the one on which the Web server runs.
There are two possible ways in which you can work around the security restriction:
■ You can connect to the database by using the Oracle Connection Manager.
or:
■ You can use a signed applet to connect to the database directly.
These options are discussed in the next section, "Connecting to a Database on a
Different Host Than the Web Server".
Figure 23–1 illustrates the relationship between the applet, the Oracle Connection
Manager, and the database.
webHost oraHost
Installing and Running the Oracle Connection Manager You must install the Connection
Manager, available on the Oracle distribution media, onto the Web server host. You
can find the installation instructions in the Oracle Net Services Administrator's Guide.
On the Web server host, create a CMAN.ORA file in the [ORACLE_HOME]/NET8/ADMIN
directory. The options you can declare in a CMAN.ORA file include firewall and
connection pooling support.
Here is an example of a very simple CMAN.ORA file. Replace web-server-host with
the name of your Web server host. The fourth line in the file indicates that the
Connection Manager is listening on port 1610. You must use this port number in your
connect string for JDBC.
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)
)
Note that the Java Oracle Net version inside the JDBC Thin driver does not have
authentication service support. This means that the AUTHENTICATION_LEVEL
configuration parameter in the CMAN.ORA file must be set to 0.
After you create the file, start the Connection Manager at the operating system prompt
with this command:
cmctl start
To use your applet, you must now write the connect string for it.
Writing the URL that Targets the Connection Manager This section describes how to write
the URL in your applet so that the applet connects to the Connection Manager, and the
Connection Manager connects with the database. In the URL, you specify an address
list that lists the protocol, port, and name of the Web server host on which the
Connection Manager is running, followed by the protocol, port, and name of the host
on which the database is running.
The following example describes the configuration illustrated in Figure 23–1. The Web
server on which the Connection Manager is running is on host webHost and is
listening on port 1610. The database to which you want to connect is running on host
oraHost, listening on port 1521, and SID ORCL. 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))";
OracleDataSource ods = new OracleDataSource();
ods.setURL(myURL);
ods.setUser("scott");
ods.setPassword("tiger");
Connection conn = ods.getConnection();
The first element in the address_list entry represents the connection to the
Connection Manager. The second element represents the database to which you want
to connect. The order in which you list the addresses is important.
When your applet uses a URL such as the one above, it will behave exactly as if it were
connected directly to the database on the host oraHost.
For more information on the parameters that you specify in the URL, see the Oracle Net
Services Administrator's Guide.
Connecting through Multiple Connection Managers Your applet can reach its target database
even if it first has to go through multiple Connection Managers (for example, if the
Connection Managers form a "proxy chain"). To do this, add the addresses of the
Connection Managers to the address list, in the order that you plan to access them. The
database listener should be the last address on this list. See the Oracle Net Services
Administrator's Guide for more information about source_route addressing.
2. Include applet code that asks for appropriate permission before opening a socket.
If you are using Netscape, then your code would include a statement like this:
netscape.security.PrivilegeManager.enablePrivilege("UniversalConnect");
OracleDataSource ods = new OracleDataSource();
ods.setURL("jdbc:oracle:thin:scott/tiger@dlsun511:1721:orcl");
Connection conn = ods.getConnection();
For information about the Java Security API, including signed applet examples, see the
following Sun Microsystems site:
http://java.sun.com/security
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.
Java applets do not have access to the local system—that is, they cannot get the
hostname or environment variables locally—because of security limitations. As a
result, the JDBC Thin driver cannot access the hostname on which it is running. The
firewall cannot be provided with the hostname. To allow requests from JDBC Thin
clients to go through the firewall, you must do the following two things to the
firewall's list of rules:
■ Add the IP address (not the hostname) of the host on which the JDBC applet is
running.
■ Ensure that the hostname "__jdbc__" never appears in the firewall's rules. This
hostname has been hard-coded as a false hostname inside the driver to force an IP
address lookup. If you do enter this hostname in the list of rules, then every applet
using Oracle's JDBC Thin driver will be able to go through your firewall.
By not including the Thin driver's hostname, the firewall is forced to do an IP address
lookup and base its access decision on the IP address, instead of the hostname.
"jdbc:oracle:thin:@example.us.oracle.com:1521:orcl
";
The first element in the address_list represents the connection to the firewall. The
second element represents the database to which you want to connect. Note that the
order in which you specify the addresses is important.
Notice that you can also write the preceding URL in this 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))";
OracleDataSource ods = new OracleDataSource();
ods.setURL(connString);
ods.setUser("scott");
ods.setPassword("tiger");
Connection conn = ods.getConnection();
When your applet uses a URL similar to the one above, it will behave as if it were
connected to the database on host oraHost.
For more information on the parameters used in the above example, see the Oracle Net
Services Administrator's Guide. For more information on how to configure a firewall,
please see your firewall's documentation or contact your firewall vendor.
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 classes12.jar.
Follow these steps:
1. Move the JDBC driver classes file classes12.jar to an empty directory.
If your applet will connect to a database with a non-US7ASCII and
non-WE8ISO8859P1 character set, then also move the orai18n.jar file to the
same directory.
2. Add your applet classes files to the directory, and any other files the applet might
require.
3. Zip the applet classes and driver classes together into a single ZIP or JAR file. The
single zip file should contain the following:
■ class files from classes12.jar (and required class files from orai18n.jar
if the applet requires Globalization Support)
■ your applet classes
Additionally, if you are using DatabaseMetaData entry points in your applet,
include the oracle/jdbc/driver/OracleDatabaseMetaData.class file.
Note that this file is very large and might have a negative impact on performance.
If you do not use DatabaseMetaData methods, omit this file.
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>
You can find a description of the APPLET, CODE, ARCHIVE, CODEBASE, WIDTH, and
HEIGHT parameters in the next section.
If you use this form of the CODE tag, then the classes for the applet and the classes for
the JDBC Thin driver must be in the same directory as the HTML page.
Notice that in the CODE specification, you do not include the file name extension
".class".
CODEBASE
The CODEBASE parameter is optional and specifies the base URL of the applet; that is,
the name of the directory that contains the applet's code. If it is not specified, then the
document's URL 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 entry CODEBASE="." indicates that the applet resides in the current directory
(my_Dir). If the value of codebase was set to Applet_Samples, for example:
CODEBASE="Applet_Samples"
ARCHIVE
The ARCHIVE parameter is optional and specifies the name of the archive file (either a
.zip or .jar file), if applicable, that contains the applet classes and resources the
applet needs. Oracle recommends using a .zip file or .jar file, which saves many
extra round-trips to the server.
The .zip (or .jar) file will be preloaded. If you have more than one archive 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>
class JDBCConnection
{
public static Connection connect() throws SQLException
{
Connection conn = null;
try {
// connect with the server-side internal driver
OracleDriver ora = new OracleDriver();
conn = ora.defaultConnection();
}
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 typically not be closed.
If you do call the close() method, be aware of the following:
■ All connection instances obtained through the defaultConnection() method,
which actually all reference the same connection object, will be closed and
unavailable for further use, with state and resource cleanup as appropriate.
Executing 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.
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
server default connection.
The OracleDataSource.getConnection() method returns a new Java
Connection object every time you call it. Note that although the method is not
creating a new physical connection (only a single implicit connection is used), it is
returning a new object.
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.
Example
Following is an example of server-side error processing:
try
{
// should get "ORA-942: table or view does not exist"
stmt.execute("drop table no_such_table");
}
catch (OracleSQLException e)
{
System.out.println(e.getMessage());
// prints "ORA-942: table or view does not exist"
System.out.println(e.getNumParameters());
// prints "1"
or:
conn.rollback();
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 simply use:
ods.setUrl(
"jdbc:oracle:kprb:@");
Connection conn = ods.getConnection();
However, the most convenient way to get a connection is to call the static
OracleDriver.defaultConnection() method, as shown below:
Connection conn = OracleDriver.defaultConnection();
or:
loadjava -user scott/tiger Foo*.class
or:
loadjava -user scott/tiger Foo.jar
Or use the following command to load with the Thin driver (specifying the -thin
option and an appropriate URL):
loadjava -thin -user scott/tiger@localhost:1521:ORCL Foo.jar
(Whether to use an OCI driver or the Thin driver to load classes depends on your
particular environment and which performs better for you.)
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 OCI driver:
loadjava -user scott/tiger -resolve Foo.java
Or use the following command to load with the Thin driver (specifying the -thin
option and an appropriate URL):
loadjava -thin -user scott/tiger@localhost:1521:ORCL -resolve Foo.java
Either of these will result in appropriate class schema objects being created in addition
to the source schema object.
This chapter contains detailed JDBC reference information, including the following
topics:
■ Valid SQL-JDBC Datatype Mappings
■ Supported SQL and PL/SQL Datatypes
■ Embedded SQL92 Syntax
■ Oracle JDBC Notes and Limitations
Notes:
■ The type UROWID is not supported.
■ The oracle.sql.Datum class is abstract. The value passed to
a parameter of type oracle.sql.Datum must be of the Java
type corresponding to the underlying SQL type. Likewise, the
value returned by a method with return type
oracle.sql.Datum must be of the Java type corresponding
to the underlying SQL type.
■ The mappings to oracle.sql classes are optimal if no
conversion from SQL format to Java format is necessary.
Table 24–3 describes Oracle JDBC support for the ANSI-supported SQL datatypes.
Table 24–4 describes Oracle JDBC driver support for SQL User-Defined types.
Table 24–5 describes Oracle JDBC driver support for PL/SQL datatypes. Note that
PL/SQL datatypes include these categories:
■ scalar types
■ scalar character types (includes boolean and date datatypes)
■ composite types
■ reference types
■ LOB types
Notes:
■ The types NATURAL, NATURALn, POSITIVE, POSITIVEn, and
SIGNTYPE are subtypes of BINARY INTEGER.
■ The types DEC, DECIMAL, DOUBLE PRECISION, FLOAT, INT,
INTEGER, NUMERIC, REAL, and SMALLINT are subtypes of
NUMBER.
■ The types NCHAR and NVARCHAR2 are supported indirectly.
There is no corresponding java.sql.Types type (use CHAR),
but if your application invokes formOfUse(NCHAR) then
these types can be accessed. See "NCHAR, NVARCHAR2,
NCLOB and the defaultNChar Property" on page 12-2 for
details.
Date Literals
The JDBC drivers support date literals in SQL statements written in the format:
{d 'yyyy-mm-dd'}
The JDBC drivers will replace this escape clause with the equivalent Oracle
representation: "22 OCT 1995".
This code snippet contains an example of using a date literal in a SQL statement.
// Connect to the database
// You can put a database name after the @ sign in the connection URL.
OracleDataSource ods = new OracleDataSource();
ods.setURL("jdbc:oracle:oci:@");
ods.setUser("scott");
ods.setPassword("tiger");
Connection conn = ods.getConnection();
// Create a Statement
Statement stmt = conn.createStatement ();
// Select the ename column from the emp table where the hiredate is Jan-23-1982
ResultSet rset = stmt.executeQuery
("SELECT ename FROM emp WHERE hiredate = {d '1982-01-23'}");
Time Literals
The JDBC drivers support time literals in SQL statements written in the format:
{t 'hh:mm:ss'}
The JDBC drivers will replace this escape clause with the equivalent Oracle
representation: "05:10:45".
If the time is specified as:
{t '14:20:50'}
Then the equivalent Oracle representation would be "14:20:50", assuming the server is
using a 24-hour clock.
This code snippet contains an example of using a time literal in a SQL statement.
ResultSet rset = stmt.executeQuery
Timestamp Literals
The JDBC drivers support timestamp literals in SQL statements written in the format:
{ts 'yyyy-mm-dd hh:mm:ss.f...'}
Scalar Functions
The Oracle JDBC drivers do not support all scalar functions. To find out which
functions the drivers support, use the following methods supported by the
Oracle-specific oracle.jdbc.OracleDatabaseMetaData class and the standard
Java java.sql.DatabaseMetadata interface:
■ getNumericFunctions(): Returns a comma-separated list of math functions
supported by the driver. For example, ABS, COS, SQRT.
■ getStringFunctions(): Returns a comma-separated list of string functions
supported by the driver. For example, ASCII, LOCATE.
■ getSystemFunctions(): Returns a comma-separated list of system functions
supported by the driver. For example, DATABASE, USER.
■ getTimeDateFunctions(): Returns a comma-separated list of time and date
functions supported by the driver. For example, CURDATE, DAYOFYEAR, HOUR.
// Select the empno column from the emp table where the ename starts with '_'
ResultSet rset = stmt.executeQuery
("SELECT empno FROM emp WHERE ename LIKE '&_%' {ESCAPE '&'}");
Outer Joins
Oracle's JDBC drivers do not support outer join syntax: {oj outer-join}. The workaround
is to use Oracle outer join syntax:
Instead of:
Statement stmt = conn.createStatement ();
ResultSet rset = stmt.executeQuery
("SELECT ename, dname
FROM {OJ dept LEFT OUTER JOIN emp ON dept.deptno = emp.deptno}
ORDER BY ename");
The following code is the output that prints the comparable SQL syntax.
{call foo(?, ?)} => BEGIN foo(:1, :2); END;
{? = call bar (?, ?)} => BEGIN :1 := bar (:2, :3); END;
{d '1998-10-22'} => TO_DATE ('1998-10-22', 'YYYY-MM-DD')
{t '16:22:34'} => TO_DATE ('16:22:34', 'HH24:MI:SS')
{ts '1998-10-22 16:22:34'} => TO_DATE ('1998-10-22 16:22:34', 'YYYY-MM-DD
HH24:MI:SS')
CursorName
Oracle JDBC drivers do not support the get getCursorName() and
setCursorName() methods, because there is no convenient way to map them to
Oracle constructs. Oracle recommends using ROWID instead. For more information on
how to use and manipulate ROWIDs, see "Oracle ROWID Type" on page 10-23.
SQLWarning Class
The java.sql.SQLWarning class provides information on a database access
warning. Warnings typically contain a description of the warning and a code that
identifies the warning. Warnings are silently chained to the object whose method
caused it to be reported. The Oracle JDBC drivers generally do not support
SQLWarning. (As an exception to this, scrollable result set operations do generate SQL
warnings, but the SQLWarning instance is created on the client, not in the database.)
For information on how the Oracle JDBC drivers handle errors, see "Processing SQL
Exceptions" on page 4-25.
This capability to bind by name using the setXXX methods is not part of the JDBC
specification, and Oracle does not support it. The JDBC drivers can throw a
SQLException or produce unexpected results. In 10g Release 1 (10.1) JDBC drivers,
bind by name is supported using the setXXXAtName methods. See "Interface
oracle.jdbc.OracleCallableStatement" on page 10-15 and "Interface
oracle.jdbc.OraclePreparedStatement" on page 10-14.
PreparedStatement p = conn.prepareStatement
("SELECT name FROM emp WHERE id = ? AND dept = ?");
p.setInt(1, 314159);
p.setString(2, "SALES");
ResultSet r1 = p.execute();
p.setInt(1, 425260);
ResultSet r2 = p.execute();
Having authenticated, your application can connect as "jeff" using the already
authenticated credentials of "scott". Although the created session will behave as
if "jeff" was connected normally (using "jeff"/"jeff-password"), "jeff" will
not have to divulge its password to the middle tier. The proxy section has access to
the schema of "jeff" as well as to what is indicated in the list of roles. Therefore,
if "scott" wants "jeff" to access its table EMP, the following code can be used:
create role role1;
grant select on EMP to role1;
The role clause can also be thought as limiting "jeff's" access to only those
database objects of "scott" mentioned in the list of the roles. The list of roles can
be empty.
■ Accounting purposes. The transactions made via proxy sessions can be better
accounted by proxying the user ("jeff"), under different users such as "scott",
"scott2" assuming "scott" and "scott2" are authenticated. Transactions made
under these different proxy sessions by "jeff" can be logged separately.
There are three ways to create proxy sessions in the OCI driver. Roles can be associated
with any of the following options:
■ USER NAME: This is done by supplying the user name and/or the password. The
reason why the "password" option exists is so that database operations made by
the user ("jeff"), can be accounted. The SQL clause is:
alter user jeff grant connect through scott authenticated using password;
The string after the "globally as" clause is the distinguished name. It is then
necessary to authenticate as:
alter user jeff grant connect through scott authenticated using distinguished
name;
■ CERTIFICATE: This is a more encrypted way of passing the credentials of the user
(to be proxied) to the database. The certificate contains the distinguished encoded
name. One way of generating it is by creating a wallet (using "runutl
mkwallet"), then decoding the wallet to get the certificate. It is then necessary to
authenticate as:
alter user jeff grant connect through scott authenticated using certificate;
PROXYTYPE_DISTINGUISHED_NAME
- This will specify the distinguished name of the user
in proxyUser
PROXYTYPE_CERTIFICATE
- This will specify the proxy certificate
If PROXYTYPE_USER_NAME
PROXY_USER_NAME and/or PROXY_USER_PASSWORD depending
on how the connection-pool owner was authenticated
to act as proxy for this proxy user
PROXY_USER_NAME (String) = user to be proxied for
PROXY_PASSWORD (String) = password of the user to be proxied for
else if PROXYTYPE_DISTINGUISHED_NAME
PROXY_DISTINGUISHED_NAME (String) = (global) distinguished name of the
user to be proxied for
PROXY_ROLES (String[]) Set of roles which this proxy connection can use.
Roles can be null, and can be associated
with any of the above proxy methods.
*
* @return connection object
*
* Notes: The user and password used to create OracleOCIConnectionPool()
* must be allowed to act as proxy for user 'us'.
*/
public synchronized OracleConnection getProxyConnection(String proxyType,
Properties prop)
throws SQLException
This chapter describes how to optimize and troubleshoot a JDBC application or applet,
including the following topics:
■ JDBC and Multithreading
■ Performance Optimization
■ Common Problems
■ Basic Debugging Procedures
■ Transaction Isolation Levels and Access Modes
Where number_of_threads is the number of threads that you want to create, and
share specifies that you want the threads to share the connection. If you do not
specify the number of threads, then the program creates 10 by default.
/*
* This sample is a multi-threaded JDBC program.
*/
import java.sql.*;
import oracle.jdbc.OracleStatement;
int m_myId;
if (args.length > 1)
{
share_connection = true;
System.out.println
("All threads will be sharing the same connection");
}
// spawn threads
for (int i = 0; i < NUM_OF_THREADS; i++)
{
threadList[i] = new JdbcMTSample();
threadList[i].start();
}
if (share_connection)
{
s_conn.close();
s_conn = null;
}
}
catch (Exception e)
{
e.printStackTrace();
}
public JdbcMTSample()
{
super();
// Assign an Id to the thread
m_myId = getNextId();
}
try
{
// Get the connection
if (share_connection)
stmt = s_conn.createStatement (); // Create a Statement
else
{
OracleDataSource ods = new OracleDataSource();
ods.setURL("jdbc:oracle:oci:@");
ods.setUser("scott");
ods.setPassword("tiger");
Connection conn = ods.getConnection();
stmt = conn.createStatement (); // Create a Statement
}
while (!getGreenLight())
yield();
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
single statement can return multiple results as well as output parameter values. Here,
the COMMIT occurs when all results and output parameter values have been retrieved.
If you disable auto-commit mode with a setAutoCommit(false) call, then you
must manually commit or roll back groups of operations using the commit() or
rollback() method of the connection object.
// Create a Statement
Statement stmt = conn.createStatement ();
...
Table 26–1 Mapping of SQL Datatypes to Java Classes that Represent SQL Datatypes
ORACLE Mapping - Java Classes
SQL Datatype Representing SQL Datatypes
CHAR oracle.sql.CHAR
VARCHAR2 oracle.sql.CHAR
DATE oracle.sql.DATE
DECIMAL oracle.sql.NUMBER
DOUBLE PRECISION oracle.sql.NUMBER
FLOAT oracle.sql.NUMBER
INTEGER oracle.sql.NUMBER
REAL oracle.sql.NUMBER
RAW oracle.sql.RAW
LONG RAW oracle.sql.RAW
REF CURSOR java.sql.ResultSet
CLOB LOCATOR oracle.sql.CLOB
BLOB LOCATOR oracle.sql.BLOB
BFILE oracle.sql.BFILE
nested table oracle.sql.ARRAY
varray oracle.sql.ARRAY
SQL object value If there is no entry for the object value in the type map:
■ oracle.sql.STRUCT
If there is an entry for the object value in the type map:
■ customized Java class
REF to SQL object type class that implements oracle.sql.SQLRef, typically by extending
oracle.sql.REF
This mapping provides the most efficient conversion between SQL and Java data
representations. It stores the usual representations of SQL data as byte arrays. It avoids
re-formatting the data or performing character-set conversions (aside from the usual
network conversions). It is information-preserving. This "Oracle Mapping" is the most
efficient type-mapping for applications that "shovel" data from SQL to Java, or vice
versa.
Common Problems
This section describes some common problems that you might encounter while using
the Oracle JDBC drivers. These problems include:
■ Memory Consumption for CHAR Columns Defined as OUT or IN/OUT Variables
■ Memory Leaks and Running Out of Cursors
■ Boolean Parameters in PL/SQL Stored Procedures
■ Opening More Than 16 OCI Connections for a Process
identifies the events that led to the error. Several Oracle Net parameters in the
SQLNET.ORA file control the gathering of trace information. After setting the
parameters in SQLNET.ORA, you must make a new connection for tracing to be
performed.
The higher the trace level, the more detail is captured in the trace file. Because the trace
file can be hard to understand, start with a trace level of 4 when enabling tracing. The
first part of the trace file contains connection handshake information, so look beyond
this for the SQL statements and error messages related to your JDBC program.
Note: The trace facility uses a large amount of disk space and
might have significant impact upon system performance. Therefore,
enable tracing only when necessary.
Client-Side Tracing
Set the following parameters in the SQLNET.ORA file on the client system.
TRACE_LEVEL_CLIENT
Purpose:
Turns tracing on/off to a certain specified level.
Default Value:
0 or OFF
Available Values:
■ 0 or OFF - No trace output
■ 4 or USER - User trace information
■ 10 or ADMIN - Administration trace information
■ 16 or SUPPORT - WorldWide Customer Support trace information
Example:
TRACE_LEVEL_CLIENT=10
TRACE_DIRECTORY_CLIENT
Purpose:
Specifies the destination directory of the trace file.
Default Value:
ORACLE_HOME/network/trace
Example:
UNIX: TRACE_DIRECTORY_CLIENT=/oracle/traces
Windows: TRACE_DIRECTORY_CLIENT=C:\ORACLE\TRACES
TRACE_FILE_CLIENT
Purpose:
Specifies the name of the client trace file.
Default Value:
SQLNET.TRC
Example:
TRACE_FILE_CLIENT=cli_Connection1.trc
Note: Ensure that the name you choose for the TRACE_FILE_
CLIENT file is different from the name you choose for the TRACE_
FILE_SERVER file.
TRACE_UNIQUE_CLIENT
Purpose:
Gives each client-side trace a unique name to prevent each trace file from being
overwritten with the next occurrence of a client trace. The PID is attached to the end of
the file name.
Default Value:
OFF
Example:
TRACE_UNIQUE_CLIENT = ON
Server-Side Tracing
Set the following parameters in the SQLNET.ORA file on the server system. Each
connection will generate a separate file with a unique file name.
TRACE_LEVEL_SERVER
Purpose:
Turns tracing on/off to a certain specified level.
Default Value:
0 or OFF
Available Values:
■ 0 or OFF - No trace output
■ 4 or USER - User trace information
■ 10 or ADMIN - Administration trace information
■ 16 or SUPPORT - WorldWide Customer Support trace information
Example:
TRACE_LEVEL_SERVER=10
TRACE_DIRECTORY_SERVER
Purpose:
Specifies the destination directory of the trace file.
Default Value:
ORACLE_HOME/network/trace
Example:
TRACE_DIRECTORY_SERVER=/oracle/traces
TRACE_FILE_SERVER
Purpose:
Specifies the name of the server trace file.
Default Value:
SERVER.TRC
Example:
TRACE_FILE_SERVER= svr_Connection1.trc
Note: Ensure that the name you choose for the TRACE_FILE_
SERVER file is different from the name you choose for the TRACE_
FILE_CLIENT file.
This appendix briefly discusses the general structure of JDBC error messages, then lists
general JDBC error messages and TTC error messages that the Oracle JDBC drivers
can return. The appendix is organized as follows:
■ General Structure of JDBC Error Messages
■ General JDBC Messages
■ HeteroRM XA Messages
■ TTC Messages
Each of the message lists is first sorted by ORA number, and then alphabetically.
For general information about processing JDBC exceptions, see "Processing SQL
Exceptions" on page 4-25.
This indicates that the exception was thrown during a call to the next() method (of a
result set object).
In some cases, the user can find the same information in a stack trace.
HeteroRM XA Messages
The following are the JDBC error messages that are specific to the HeteroRM XA
feature.
TTC Messages
This section lists TTC error messages, first sorted by ORA number, and then
alphabetically.
Index-1
BLOB (cont’d), CODE, parameter for APPLET tag, 23-14
size limit with PL/SQL prodcedures, 14-4 CODEBASE, parameter for APPLET tag, 23-14
writing data, 14-6 collections
Boolean parameters, restrictions, 26-7 defined, 16-1
branch qualifier (distributed transactions), 9-12 collections (nested tables and arrays), 16-8
column types
defining, 22-18
C
redefining, 22-15
CachedRowSet, 18-4 commit a distributed transaction branch, 9-11
caching, client-side commit changes to database, 4-11
custom use for scrollable result sets, 17-4 compatibility
Oracle use for scrollable result sets, 17-4 forward and backward, 1-8
callable statement CONCUR_READ_ONLY result sets, 17-6
getting a BFILE locator, 14-16 CONCUR_UPDATABLE result sets, 17-6
getting LOB locators, 14-3 concurrency types in result sets, 17-3
passing BFILE locator, 14-16 connect string
passing LOB locators, 14-4 Connection Manager, 23-10
using getOracleObject() method, 11-4 connection
cancelRowUpdates() method (result set), 17-13 closing, 4-11
casting return values, 11-8 from KPRB driver, 1-7
catalog arguments (DatabaseMetaData), 24-12 opening, 4-2
CHAR class opening for JDBC Thin driver, 3-10
conversions with KPRB driver, 23-20 Connection Manager, 23-8
CHAR columns installing, 23-9
space padding, 26-7 starting, 23-9
using setFixedCHAR() to match in using, 23-8
WHERE, 11-12 using multiple managers, 23-10
character sets, 10-22 writing the connect string, 23-10
conversions with KPRB driver, 23-20 connection methods, JDBC 2.0 result sets, 17-21
checksums connection properties
code example, 23-6 database, 4-3
setting parameters in Java, 23-5 defaultBatchValue, 4-3
support by OCI drivers, 23-3 defaultRowPrefetch, 4-3
support by Thin driver, 23-4 includeSynonyms, 4-4
CLASSPATH, specifying, 2-3 internal_logon, 4-4
clearBatch() method, 22-10 sysdba, 4-6
clearClientIdentifier() method, 10-13 sysoper, 4-6
clearDefines() method, 22-18 password, 4-5
CLOB put() method, 4-8
class, 10-9 remarksReporting, 4-5
creating and populating, 14-7 user, 4-5
creating columns, 14-7 connections
interface changes, 5-7 read-only, 26-11
introduction, 14-2 constants for SQL types, 10-17
locators, 14-2 CREATE DIRECTORY statement
getting from result set, 14-3 for BFILEs, 14-17
passing to callable statements, 14-4 CREATE TABLE statement
passing to prepared statement, 14-4 to create BFILE columns, 14-17
locators, selecting, 10-9 to create BLOB, CLOB columns, 14-7
manipulating data, 14-8 CREATE TYPE statement, 13-21
populating columns, 14-8 create() method
reading data, 14-4, 14-6 for ORADataFactory interface, 13-16
writing data, 14-6 createDescriptor() method, 13-4, 16-10
close(), 6-3 createStatement(), 6-3
close() method, 10-14, 10-15, 10-16, 26-7 createStatement() method, 6-7, 10-13
for caching statements, 6-5, 6-6 createTemporary() method, 14-13
closeFile() method, 14-20 creationState() method, 6-5
closeWithKey(), 6-3 code example, 6-5
closeWithKey() method, 6-7 CursorName
CMAN.ORA file, creating, 23-9 limitations, 24-11
Index-2
cursors, 26-7 defaultConnection() method, 23-15
custom collection classes defaultExecuteBatch connection property, 4-3
and JPublisher, 16-19 defaultNchar connection property, 4-3
defined, 16-2, 16-18 defaultRowPrefetch connection property, 4-3
custom Java classes, 10-3 defineColumnType() method, 4-18, 10-14, 22-18
defined, 13-1 DELETE in a result set, 17-12
custom object classes deleteRow() method (result set), 17-12
creating, 13-7 deletesAreDetected() method (database meta
defined, 13-1 data), 17-19
custom reference classes deserialization
and JPublisher, 15-5 ArrayDescriptor object, 16-10
defined, 15-1, 15-5 creating a StructDescriptor object, 13-5
creating an ArrayDescriptor object, 16-11
definition of, 13-5, 16-10
D
StructDescriptor object, 13-5
data conversions, 11-1 disableDefineColumnType connection property, 4-4
LONG, 4-16 disabling
LONG RAW, 4-16 escape processing, 4-5
data sources distributed transaction ID component, 9-12
creating and connecting (with JNDI), 3-6 distributed transactions
creating and connecting (without JNDI), 3-6 branch qualifier, 9-12
logging and tracing, 3-7 check for same resource manager, 9-11
Oracle implementation, 3-2 commit a transaction branch, 9-11
PrintWriter, 3-7 components and scenarios, 9-2
properties, 3-2 concepts, 9-2
standard interface, 3-2 distributed transaction ID component, 9-12
data streaming end a transaction branch, 9-9
avoiding, 4-18 example of implementation, 9-15
database global transaction identifier, 9-12
connecting ID format identifier, 9-12
from an applet, 23-7 introduction, 9-1
via multiple Connection Managers, 23-10 Oracle XA connection implementation, 9-6
with server-side internal driver, 23-15 Oracle XA data source implementation, 9-5
connection testing, 2-5 Oracle XA ID implementation, 9-12
database connection Oracle XA optimizations, 9-14
connection property, 4-3 Oracle XA resource implementation, 9-7
database meta data methods, JDBC 2.0 result prepare a transaction branch, 9-10
sets, 17-24 roll back a transaction branch, 9-11
database specifiers, 3-8 start a transaction branch, 9-8
database URL transaction branch ID component, 9-12
including userid and password, 4-3 XA connection interface, 9-6
database URL, specifying, 4-2 XA data source interface, 9-5
database URLs XA error handling, 9-14
and database specifiers, 3-8 XA exception classes, 9-13
DatabaseMetaData calls, 24-12 XA ID interface, 9-12
DatabaseMetaData class, 24-9 XA resource functionality, 9-8
entry points for applets, 23-13 XA resource interface, 9-7
datasources, 3-1 DMS
and JNDI, 3-6 to 3-7 and end-to-end matrics, 21-1
datatype classes, 10-5 DMSName connection property, 4-4
datatype mappings, 4-12 DMSType connection property, 4-4
datatypes Double.NaN
Java, 4-12 restrictions on use, 10-9
Java native, 4-12 driverType, 3-4
JDBC, 4-12
Oracle SQL, 4-12
DATE class, 10-9
debugging JDBC programs, 26-8
DEFAULT_CHARSET character set value, 10-22
defaultBatchValue connection property, 4-3
Index-3
E Float.NaN
restrictions on use, 10-9
encryption format identifier, transaction ID, 9-12
code example, 23-6
forward-only result sets, 17-2
overview, 23-2
freeTemporary() method, 14-13
setting parameters in Java, 23-5 function call syntax, SQL92 syntax, 24-10
support by OCI drivers, 23-3
support by Thin driver, 23-4
end a distributed transaction branch, 9-9 G
end-to-end matrics getARRAY() method, 16-11
and DMS, 21-1 getArray() method, 16-5, 16-7, 16-11
end-to-end metrics, 21-1 to 21-2 using type maps, 16-13
Enterprise Java Beans (EJB), 18-7 getArrayType() method, 16-10
environment variables getAsciiStream() method, 14-10
specifying, 2-3 for reading CLOB data, 14-5
errors getAttributes() method
general JDBC message structure, A-1 used by Structs, 13-11
general JDBC messages, listed, A-2 getAutoBuffering() method
processing exceptions, 4-25 of the oracle.sql.ARRAY class, 16-6
TTC messages, listed, A-10 of the oracle.sql.STRUCT class, 13-7
escape processing getBaseName() method, 16-10
disabling, 4-5 getBaseType() method, 16-5, 16-10, 16-14
exceptions getBaseTypeName() method, 15-3, 16-5
printing stack trace, 4-26 getBinaryStream() method, 4-17, 14-20
retrieving error code, 4-25 for reading BFILE data, 14-17
retrieving message, 4-25 for reading BLOB data, 14-5
retrieving SQL state, 4-25 getBufferSize() method, 14-9, 14-10
execute() method, 18-8 getBytes() method, 4-18, 10-7, 14-9, 14-20
executeBatch() method, 22-9 getCallWithKey(), 6-3
executeQuery() method, 10-14 getCallWithKey() method, 6-8
executeUpdate() method, 22-7 getCharacterStream() method, 14-10
explicit statement caching for reading CLOB data, 14-5
definition of, 6-2 getChars() method, 14-11
null data, 6-8 getChunkSize() method, 14-10, 14-11
extensions to JDBC, Oracle, 10-1, 11-1, 13-1, 15-1, getColumnCount() method, 11-13
16-1, 22-1 getColumnName() method, 11-13
external changes (result set) getColumns() method, 22-20
defined, 17-17 getColumnType() method, 11-13
seeing, 17-18 getColumnTypeName() method, 11-13
visibility vs. detection, 17-19 getConcurrency() method (result set), 17-8
external file getConnection() method, 16-10, 19-7, 23-15
defined, 4-21 getCursor() method, 10-24, 10-25
getCursorName() method
F limitations, 24-11
getDefaultExecuteBatch() method, 10-13, 22-5
failover
getDefaultRowPrefetch() method, 10-13, 22-16
fast connection, 8-1 to 8-7 getDescriptor() method, 13-3, 16-5
fast connection failover, 8-1 to 8-7
getDirAlias() method, 14-19, 14-20
prerequisites, 8-2
getErrorCode() method (SQLException), 4-25
fetch direction in result sets, 17-11 getExecuteBatch() method, 10-14, 22-5
fetch size, result sets, 17-15
getFetchSize() method, 17-16
finalizer methods, 26-7
getJavaSQLConnection() method, 13-3, 16-5
firewalls getJavaSqlConnection() method, 10-19
configuring for applets, 23-11
getMaxLength() method, 16-10
connect string, 23-12
getMessage() method (SQLException), 4-25
described, 23-11 getName() method, 14-19, 14-20
required rule list items, 23-12
getNumericFunctions() method, 24-9
using with applets, 1-6, 23-11
first() method (result sets), 17-9
fixedString connection property, 4-4
floating-point compliance, 24-12
Index-4
getObject() method Oracle extended properties, 3-5
casting return values, 11-8 global transaction identifier (distributed
for object references, 15-3 transactions), 9-12
for ORAData objects, 13-16 global transactions, 9-1
for SQLInput streams, 13-12 globalization, 12-1 to 12-3
for SQLOutput streams, 13-12 Java methods that employ, 12-3
for Struct objects, 13-5 using, 12-1
return types, 11-3, 11-5
to get BFILE locators, 14-15
H
to get Oracle objects, 13-6
used with ORAData interface, 13-18 HEIGHT, parameter for APPLET tag, 23-14
getOracleArray() method, 16-5, 16-11, 16-14 HTML tags, to deploy applets, 23-14
getOracleAttributes() method, 13-3, 13-6 HTTP protocol, 1-3
getOracleObject() method, 10-15, 10-17
casting return values, 11-8 I
return types, 11-4, 11-5
using in callable statement, 11-4 IEEE 754 floating-point compliance, 24-12
using in result set, 11-4 implicit statement caching
getOraclePlsqlIndexTable() method, 19-11, 19-14 definition of, 6-2
argument Least Recently Used (LRU) scheme, 6-2
int paramIndex, 19-15 IN OUT parameter mode, 19-13
code example, 19-15 IN parameter mode, 19-11
getORAData() method, 13-16, 13-18 includeSynonyms connection property, 4-4
getPassword() method, 3-3 INSERT in a result set, 17-14
getPlsqlIndexTable() method, 19-11, 19-14, 19-15 INSERT INTO statement
arguments for creating BFILE columns, 14-18
Class primitiveType, 19-16 insertRow() method (result set), 17-14
int paramIndex, 19-16 insertsAreDetected() method (database meta
code example, 19-14, 19-16 data), 17-19
getProcedureColumns() method, 22-20 installation
getProcedures() method, 22-20 directories and files, 2-2
getREF() method, 15-4 verifying on the client, 2-2
getResultSet() method, 10-14, 16-5 Instant Client feature, 20-1
getRow() method (result set), 17-10 integrity
getRowPrefetch() method, 10-14, 22-16 code example, 23-6
getSQLState() method (SQLException), 4-25 overview, 23-2
getSQLTypeName() method, 13-2, 16-5, 16-14 setting parameters in Java, 23-5
getStatementCacheSize() method support by OCI drivers, 23-3
code example, 6-5 support by Thin driver, 23-4
getStatementWithKey(), 6-3 internal changes (result set)
getStatementWithKey() method, 6-8 defined, 17-17
getString() method, 10-22 seeing, 17-18
to get ROWIDs, 10-23 internal_logon connection property, 4-4
getStringFunctions() method, 24-9 sysdba, 4-6
getStringWithReplacement() method, 10-22 sysoper, 4-6
getSTRUCT() method, 13-6 isAfterLast() method (result set), 17-10
getSubString() method, 14-11 isBeforeFirst() method (result set), 17-10
for reading CLOB data, 14-5 isFileOpen() method, 14-20
getSystemFunctions() method, 24-9 isFirst() method (result set), 17-10
getTimeDateFunctions() method, 24-9 isLast() method (result set), 17-10
getTransactionIsolation() method, 10-13, 26-11 isSameRM() (distributed transactions), 9-11
getType() method (result set), 17-8 isTemporary() method, 14-13
getTypeMap() method, 10-13, 13-10
getUpdateCounts() method J
(BatchUpdateException), 22-12
Java
getValue() method, 15-3
for object references, 15-3 compiling and running, 2-4
getXXX() methods datatypes, 4-12
native datatypes, 4-12
casting return values, 11-8
for specific datatypes, 11-6 stored procedures, 4-25
stream data, 4-15
Index-5
Java Naming and Directory Interface (JNDI), 3-1 type mapping modes and settings, 13-33
Java Sockets, 1-3 type mappings, 13-33
Java virtual machine (JVM), 1-5, 23-15 JVM, 1-5, 23-15
JavaBeans, 18-1
java.math, Java math packages, 4-2
K
JavaSoft, 18-1
java.sql, JDBC packages, 4-2 KPRB driver
java.sql.SQLException() method, 4-25 described, 1-5
java.sql.Struct class relation to the SQL engine, 23-15
getSQLTypeName() method, 13-2 session context, 23-18
java.sql.Types class, 22-18 testing, 23-18
java.util.Map class, 16-14 transaction context, 23-18
java.util.Properties, 19-5 URL for, 23-16
JDBC
and IDEs, 1-8 L
basic program, 4-1
datatypes, 4-12 last() method (result set), 17-9
defined, 1-1 LD_LIBRARY_PATH variable, specifying, 2-4
importing packages, 4-2 LDAP
limitations of Oracle extensions, 24-11 and SSL, 3-9
sample files, 2-4 Least Recently Used (LRU) scheme, 6-2, 19-5
testing, 2-5 length() method, 14-10, 14-11, 14-20, 16-5
version compatibility, 1-8 libheteroxa10.so Solaris shared library, 19-10
version support, 5-1 to 5-7 libheteroxa9_g.so Solaris shared library, 19-10
JDBC 2.0 support libheteroxa9.so Solaris shared library, 19-10
datatype support, 5-2 LIKE escape characters, SQL92 syntax, 24-9
extended feature support, 5-2 limitations on setBytes() and setString(), use of
introduction, 5-1 streams to avoid, 4-23
JDK 1.2.x vs. JDK 1.1.x, 5-2, 5-3 LOB
overview of features, 5-4 defined, 4-21
standard feature support, 5-2 introduction, 14-2
JDBC drivers locators, 14-2
applets, 1-6 reading data, 14-4
choosing a driver for your needs, 1-5 LOB locators
common features, 1-3 getting from callable statements, 14-3
common problems, 26-7 passing, 14-4
determining driver version, 2-4 LOBs
introduction, 1-2 empty, 14-12
restrictions, 26-7 new interface methods, 5-7
SQL92 syntax, 24-7 locators
JDBC mapping (for attributes), 13-33 getting for BFILEs, 14-15
JdbcCheckup program, 2-5 getting for BLOBs, 14-2
JDBCSpy, 26-11 getting for CLOBs, 14-2
JDBCTest, 26-11 LOB, 14-2
JDeveloper, 1-8 passing to callable statements, 14-4
Jdeveloper, 18-2 passing to prepared statement, 14-4
JDK logging with a data source, 3-7
migration from 1.1.x to 1.2.x, 5-3 LONG
versions supported, 1-7 data conversions, 4-16
JNDI LONG RAW
and datasources, 3-6 to 3-7 data conversions, 4-16
looking up data source, 3-7 LRU scheme, 6-2, 19-5
overview of Oracle support, 3-1
registering data source, 3-7 M
JPublisher, 13-18, 13-32
make() method, 10-21
JPublisher utility, 13-8
creating custom collection classes, 16-18 memory leaks, 26-7
creating custom Java classes, 13-32 metrics
end-to-end, 21-1 to 21-2
creating custom reference classes, 15-5
SQL type categories and mapping options, 13-33 migration from JDK 1.1.x to 1.2.x, 5-3
moveToCurrentRow() method (result set), 17-14
Index-6
moveToInsertRow() method (result set), 17-14 PL/SQL TABLE, BOOLEAN, RECORD
mutable arrays, 16-19 types, 24-11
read-only connection, 26-11
SQL92 outer join escapes, 24-11
N
SQLWarning class, 24-12
named arrays, 16-1 object support, 10-3
defined, 16-8 packages, 10-2
nativeXA, 3-4, 19-9 result sets, 11-2
NC, 18-7 schema naming support, 10-4
Network Computer (NC), 18-7 statements, 11-2
network events, trapping, 26-8 to JDBC, 10-1, 11-1, 13-1, 15-1, 16-1, 22-1
next() method, 18-5 Oracle JPublisher, 10-3
next() method (result set), 17-10 generated classes, 13-27
NLS. See globalization Oracle mapping (for attributes), 13-33
NLS_LANG variable Oracle Net
desupported, 12-1 protocol, 1-3
NULL Oracle Notification Service. See ONS
testing for, 11-2 Oracle objects
NULL data and JDBC, 13-1
converting, 11-2 converting with ORAData interface, 13-15
null data converting with SQLData interface, 13-11
explicit statement caching, 6-8 getting with getObject() method, 13-6
NullPointerException Java classes which support, 13-2
thrown when converting Double.NaN and mapping to custom object classes, 13-7
Float.NaN, 10-9 reading data by using SQLData interface, 13-13
NUMBER class, 10-9 working with, 13-1
writing data by using SQLData interface, 13-15
O Oracle SQL datatypes, 4-12
OracleCallableStatement interface, 10-15
object references getOraclePlsqlIndexTable() method, 19-11
accessing object values, 15-3, 15-5 getPlsqlIndexTable() method, 19-11
described, 15-1 getTIMESTAMP(), 10-10
passing to prepared statements, 15-4 getTIMESTAMPLTZ(), 10-10
retrieving, 15-3 getTIMESTAMPTZ(), 10-10
retrieving from callable statement, 15-4 getXXX() methods, 11-6
updating object values, 15-3, 15-5 registerIndexTableOutParameter()
object-JDBC mapping (for attributes), 13-33 method, 19-11, 19-13
OCI driver registerOutParameter() method, 11-9
described, 1-3 setPlsqlIndexTable() method, 19-11
ODBCSpy, 26-11 OracleCallableStatement object, 6-2
ODBCTest, 26-11 OracleConnection class, 10-13
ONS OracleConnection interface, 19-2
configuring, 8-2 to 8-3 OracleConnection object, 6-1
ons.config file, 8-2, 8-3, 8-4 OracleDatabaseMetaData class, 24-9
openFile() method, 14-20 and applets, 23-13
optimization, performance, 26-4 OracleDataSource class, 3-2, 19-2
Oracle Advanced Security oracle.jdbc. package, 10-11
support by JDBC, 23-1 oracle.jdbc., Oracle JDBC extensions, 4-2
support by OCI drivers, 23-1 oracle.jdbc.J2EE13Compliant connection
support by Thin driver, 23-2 property, 4-4
Oracle Connection Manager, 1-6, 23-8 oracle.jdbc.ocinativelibrary connection property, 4-5
Oracle datatypes oracle.jdbc.OracleCallableStatement interface, 10-15
using, 11-1 close() method, 10-16
Oracle extensions getOracleObject() method, 10-15
datatype support, 10-2 getXXX() methods, 10-15, 10-17
limitations, 24-11 registerOutParameter() method, 10-16
catalog arguments to DatabaseMetaData setNull() method, 10-16
calls, 24-12 setOracleObject() methods, 10-15
CursorName, 24-11 setXXX() methods, 10-15
IEEE 754 floating-point compliance, 24-12 oracle.jdbc.OracleConnection interface, 10-13
Index-7
clearClientIdentifier() method, 10-13 OracleResultSetMetaData interface, 10-17
createStatement() method, 10-13 OracleServerDriver class
getDefaultExecuteBatch() method, 10-13 defaultConnection() method, 23-16
getDefaultRowPrefetch() method, 10-13 oracle.sql datatype classes, 10-5
getTransactionIsolation() method, 10-13, 26-11 oracle.sql package
getTypeMap() method, 10-13 data conversions, 11-1
prepareCall() method, 10-13 described, 10-5
prepareStatement() method, 10-13 oracle.sql.ARRAY class, 16-2
setClientIdentifier() method, 10-13 and nested tables, 10-8
setDefaultExecuteBatch() method, 10-13 and VARRAYs, 10-8
setDefaultRowPrefetch() method, 10-13 createDescriptor() method, 16-10
setTransactionIsolation() method, 10-13, 26-11 getArray() method, 16-5
setTypeMap() method, 10-13 getArrayType() method, 16-10
oracle.jdbc.OraclePreparedStatement getAutoBuffering() method, 16-6
interface, 10-14 getBaseType() method, 16-5
close() method, 10-15 getBaseTypeName() method, 16-5
getExecuteBatch() method, 10-14 getDescriptor() method, 16-5
setExecuteBatch() method, 10-14 getJavaSQLConnection() method, 16-5, 16-10
setNull() method, 10-15 getMaxLength() method, 16-10
setOracleObject() method, 10-14 getOracleArray() method, 16-5
setORAData() method, 10-15 getResultSet() method, 16-5
setXXX() methods, 10-14 getSQLTypeName() method, 16-5
oracle.jdbc.OracleResultSet, 11-3 length() method, 16-5
oracle.jdbc.OracleResultSet interface, 10-17 methods for Java primitive types, 16-6
getOracleObject() method, 10-17 setAutoBuffering() method, 16-6
oracle.jdbc.OracleResultSetMetaData setAutoIndexing() method, 16-7
interface, 10-17, 11-13 oracle.sql.ArrayDescriptor class
getColumnCount() method, 11-13 getBaseName() method, 16-10
getColumnName() method, 11-13 getBaseType() method, 16-10
getColumnType() method, 11-13 oracle.sql.BFILE class, 10-9
getColumnTypeName() method, 11-13 closeFile() method, 14-20
using, 11-13 getBinaryStream() method, 14-20
oracle.jdbc.OracleSql class, 24-10 getBytes() method, 14-20
oracle.jdbc.OracleStatement, 11-3 getDirAlias() method, 14-20
oracle.jdbc.OracleStatement interface, 10-13 getName() method, 14-20
close() method, 10-14 isFileOpen() method, 14-20
defineColumnType(), 10-14 length() method, 14-20
executeQuery() method, 10-14 openFile() method, 14-20
getResultSet() method, 10-14 position() method, 14-20
getRowPrefetch() method, 10-14 oracle.sql.BLOB class, 10-9
setRowPrefetch() method, 10-14 getBufferSize() method, 14-9
oracle.jdbc.OracleTypes class, 10-17, 22-18 getBytes() method, 14-9
oracle.jdbc.pool package, 19-3 getChunkSize() method, 14-10
oracle.jdbc.TcpNoDelay connection property, 4-5 length() method, 14-10
oracle.jdbc.xa package and subpackages, 9-5 position() method, 14-10
OracleOCIConnection class, 19-2 putBytes() method, 14-10
OracleOCIConnectionPool class, 19-1, 19-2 setBinaryStream() method, 14-9
OraclePooledConnection object, 6-1 oracle.sql.CHAR class, 23-20
OraclePreparedStatement interface, 10-14 getString() method, 10-22
getOraclePlsqlIndexTable() method, 19-11 getStringWithReplacement() method, 10-22
getPlsqlIndexTable() method, 19-11 toString() method, 10-22
registerIndexTableOutParameter() method, 19-11 oracle.sql.CharacterSet class, 10-21
setPlsqlIndexTable() method, 19-11 oracle.sql.CLOB class, 10-9
setTIMESTAMP(), 10-10 getAsciiStream() method, 14-10
setTIMESTAMPLTZ(), 10-10 getBufferSize() method, 14-10
setTIMESTAMPTZ(), 10-10 getCharacterStream() method, 14-10
OraclePreparedStatement object, 6-2 getChars() method, 14-11
OracleResultSet interface, 10-17 getChunkSize() method, 14-11
getXXX() methods, 11-6 getSubString() method, 14-11
OracleResultSetCache interface, 17-4 length() method, 14-11
Index-8
position() method, 14-11 P
putChars() method, 14-11
setAsciiStream() method, 14-10 parameter modes
IN, 19-11
setCharacterStream() method, 14-10
IN OUT, 19-13
setString() method, 14-11
supported character sets, 14-9 OUT, 19-13, 19-14
password connection property, 4-5
oracle.sql.datatypes
password, specifying, 4-2
support, 10-6
oracle.sql.DATE class, 10-9 PATH variable, specifying, 2-4
PDA, 18-7
oracle.sql.Datum array, 19-15
performance enhancements, standard vs. Oracle, 5-2
oracle.sql.Datum class, described, 10-5
oracle.sql.NUMBER class, 10-9 performance extensions
defining column types, 22-18
oracle.sql.ORAData interface, 13-15
prefetching rows, 22-15
oracle.sql.ORADataFactory interface, 13-15
OracleSql.parse() method, 24-10 TABLE_REMARKS reporting, 22-20
performance optimization, 26-4
oracle.sql.RAW class, 10-9
Personal Digital Assistant (PDA), 18-7
oracle.sql.REF class, 10-8, 15-1
getBaseTypeName() method, 15-3 PL/SQL
limit on BLOB size, 14-4
getValue() method, 15-3
restrictions, 26-7
setValue() method, 15-3
oracle.sql.ROWID class, 10-7, 10-11, 10-23 space padding, 26-7
stored procedures, 4-24
oracle.sql.STRUCT class, 10-7, 13-3
PL/SQL index-by tables
getAutoBuffering() method, 13-7
getDescriptor() method, 13-3 mapping, 19-14
scalar datatypes, 19-10
getJavaSQLConnection() method, 13-3
PL/SQL types
getOracleAttributes() method, 13-3
setAutoBuffering() method, 13-7 corresponding JDBC types, 19-10
limitations, 24-11
toJDBC() method, 13-3
PoolConfig() method, 19-5
oracle.sql.StructDescriptor class
createDescriptor() method, 13-4 populate() method, 18-5
position() method, 14-10, 14-11, 14-20
OracleStatement interface, 10-13
positioning in result sets, 17-2
OracleTypes class, 10-17
OracleTypes class for typecodes, 10-17 prefetching rows, 22-15
OracleTypes.CURSOR variable, 10-25 suggested default, 22-17
prepare a distributed transaction branch, 9-10
OracleXAConnection class, 9-6
OracleXADataSource class, 9-5 prepareCall(), 6-3
OracleXAResource class, 9-7, 9-8 prepareCall() method, 6-6, 6-7, 10-13
prepared statement
OracleXid class, 9-12
ORAData interface, 10-3 passing BFILE locator, 14-16
additional uses, 13-19 passing LOB locators, 14-4
PreparedStatement object
advantages, 13-8
Oracle object types, 13-1 creating, 4-10
reading data, 13-17 prepareStatement(), 6-3
prepareStatement() method, 6-6, 6-7, 10-13
writing data, 13-18
orai18n.jar file, 12-2 code example, 6-6
othersDeletesAreVisible() method (database meta previous() method (result set), 17-10
printStackTrace() method (SQLException), 4-26
data), 17-19
othersInsertsAreVisible() method (database meta PrintWriter for a data source, 3-7
data), 17-19 processEscapes
connection property, 4-5
othersUpdatesAreVisible() method (database meta
data), 17-19 put() method
OUT parameter mode, 19-13, 19-14 for Properties object, 4-8
for type maps, 13-9, 13-10
outer joins, SQL92 syntax, 24-10
ownDeletesAreVisible() method (database meta putBytes() method, 14-10
deta), 17-18 putChars() method, 14-11
ownInsertsAreVisible() method (database meta
data), 17-18 Q
ownUpdatesAreVisible() method (database meta
query, executing, 4-9
data), 17-18
Index-9
R result set fetch size, 17-15
result set methods, JDBC 2.0, 17-21
racgons, 8-4 result set object
RAW class, 10-9
closing, 4-9
RDBMS, 1-3
result set types for scrollability and sensitivity, 17-2
read-only result set concurrency type, 17-3 result set, processing, 4-9
readSQL() method, 13-11, 13-12
ResultSet class, 4-9
implementing, 13-12
ResultSet() method, 16-7
REF class, 10-8 return types
REF CURSORs, 10-24
for getXXX() methods, 11-6
materialized as result set objects, 10-24
getObject() method, 11-5
refetching rows into a result set, 17-16, 17-19 getOracleObject() method, 11-5
refreshRow() method (result set), 17-16
return values
registerIndexTableOutParameter() method, 19-11,
casting, 11-8
19-13 RMI, 18-6
arguments
roll back a distributed transaction branch, 9-11
int elemMaxLen, 19-13
roll back changes to database, 4-11
int elemSqlType, 19-13 row prefetching, 22-15
int maxLen, 19-13
and data streams, 4-23
int paramIndex, 19-13
ROWID class, 10-11
code example, 19-13 CursorName methods, 24-11
registerOutParameter() method, 10-16, 11-9
defined, 10-23
Relational Database Management System
ROWID, use for result set updates, 17-4
(RDBMS), 1-3
relative positioning in result sets, 17-2
relative() method (result set), 17-9 S
remarksReporting connection property, 4-5 savepoints
remarksReporting flag, 22-15 transaction, 5-4 to 5-6
Remote Method Invocation (RMI), 18-6 scalar functions, SQL92 syntax, 24-9
resource managers, 9-2 schema naming conventions, 10-4
restrictGetTables connection property, 4-5 scrollability in result sets, 17-2
result set scrollable result sets
auto-commit mode, 26-4 creating, 17-5
getting BFILE locators, 14-15 fetch direction, 17-11
getting LOB locators, 14-3 implementation of scroll-sensitivity, 17-20
metadata, 10-17 positioning, 17-8
Oracle extensions, 11-2 processing backward/forward, 17-10
using getOracleObject() method, 11-4 refetching rows, 17-16, 17-19
result set enhancemennts scroll-insensitive result sets, 17-2
positioning result sets, 17-8 scroll-sensitive result sets, 17-2
result set enhancements seeing external changes, 17-18
concurrency types, 17-3 visibility vs. detection of external changes, 17-19
downgrade rules, 17-7 scroll-sensitive result sets
fetch size, 17-15 limitations, 17-7
limitations, 17-6 security
Oracle scrollability requirements, 17-4 authentication, 23-2
Oracle updatability requirements, 17-4 encryption, 23-2
positioning, 17-2 integrity, 23-2
processing result sets, 17-10 Oracle Advanced Security support, 23-1
refetching rows, 17-16, 17-19 overview, 23-1
result set types, 17-2 SELECT statement
scrollability, 17-2 to retrieve object references, 15-3
seeing external changes, 17-18 to select LOB locator, 14-9
seeing internal changes, 17-18 sendBatch() method, 22-5, 22-7
sensitivity to database changes, 17-2 sensitivity in result sets to database changes, 17-2
specifying scrollability, updatability, 17-5 serialization
summary of methods, 17-21 ArrayDescriptor object, 16-10
summary of visibility of changes, 17-20 definition of, 13-5, 16-10
updatability, 17-2 StructDescriptor object, 13-5
updating result sets, 17-11 server connection property, 4-5
visibility vs. detection of external changes, 17-19
Index-10
server-side internal driver int paramIndex, 19-12, 19-14
connection to database, 23-15 Object arrayData, 19-12
server-side Thin driver, described, 1-4 code example, 19-12
session context, 1-7 setPoolConfig() method, 19-5
for KPRB driver, 23-18 setREF() method, 15-4
setAsciiStream() method, 11-12 setRemarksReporting() method, 22-20
for writing CLOB data, 14-5 setResultSetCache() method, 17-5
setAutoBuffering() method setRowPrefetch() method, 10-14, 22-16
of the oracle.sql.ARRAY class, 16-6 setString() limitations, using streams to avoid, 4-23
of the oracle.sql.STRUCT class, 13-7 setString() method, 14-11
setAutoCommit() method, 26-4 to bind ROWIDs, 10-23
setAutoIndexing() method, 16-7 setTime() method, 11-12
direction parameter values setTimestamp() method, 11-12
ARRAY.ACCESS_FORWARD, 16-7 setTransactionIsolation() method, 10-13, 26-11
ARRAY.ACCESS_REVERSE, 16-7 setTypeMap() method, 10-13
ARRAY.ACCESS_UNKNOWN, 16-7 setUnicodeStream() method, 11-12
setBFILE() method, 14-16 setValue() method, 15-3
setBinaryStream() method, 11-12, 14-9 setXXX() methods
for writing BLOB data, 14-5 Oracle extended properties, 3-5
setBLOB() method, 14-4 setXXX() methods, for empty LOBs, 14-12
setBlob() method, JDK 1.2.x, 14-4 setXXX() methods, for specific datatypes, 11-9
setBytes() limitations, using streams to avoid, 4-23 signed applets, 1-6
setCharacterStream() method, 11-12 Solaris
for writing CLOB data, 14-5 shared libraries
setClientIdentifier() method, 10-13 libheteroxa10_g.so, 19-10
setCLOB() method, 14-4 libheteroxa9.so, 19-10
setClob() method, JDK 1.2.x, 14-4 specifiers
setConnection() method database, 3-8
ArrayDescriptor object, 16-11 SQL
StructDescriptor object, 13-5 data converting to Java datatypes, 11-1
setCursorName() method, 24-11 types, constants for, 10-17
setDate() method, 11-12 SQL engine
setDefaultExecuteBatch() method, 10-13, 22-4 relation to the KPRB driver, 23-15
setDefaultRowPrefetch() method, 10-13, 22-16 SQL syntax (Oracle), 24-7
setDisableStatementCaching() method, 6-6 SQL92 syntax, 24-7
setEscapeProcessing() method, 24-7 function call syntax, 24-10
setExecuteBatch() method, 10-14, 22-5 LIKE escape characters, 24-9
setFetchSize() method, 17-16 outer joins, 24-10
setFixedCHAR() method, 11-12 scalar functions, 24-9
setFormOfUse() method, 10-20 time and date literals, 24-8
setMaxFieldSize() method, 22-18 translating to SQL example, 24-10
setNull(), 11-2 SQLData interface, 10-3
setNull() method, 10-15, 10-16, 11-9 advantages, 13-8
setObejct() method, 11-9 described, 13-11
setObject() method Oracle object types, 13-1
for BFILES, 14-16 reading data from Oracle objects, 13-13
for CustomDatum objects, 13-17 using with type map, 13-11
for object references, 15-4 writing data from Oracle objects, 13-15
for STRUCT objects, 13-6 SQLInput interface, 13-11
to write object data, 13-19 described, 13-11
setOracleObject() method, 10-14, 10-15, 11-9 SQLInput streams, 13-12
for BFILES, 14-16 SQLNET.ORA
for BLOBs and CLOBs, 14-4 parameters for tracing, 26-9
setORAData() method, 10-15, 13-16, 13-19 SQLOutput interface, 13-11
setPlsqlIndexTable() method, 19-11 described, 13-11
arguments SQLOutput streams, 13-12
int curLen, 19-12 SQLWarning class, limitations, 24-12
int elemMaxLen, 19-12 SSL
int elemSqlType, 19-12 and LDAP, 3-9
int maxLen, 19-12 start a distributed transaction branch, 9-8
Index-11
statement caching applets, 23-7
explicit applications, 1-6
definition of, 6-2 described, 1-3
null data, 6-8 LDAP over SSL, 3-9
implicit server-side, described, 1-4
definition of, 6-2 time and date literals, SQL92 syntax, 24-8
Least Recently Used (LRU) scheme, 6-2 tnsEntry, 3-4, 19-9
statement methods, JDBC 2.0 result sets, 17-23 toDatum() method
Statement object applied to CustomDatum objects, 13-8, 13-16
closing, 4-9 called by setORAData() method, 13-19
creating, 4-9 toJDBC() method, 13-3
statements toJdbc() method, 10-7
Oracle extensions, 11-2 toString() method, 10-22
stored procedures trace facility, 26-8
Java, 4-25 trace parameters
PL/SQL, 4-24 client-side, 26-9
stream data, 4-15, 14-4 server-side, 26-10
CHAR columns, 4-19 tracing with a data source, 3-7
closing, 4-21 transaction branch, 9-1
example, 4-17 transaction branch ID component, 9-12
external files, 4-21 transaction context, 1-7
LOBs, 4-21 for KPRB driver, 23-18
LONG columns, 4-15 transaction IDs (distributed transactions), 9-3
LONG RAW columns, 4-15 transaction managers, 9-2
multiple columns, 4-19 transaction savepoints, 5-4 to 5-6
precautions, 4-22 transactions
RAW columns, 4-19 switching between local and global, 9-4 to 9-5
row prefetching, 4-23 Transparent Application Failover (TAF), definition
UPDATE/COMMIT statements, 14-5 of, 19-8
use to avoid setBytes() and setString() TTC error messages, listed, A-10
limitations, 4-23 TTC protocol, 1-3, 1-4
VARCHAR columns, 4-19 type map, 10-3, 11-4
stream data column adding entries, 13-10
bypassing, 4-20 and STRUCTs, 13-11
STRUCT class, 10-7 creating a new map, 13-10
STRUCT descriptor, 13-4 used with arrays, 16-13
STRUCT object, 10-7 used with SQLData interface, 13-11
attributes, 10-7 using with arrays, 16-17
creating, 13-4 type map (SQL to Java), 13-7
embedded object, 13-5 type mapping
nested objects, 10-8 BigDecimal mapping, 13-34
retrieving, 13-5 JDBC mapping, 13-33
retrieving attributes as oracle.sql types, 13-6 object JDBC mapping, 13-33
StructDescriptor object Oracle mapping, 13-33
creating, 13-4 type mappings
deserialization, 13-5 JPublisher options, 13-33
get methods, 13-4 type maps
serialization, 13-5 relationship to database connection, 23-17
setConnection() method, 13-5 TYPE_FORWARD_ONLY result sets, 17-6
TYPE_SCROLL_INSENSITIVE result sets, 17-6
TYPE_SCROLL_SENSITIVE result sets, 17-6
T
typecodes, Oracle extensions, 10-17
TABLE_REMARKS columns, 22-15
TABLE_REMARKS reporting
restrictions on, 22-20
U
TAF, definition of, 19-8 unicode data, 10-20
TCP/IP protocol, 1-3, 3-9 updatability in result sets, 17-2
testing updatable result set concurrency type, 17-3
for NULL values, 11-2 updatable result sets
Thin driver creating, 17-5
Index-12
DELETE operations, 17-12 compatibility, 1-8
INSERT operations, 17-14
limitations, 17-7
W
refetching rows, 17-16, 17-19
seeing internal changes, 17-18 WIDTH, parameter for APPLET tag, 23-14
update conflicts, 17-15 window, scroll-sensitive result sets, 17-20
UPDATE operations, 17-12 writeSQL() method, 13-11, 13-12
update batching implementing, 13-12
overview, Oracle vs. standard model, 22-2
overview, statements supported, 22-2 X
update batching (Oracle model)
batch value, checking, 22-5 XA
batch value, overriding, 22-5 connection implementation, 9-6
committing changes, 22-6 connections (definition), 9-3
connection batch value, setting, 22-4 data source implementation, 9-5
connection vs. statement batch value, 22-3 data sources (definition), 9-3
default batch value, 22-4 definition, 9-2
disable auto-commit, 22-3 error handling, 9-14
example, 22-7 example of implementation, 9-15
limitations and characteristics, 22-4 exception classes, 9-13
overview, 22-3 Oracle optimizations, 9-14
statement batch value, setting, 22-4 Oracle transaction ID implementation, 9-12
stream types not allowed, 22-4 resource implementation, 9-7
update counts, 22-7 resources (definition), 9-3
update batching (standard model) transaction ID interface, 9-12
adding to batch, 22-9 XAException, 9-11
clearing the batch, 22-10 Xids, 9-11
committing changes, 22-10
error handling, 22-12
example, 22-12
executing the batch, 22-9
intermixing batched and non-batched, 22-13
overview, 22-8
stream types not allowed, 22-8
update counts, 22-11
update counts upon error, 22-12
update conflicts in result sets, 17-15
update counts
Oracle update batching, 22-7
standard update batching, 22-11
upon error (standard batching), 22-12
UPDATE in a result set, 17-12
updateRow() method (result set), 17-13
updatesAreDetected() method (database meta
data), 17-19
updateXXX() methods (result set), 17-12, 17-14
updateXXX() methods for empty LOBs, 14-12
updating result sets, 17-11
url, 3-4
URLs
for KPRB driver, 23-16
useFetchSizeWithLongColumn connection
property, 4-5
user connection property, 4-5
userid, specifying, 4-2
V
VARCHAR2 columns, 26-7
version
Index-13
Index-14