Updated January 5, 2022
This document contains answers to the most frequently asked questions about Oracle's JDBC drivers. Note that this FAQ addresses specific technical questions only and are used to document solutions to frequent customer questions as well as any known problems. Go through the JDBC Reference Guide and Javadoc for JDBC for more detailed information.
The section below highlights the key JDBC features of 19c. Please refer to Revisiting the Performance & Scalability of Java Applications that use RDBMSes for more details.
Latest Java Standards: Supports JDK17, JDK11, JDK8 and compliant to JDBC 4.3 (ojdbc11.jar and ojdbc10.jar) and JDBC 4.2(ojdbc8.jar) by JDBC driver and Universal Connection Pool (ucp.jar)
For Java developers using JDBC driver and/or UCP, the detailed instructions to connect to database service on cloud are present on JDBC with DB Cloud page .
The Java Database Connectivity (JDBC) API is the industry standard for database-independent connectivity between the Java programming language and a wide range of databases—SQL databases and other tabular data sources, such as spreadsheets or flat files. The JDBC API provides a call-level API for SQL-based database access.
JDBC technology allows you to use the Java programming language to exploit "Write Once, Run Anywhere" capabilities for applications that require access to enterprise data. With a JDBC technology-enabled driver, you can connect all corporate data even in a heterogeneous environment.
—Refer to java.sql for various JDBC specs (4.3, 4.2, 4.2, etc.,) summary in JDK 11
—Refer to complete JDBC specs at jcp.org
You can start at Oracle's JDBC drivers page and can get more information from JDBC Developer's Guide and JDBC Github.
There are lots of books on JDBC. A good place to start is JDBC API Tutorial and Reference, Third Edition .
A good place to start is Oracle's Java site.
There are lots of books on Java. A few of the more popular ones are:
Please refer to the table below for the supported versions of JDBC drivers. Please note that the information in this table provides the summary for your convenience, we recommend you to refer to page#4 on Lifetime Support Policy for more details and for any updates.
Release | GA Date | Premier Support Ends | Extended Support Ends | Sustaining Support Ends |
---|---|---|---|---|
21c (Innovation Release) | Aug 2021 | Apr 2024 | Not Available | Indefinite |
19c (Long Term Release) | Apr 2019 | Apr 2024 | Apr 2027 | Indefinite |
18c | Jul 2018 | Jun 2021 | Not Available | Indefinite |
12.2 | Mar 2017 | Nov 30, 2020 (Limited Error Correction Period for 12.2.0.1 – Dec 1, 2020 – Mar 31, 2022) | Not Available | Indefinite |
EE 12.1 | Jun 2013 | Jul 2018 | Jul 2022 | Indefinite |
Please refer to the table that covers the JDBC driver interoperability matrix for the supported Oracle database versions. The recommendation is that JDBC driver version should always be either same as or higher than the Oracle database version in order to leverage the latest capabilities of the driver.
Interoperability Matrix | Database 23.3 | Database 21.x | Database 19.x | Database 18.3 | Database 12.2 and 12.1 |
---|---|---|---|---|---|
JDBC 23.3 | Yes | Yes | Yes | No | No |
JDBC 21.x | Yes | Yes | Yes | Was | Was |
JDBC 19.x | Yes | Yes | Yes | Was | Was |
JDBC 18.x | No | Was | Was | Was | Was |
JDBC 12.2 and 12.1 | No | Was | Was | Was | Was |
The Oracle JDBC driver is always compliant to the latest JDK version in each of the new releases. In some versions, JDBC drivers support multiple JDK versions. Use the table below to choose the correct JDBC driver based on your preferred JDK version.
Oracle Database version | JDBC Jar files specific to the release |
---|---|
23.x | ojdbc11.jar with JDK11, JDK17, JDK19, and JDK21 ojdbc8.jar with JDK8 and JDK11 |
21.x | ojdbc11.jar with JDK11, JDK17, and JDK19 ojdbc8.jar with JDK8 and JDK11 |
19.x | ojdbc10.jar with JDK11, JDK17, and JDK19 ojdbc8.jar with JDK8, JDK11, and JDK17 |
18.x | ojdbc8.jar with JDK8 and JDK11 |
12.2 or 12cR2 | ojdbc8.jar with JDK 8 |
12.1 or 12cR1 | ojdbc7.jar with JDK 7 and JDK 8 ojdbc6.jar with JDK 6 |
11.2 or 11gR2 | ojdbc6.jar with JDK 6, JDK 7, and JDK 8 (Note: JDK7 and JDK8 are supported in 11.2.0.3 and 11.2.0.4 only) ojdbc5.jar with JDK 5 |
The table lists the Oracle JDBC drivers and the JDBC specification supported in that release.
Oracle Database version | JDBC specification compliance |
---|---|
23.x and 21.x | JDBC 4.3 in ojdbc11.jar JDBC 4.2 in ojdbc8.jar |
19.x | JDBC 4.3 in ojdbc10.jar JDBC 4.2 in ojdbc8.jar |
18.3 | JDBC 4.2 in ojdbc8.jar |
12.2 or 12cR2 | JDBC 4.2 in ojdbc8.jar |
12.1 or 12cR1 | JDBC 4.1 in ojdbc7.jar JDBC 4.0 in ojdbc6.jar |
11.2 or 11gR2 | JDBC 4.0 in ojdbc6.jar JDBC 3.0 in ojdbc5.jar |
Oracle JDBC drivers are certified only with the Oracle JVM (formerly Sun JVM). However, customers have been using Oracle JDBC drivers with non-Oracle JVMs (e.g., IBM JVM). The only caveat is that for the Oracle JDBC development team and Oracle Support to consider an issue pertaining to Oracle JDBC drivers, we will mandate that such issue be reproduced on the Oracle JVM.
19.x version has
(a) ojdbc8.jar (compiled with JDK8 (JDBC 4.2) and can be used with JDK9, JDK11) and
(b) ojdbc10.jar (compiled with JDK10 (JDBC 4.3) and can be used with JDK11).
If you are using JDK11 then, ojdbc8.jar is still a better choice as it includes all the 4.3 features but as Oracle extensions. Customers can use ojdbc10.jar only if they need JDBC 4.3 features available through standard Java SE.
Example:
ojdbc8.jar:
Connection conn = DriverManager.getConnection(. . .); // conn.beginRequest(); would fail because beginRequest is not in Java 8 ((OracleConnection)conn).beginRequest(); // succeeds because beginRequest is provided as an Oracle extension
Connection conn = DriverManager.getConnection(. . .); conn.beginRequest(); // succeeds because beginRequest is in Java 10 ((OracleConnection)conn).beginRequest(); // succeeds because OracleConnection supports JDBC 4.3 (in Java 10) and beginRequest is part of JDBC 4.3
If it is not listed in the above table then please check with your support channel to check if you are still on the support contract for the older versions.
Please download the required JDBC jar and other companion jars such as orai18n.jar, oraclepki.jar, osdt_core.jar, osdt_cert.jar
from the Oracle Technology Network JDBC Download Page.
Please refer to the table below to know more details about the JDBC drivers.
Oracle provides four different types of JDBC drivers, for use in different deployment scenarios. While all Oracle JDBC drivers are similar, some features apply only to JDBC OCI drivers and some apply only to the JDBC Thin driver.
The use of native methods makes the JDBC OCI driver platform specific. Oracle supports Solaris, Windows, and many other platforms.
This JDBC OCI driver is available for install with the OCI Instant Client feature, which does not require a complete Oracle client-installation. Please refer to Oracle Call Interface for more information.
The best choice is to use Oracle JDBC thin driver. All the new enhancements and features are implemented only on JDBC Thin driver.
If you are using a non-TCP/IP network you must use the OCI driver.
For in-place processing within your database session (i.e., Java in the database), you must use either the embedded type 2 driver (or server internal driver); if your java code running in your session needs to access a remote Oracle database or another session within the same database instance, then you must use the embedded type 4 driver (or server thin driver).
Both of these drivers run only in the Oracle Server Java VM and their classes are installed as part of installing the VM. There are no separate classes files available or needed for these drivers. Check out the InternalT2Driver.java and InternalT4Driver.java for reference.
If you are a third party software company (and Oracle partner) then please check out FUTC license and run this by your legal department and then contact your local Oracle sales rep for more details.
When your application is run with a SecurityManager enabled (which it should in production) certain operations are priviliged. In order to do those operations the code must be granted the appropriate permissions.
The way to find out what permissions to grant is to look at the file ojdbc.policy on the download page. This is a generic security policy file that you can use to grant the drivers all the necessary permissions. In most cases you will want to comment out many of the permissions since your app doesn't use the features that requires those permissions.
This file depends on a number of system properties. To use this file you will have to define those properties using the -D option to the java
command.
Some of the permissions need only be granted to the JDBC driver code. The operations that require those permissions are enclosed in a doPriviliged
block. Other permissions must also be granted to the code that calls the drivers. Those operations are not enclosed in doPriviliged
blocks. One noteworthy example is that the calling code needs the open socket permission when using the thin driver to open a connection. This is to prevent rogue code from using the drivers for a denial of service attack, among other reasons.
Download the Oracle JDBC driver that is compliant with the JDK version that you are using. You can find the latest versions of the JDBC driver on the download page.. Make sure to include the JDBC drivers on the classpath. See What are the different JAR files on the download page for? to determine which files you need.
The JDBC OCI driver generally requires an Oracle client-installation of the same version the driver. However, JDBC OCI driver is available with OCI Instant Client feature, which does not require a complete Oracle client-installation. Please refer to the documentation on OCI Instant Client install.
You don't. These two drivers are installed as part of the database installation. If the database was installed with Java support, these two drivers are already installed and available. See Can I load one of the classes files into the Oracle Server Java VM?
The first version of JDBC specified using the class java.sql.DriverManager
to create Connections. This turned out to be insufficiently flexible and later versions of the JDBC spec define an additional way to create Connections using DataSources. We recommend that you use DataSources.
DataSources provide a more flexible way to create Connections. DataSources were designed to be used with JNDI, but you don't have to use JNDI to use DataSources. DataSources can do things other than just create new connections. In particular, a DataSource can implement a connection cache. DataSources are now the preferred way to create a Connection.
The simplest way to get a connection from a DataSource is as follows:
ds = new oracle.jdbc.pool.OracleDataSource();
ds.setURL(myURL);
conn = ds.getConnection(user, password);
You should use Universal Connection Pool (UCP). This new connection caching mechanism is driver, protocol, and database independent. It supports non-JDBC connections and JDBC connections to databases other than Oracle. When using Oracle JDBC it provides advanced Oracle features including:
The Oracle Implicit Connection Cache is de-supported. Note that the old connection cache, OracleConnectionCacheImpl was desupported in 11.1.
JDBC OCIConnectionPool is for pooling multiple stateful sessions with few underlying physical connections to database. The connection is bound to the session only for duration of call. The pool element is the underlying physical connection. The application sessions can migrate (internally) to any underlying available physical connection.
Each physical connection from pool has an additional internal session to server. Hence you can see more sessions on server.
The general form of a URL is
jdbc:oracle:<drivertype>:<username/password>@<database>
The <drivertype>
thin
oci
kprb
The <username/password>
is either empty or of the form
<username>/<password>
Note that a URL like
has an empty username and password whereas this URL
jdbc:oracle:thin:@mydatabase
does not specify a username and password. When using this form the username and password must be provided some other way.
The <database> description somewhat depends on the driver type. If the driver type is kprb, then the <database> description is empty. If the driver type is oci and you wish to use a bequeath connection, then the <database> is empty. Otherwise ( thin
or oci
driver and not bequeath) the database description is one of the following:
//<host>:<port>/<service>
<host>:<port>:<SID>
<TNSName>
The following URL connects user scott
with password tiger
to a database with service orcl
(Important: see more on services) through port 1521 of host myhost, using the Thin driver.
jdbc:oracle:thin:scott/tiger@//myhost:1521/orcl
This URL connects to the same database using the the OCI driver and the SID
inst1 without specifying the username or password.
jdbc:oracle:oci:@myhost:1521:inst1
This URL connects to the database named GL in the tnsnames.ora
file using the Thin driver and with no username or password specified. The username and password must be specifed elsewhere.
jdbc:oracle:thin:@GL
Support for using TNSNAMES entries with the Thin driver is new in release 10.2.0.1.0. In order for this to work you must have configured the file tnsnames.ora
correctly
In addition to the URL, use an object of the standard Java Properties
class as input. For example:
java.util.Properties info = new java.util.Properties();
info.put ("user", "scott");
info.put ("password","tiger");
info.put ("defaultRowPrefetch","15");
getConnection ("jdbc:oracle:oci:@",info);
All of the supported properties are defined in the JavaDoc for oracle.jdbc.OracleConnection.
There are constants that define the property names. The JavaDoc for each constant describes what the property does and how to use it.
In pre-11.1 versions of the driver the properties are defined in the JavaDoc for oracle.jdbc.pool.OracleDataSource.setConnectionProperties
and in the Oracle JDBC Developer's Guide.
OracleDriver
with the DriverManager
?You are no longer required to register the OracleDriver
class for connecting with the Server-Side Internal driver, although there is no harm in doing so. This is true whether you are using getConnection()
or defaultConnection()
to make the connection.
If you are using ojdbc6.jar and JSE 6 or later, you don't have to register the driver at all no matter which driver you are using. As of JSE 6, the standard Java Service Provider Interface registers the drivers automatically. Just call DriverManager.getConnection
and the runtime will find the driver and register it for you.
Any user name or password you include in the URL string is ignored in connecting to the server default connection. The DriverManager.getConnection()
method returns a new Java Connection
object every time you call it. Note that although the method is not creating a new database connection (only a single implicit connection is used), it is returning a new java.sql.Connection object.
Again, 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 never be closed.
The solution is to increase the startup size (-ms) and maximum size (-mx) of memory allocation pool. This should be less of a problem with the 11.1 and later drivers as they use less memory than the 10g drivers. There is a more detailed discussion of this issue in the "JDBC Memory Management" white paper on the JDBC OTN web page.
Oracle is replacing the SID mechanism for identifying databases with a new services approach. This has been available in the database since 8.1.wi7. JDBC supports services in the connect URL. We strongly encourage everyone to transition from SIDs to services as quickly as possible as SIDs will be cease to be supported in one of the next few releases of the database.
The basic format of a service URL is:
jdbc:oracle:thin:[<user>/<password>]@//<host>[:<port>]/<service> jdbc:oracle:oci:[<user>/<password>]@//<host>[:<port>]/<service>
Examples:
jdbc:oracle:thin:@//myserver.com/customer_db jdbc:oracle:oci:scott/tiger@//myserver.com:5521/customer_db
For more info see the JDBC User Guide.
The only way to do this is to use the Properties object when connecting, rather than specifying the username and password as strings. Put the username into the "user" property, and the password into the "password" property. Then, put the mode into the "internal_logon" property. Something like the following:
Properties props = new Properties();
props.put("user", "scott");
props.put("password", "tiger");
props.put("internal_logon", "sysoper");
Connection conn = DriverManager.getConnection (url, props);
When connecting as SYSDBA or SYSOPER using the Thin driver, the RDBMS must be configured to use a password file. See "Creating and Maintaining a Password File" in the "Oracle Database Administrator's Guide".
The JDBC OCI driver supports the same algorithms as the database server.
In 11.1 and 11.2 the JDBC Thin driver supports:
Assuming that the server is properly configured, use the following connection properties:
Properties props = new Properties();
props.put("oracle.net.encryption_types_client", "(3DES168)");
props.put("oracle.net.encryption_client", "REQUIRED");
props.put("oracle.net.crypto_checksum_types_client", "(MD5)");
props.put("oracle.net.crypto_checksum_client", "REQUIRED");
Proxy authentication is the ability to connect as a user through another user. For example proxy authentication enables the middle tier to authentication once to the database using a 'generic' account and then establish lightweight session on behalf of actual users. See the JavaDoc for oracle.jdbc.OracleConnection.openProxySession.
Yes, but the support is driver-specific. SSL encryption has been supported in the JDBC-OCI driver since Oracle JDBC 9.2.x, and is supported in the THIN driver starting in the 10.2.
Yes. JDBC THIN driver supports both regular LDAP and LDAP over SSL in the connection URL, for example, when using Oracle Internet Directory as an LDAP provider. Please refer to both the Oracle JDBC Developer's Guide and the Oracle Net Services Administrator's Guide for detail.
Generally, it is recommended that Oracle Connection Manager be used to proxy your connections through the firewall. You open up a port designated to be used by the Oracle Connection Manager, and let it handle the rest. You should not directly open up any port that the database listener is using, like port 1521.
Please refer to the Oracle Net Services Administrator's Guide for how to configure Oracle Connection Manager.
defineColumnType
and when should I use it?defineColumnType
is an Oracle JDBC extension that provides increased performance in some cases. In prior versions of Oracle JDBC, all of the drivers benefited from calls to defineColumnType
but beginning in 10.1.0 the Thin driver no longer needs the information provided. The Thin driver achieves maximum performance without calls to defineColumnType
. The OCI and Server-Side Internal drivers still get better performance when the application uses defineColumnType
.
If your code is used with both the Thin and OCI drivers, you can disable the defineColumnType
method when using the Thin by setting the connection property disableDefineColumnType
to "true"
. This will make defineColumnType
a NOOP. Do not set this connection property or else set it to "false"
when using the OCI or Server-Side Internal drivers.
Define column type may also be used to change the type of the data. Or to limit the size of variable length data.
There is a new variation of this with a 4th parameter for form_of_use.
defineColumnType
force conversions on the Server?No for the Thin driver and yes for the OCI and Server-Side Internal drivers.
Please use a property 'CONNECTION_PROPERTY_PROCESS_ESCAPES' in OracleConnection.
Yes. See the JavaDoc for oracle.jdbc.OraclePreparedStatement
. Look for the setXXXAtName
methods. Also, oracle.jdbc.OracleCallableStatement
supports binding arguments to PL/SQL procedures by the formal argument names. Look at the JavaDoc for the oracle.jdbc.OracleCallableStatement.setXXX(String, ...)
methods.
It is very important to note that setXXX(String, XXX)
binds using the formal parameter name of the called stored procedure. setXXXAtName(String, XXX)
binds using the name of the Oracle style ( :foo
) parameter in the SQL string being executed. These are very different and can give very different results.
Generally, there is a fixed data type associated with each setXXX method that is the data type that most sensibly corresponds to the type of the argument.
The data is shipped to the server in the format for the assumed data type and the server attempts to convert it to the type of the target parameter. If no conversion is possible, the server signals an error and the driver throws a SQLException at execute time.
For SQL statements we could first go to the server to get the type information and then do the conversions, but that would involve extra round trips. The code is optimized for the common case where the JDBC programmer uses the most appropriate API for the column type.
For byte data, there are three Oracle SQL types: RAW, LONG RAW and BLOB. RAW data is of limited length, is stored directly in a column, and is transmitted to the server in inline packets. LONG RAW data has a much larger limit (2 Gigabytes), is stored via a special mechanism alongside the row and is transmitted to the server via a streaming callback mechanism. BLOB data is effectively unlimited in length, is stored separately from the table with only a lob locator stored in the table, and is transmitted to the server is separate operations before the locator is stored into a column in the table.
For byte data, there are three Oracle SQL types: VARCHAR2, LONG and CLOB. VARCHAR2 data is of limited length, is stored directly in a column, and is transmitted to the server in inline packets. LONG data has a much larger limit (2 Gigibytes), is stored via a special mechanism alongside the row and is transmitted to the server via a streaming callback mechanism. CLOB data is effectively unlimited in length, is stored in separately from the table with only a lob locator stored in the table, and is transmitted to the server is separate operations before the locator is stored into a column in the table.
Form | Stmt | Driver | Lower Limit | Upper Limit | Bind mechanism | Note |
---|---|---|---|---|---|---|
All | All | All | 0 | 0 | Null | |
All | SQL | Client | 1 char | 32766 chars | Direct | |
All | SQL | Client | 32767 chars | 2147483647 bytes | Stream | |
All | SQL | Client | 2147483648 bytes | 2147483647 chars | Temp Clob | |
CHAR | Server | 1 char | 65536 bytes | Direct | 1, 2 | |
NCHAR | 1 char | 4000 bytes | Direct | |||
NCHAR | 4001 bytes | 2147483647 chars | Temp Clob | |||
CHAR | 65537 bytes | 2147483647 bytes | Stream | |||
2147483647 bytes | 2147483647 chars | Temp Clob | ||||
All | PL/SQL | All | 1 char | 32512 chars | Direct | |
All | PL/SQL | All | 32513 chars | 2147483647 chars | Temp Clob |
Stmt | Driver | Lower Limit | Upper Limit | Bind mechanism | Note | |
---|---|---|---|---|---|---|
All | All | All | 0 | 0 | Null | |
All | SQL | Client | 1 char | 32766 chars | Direct | |
All | SQL | Client | 32767 chars | 2147483647 bytes | Stream | |
All | SQL | Client | 2147483648 bytes | 2147483647 chars | Temp Clob | |
CHAR | Server | 1 char | 65536 bytes | Direct | 1, 2 | |
NCHAR | 1 char | 4000 bytes | Direct | |||
NCHAR | 4001 bytes | 2147483647 chars | Temp Clob | |||
CHAR | 65537 bytes | 2147483647 bytes | Stream | |||
2147483647 bytes | 2147483647 chars | Temp Clob | ||||
All | PL/SQL | All | 1 char | 32512 chars | Direct | |
All | PL/SQL | All | 32513 chars | 2147483647 chars | Temp Clob |
Notes:
could be replaced with
begin Insert into blob_tab (blob_col) values (? ); end;
API | FORM | Stmt | Driver | Lower Limit | Upper Limit | Bind mechanism | Note |
---|---|---|---|---|---|---|---|
setBytesForBlob | n/a | All | All | 0 | 0 | Null | |
All | Client | 1 byte | 2000 bytes | Direct | |||
All | Client | 2001 bytes | 21474836487 bytes | Temp blob | 2 | ||
setStringForClob | All | All | All | 0 | 0 | Null | |
All | All | Client | 1 char | 32766 chars | Direct | ||
All | All | Client | 32767 chars | 2147483647 chars | Temp clob | ||
All | All | Server | 1 char | 4000 bytes | Direct | ||
All | All | Server | 4001 bytes | 2147483647 chars | Temp clob | 1 |
Notes:
Yes.
CallableStatements
and procedures with IN OUT
parameters?It is a requirement that the data types of the IN and OUT parameter be the same. The automatic switching will cause conflicts unless user code also changes the type in registerOutParameter. A better approach is to not use IN OUT parameters where this can be an issue. This can be done by changing the original procedure, adding a wrapper procedure or PL/SQL block that uses separate IN and OUT parameters.
Yes. Consider that this can be exploited in your PL/SQL code.
Existing code will continue to work correctly. There is one change. Previously if an input exceeded the size limits of the API used, there would be an SQLException thrown when the setXXX API was called. Now, the exception will occur at execute time if at all.
Yes, they are freed after the next execution of the statement or when the statement is closed.
Yes. Except for the decision to switch to Clob for the largest strings which is made assuming the max size.
It is probably not a good idea to create the really huge string in the first place. See your Java Virtual Machine vendors documentation for the effects that very large objects have on the Java memory management system.
LONG RAW
and LONG
column types are deprecated. Why are there new uses of the setXXXStream
API's?The stream API's are not deprecated. They offer better performance for some operations than the LOB API's and will be retained.
Absolutely! The LOB API's allow random access to any part of the LOB. Consider using these where appropriate.
select * from tab where id in (?, ?, ?, ...)
?The problem is that the RDBMS does not support bind parameters for the elements in the IN clause. This is a limitation of the database, not the driver.
This error happens if you try to use a ResultSet after you close it. It also happens if you close the statement that created the ResultSet.
ResultSet rset = stmt.executeQuery ("select ROWID from EMP"); ... rset.close (); // or stmt.close (); rset.getString (1);
The original JDBC spec required that Connections, Statements, and ResultSets be closed when no longer reachable. This requires the use of finalizers. Finalizers have a huge performance penalty for all aspects of an application that run in a JVM with any finalizers. Sun strong discourages their use. Automatic closure would require the use of finalizers which would be bad for all customers whether they relied on automatic closure or not. This is not an acceptable tradeoff.
To the best of our knowledge, no JDBC driver from any vendor implements or ever has implemented automatic closure for exactly the reason outlined above. This requirement has been removed from the spec although some remnants of that wording appear in a couple of places. It also appears in the JDBC Tutorial. The tutorial, while informative and helpful, is not definitive. It has not been updated in years. The JDBC 4.0 specification absolutely does not require automatic closure.
ResultSets, Statemnents, and Connections all take up resources on both the client side and the server side. So long as those objects are open the associated resources are allocated. The resources are released only when the objects are closed. Failing to close ResultSets, Statements, and/or Connections will leak resources and impact the performance of your app.
Closing a Connection closes all of the associated Statements. Closing a Statement closes all of the associated ResultSets. So, if you are through with a Connection you can just close it and all of the Statements and ResultSets will be closed. This is acceptable programming practice. Better practice is to explicitly close Statements and ResultSets in finally blocks. This makes your application more robust and less likely to leak resources as it evolves to meet changing requirements.
PreparedStatement ps = null; ResultSet rs = null; try { ps = conn.prepareStatement(sql); try { rs = ps.executeQuery(); while (rs.next()) { // process row } } finally { if (rs != null) rs.close(); } } finally { if (ps != null) ps.close(); }
DATE
and TIMESTAMP
?This section is on simple data types. :-)
Prior to 9.2, the Oracle JDBC drivers mapped the DATE
SQL type to java.sql.Timestamp.
This made a certain amount of sense because the Oracle DATE
SQL type contains both date and time information as does java.sql.Timestamp.
The more obvious mapping to java.sql.Date
was somewhat problematic as java.sql.Date
does not include time information. It was also the case that the RDBMS did not support the TIMESTAMP
SQL type, so there was no problem with mapping DATE
to Timestamp
.
In 9.2 TIMESTAMP
support was added to the RDBMS. The difference between DATE
and TIMESTAMP
is that TIMESTAMP
includes nanoseconds and DATE
does not. So, beginning in 9.2, DATE
is mapped to Date
and TIMESTAMP
is mapped to Timestamp
. Unfortunately if you were relying on DATE
values to contain time information, there is a problem.
There are several ways to address this problem in the 9.2 through 10.2 drivers:
TIMESTAMP
instead of DATE
. This is probably rarely possible, but it is the best solution when it is.defineColumnType
to define the columns as TIMESTAMP
rather than DATE
. There are problems with this because you really don't want to use defineColumnType
unless you have to (see What is defineColumnType
and when should I use it?).getTimestamp
rather than getObject
. This is a good solution when possible, however many applications contain generic code that relies on getObject
, so it isn't always possible.V8Compatible
connection property. This tells the JDBC drivers to use the old mapping rather than the new one. You can set this flag either as a connection property or a system property. You set the connection property by adding it to the java.util.Properties
object passed to DriverManager.getConnection
or to OracleDataSource.setConnectionProperties
. You set the system property by including a -D
option in your java
command line.Oracle JDBC 11.1 fixes this problem. Beginning with this release the driver maps SQL DATE columns to java.sql.Timestamp
by default. There is no need to set V8Compatible
to get the correct mapping. V8Compatible is strongly deprecated. You should not use it at all. If you do set it to true it won't hurt anything, but you should stop using it.
Although it was rarely used that way, V8Compatible
existed not to fix the DATE to Date issue but to support compatibility with 8i databases. 8i (and older) databases did not support the TIMESTAMP type. Setting V8Compatible
not only caused SQL DATE to be mapped to Timestamp when read from the database, it also caused all Timestamps
to be converted to SQL DATE when written to the database. Since 8i is desupported, the 11.1 JDBC drivers do not support this compatibility mode. For this reason V8Compatible
is desupported.
As mentioned above, the 11.1 drivers by default convert SQL DATE to Timestamp
when reading from the database. This always was the right thing to do and the change in 9i was a mistake. The 11.1 drivers have reverted to the correct behavior. Even if you didn't set V8Compatible
in your application you shouldn't see any difference in behavior in most cases. You may notice a difference if you use getObject to read a DATE
column. The result will be a Timestamp
rather than a Date
. Since Timestamp
is a subclass of Date
this generally isn't a problem. Where you might notice a difference is if you relied on the conversion from DATE
to Date to truncate the time component or if you do toString on the value. Otherwise the change should be transparent.
If for some reason your app is very sensitive to this change and you simply must have the 9i-10g behavior, there is a connection property you can set. Set mapDateToTimestamp
to false and the driver will revert to the default 9i-10g behavior and map DATE to Date
.
Method | Column Type | Maximum length |
---|---|---|
setBytes |
LONG |
4k bytes |
setBytes |
LONG RAW |
2G bytes |
setString |
LONG |
32k chars (SetBigStringTryClob="false" )4k chars ( SetBigStringTryClob="true" ) |
setString |
CLOB |
2G chars |
In 9.2, setString() on a LONG can insert up to 64k characters with the OCI driver, and 4k characters with the Thin driver. In 10.1.0 we changed the limit for both drivers to 32k characters. We understand that reducing the limit for OCI from 64k to 32k may be a problem to some customers. However, considering the substantial performance improvement that this change made possible, and that Oracle is strongly recommending our customers to migrate from LONG to CLOB, we decided that the architectural change is necessary.
We recommend customers who need setString() to work over 32k characters to migrate from LONG to CLOB.
TIMESTAMP WITH TIME ZONE
different?The old behavior was incorrect. See bug 4322830.
The old behavior was to construct a Timestamp
that would print the same value as the database value. But since Timestamp
is in the UTC time zone this would give a Timestamp
value that was offset from the correct value. 8:00am January 1, 2007 UTC is not the same as 8:00am January 1, 2007 PST. They represent different points in time.
If you read 8:00am January 1, 2007 PST in the database, the 9i and 10g drivers would construct a Timestamp
with the value 8:00am January 1, 2007 UTC. This value would print "correctly", that is it would print as "8:00am January 1, 2007", but it obviously represented the wrong instant in time. The 11.1 drivers fix this bug.
JDBC 4.0 introduced factory methods on the Connection
interface for creating instances of ADTs. This is a far better api than using constructors. We strongly encourage you to use the factory methods as much as possible. We will deprecate use of the constructors very soon and would like to desupport them as soon as possible.
Since the standard factory methods are introduced in JDBC 4.0, those methods are only available in the JSE 6 drivers (ojdbc6.jar). For creating Oracle proprietary types, the factory methods are defined in OracleConnection
for both JSE 5 and JSE 6 (ojdbc5.jar and ojdbc6.jar). Again we strongly encourage you to use the factory methods.
createArrayOf
supported?The SQL standard array type is anonymous, that is the type "array of foo" does not have a name. Only the element type is named. In Oracle SQL the array type is named. In fact anonymous array types are not supported. So, the JDBC 4.0 standard factory method takes the element type as its argument and creates an instance of an anomyous array type. The Oracle JDBC drivers define an Oracle proprietary method, createArray
, which takes the name of an array type and returns an instance of that named array type. This is required by the way Oracle SQL is defined. At present the Oracle database cannot support the JDBC 4.0 standard createArrayOf
method.
It's just "clearing" a segment of the clob. It does *not* shorten the CLOB. So the length of the CLOB is the same before and after the ERASE. You can use DBMS_LOB.TRIM to make a CLOB shorter.
Yes, you can but you have to make sure that the position and length arguments are correct. You can also use the recommended OutputStream interface which in turn will call putChars for you.
In JDBC CLOBs are *always* in USC2, which is the Oracle character set corresponding to the Java "char" type. So there is no equivalent for the OCI CLOB CharSetId.
It depends. When writing small values, less that 10K, LONG RAWs are faster. When writing larger values, the difference disappears.
This is the correct behavior. LONG columns are not 'fetched' in-place (aka in-row). They are fetched out of place and exists in the pipe until you read them explicitly. In this case, we got the LobLocator (getBlob()) and then we are trying to get the length of this LOB before we read the LONG column. Since the pipe is not clear we are getting the above exception. The solution would be to complete reading the Long column before you do any operation on the BLOB.
Oracle LOBs use value semantics. When you update a LOB you must write the LOB back to the database to be sure of seeing the changes. For technical reasons, sometimes your changes are saved even though you do not write the LOB, but you cannot predict when that is the case, so you should always write the LOB.
That used to be true, but no longer. REF is now serializable.
The following note may still be valuable if you are using an older version of the Oracle JDBC drivers where REFs are not serializable.
The important constituents of the REF class are the byte array that represent the object reference and the fully qualified name of the object type. You can use a class like the following "SomeREF" class to hold the bytes and type name from an object REF. This class is serializable. It can recreate the REF with its "toREF" method that needs a JDBC Connection as a parameter.
public class SomeREF implements java.io.Serializable { String typeName; byte[] bytes; public SomeREF (oracle.sql.REF ref) throws SQLException { this.typeName = ref.getBaseTypeName (); this.bytes = ref.getBytes (); } public oracle.sql.REF toREF (Connection conn) throws SQLException { return new oracle.sql.REF (new oracle.sql.StructDescriptor (typeName,conn),conn, bytes); } }
You can execute queries against a table that contains REF to Oracle8 Object types and the REF will be materialized as Java oracle.sql.REF objects by JDBC. JDBC does not support creating new REF from scratch. You have to go to the database and insert the new REF in SQL. Then you have to select the REF back and return it to the client.
It is easier to do that with a PL/SQL block. For example if you have the following tables:
create or replace type point as object (x number, y number); create table point_values_table of point; create table point_ref_table (p ref point); You can insert a new point value in point_values_table, a new ref to it in the point_ref_table and return the REF to the client with following code: oracle.jdbc.driver.OracleCallableStatement call = (oracle.jdbc.driver.OracleCallableStatement) conn.prepareCall ("declare x ref point; " + "begin insert into point_values_table p values (point(10, 20))" + " returning ref(p) into x; " + " ? := x; " + "end;"); call.registerOutParameter (1, oracle.jdbc.driver.OracleTypes.REF,"SCOTT.POINT"); call.execute (); oracle.sql.REF ref = (oracle.sql.REF)call.getObject (1);
TOPAQUE types have binary data and supporting methods which are defined in a server native code library. These are available only for Oracle internal use.
A bean's properties can be classified as:
Object creation properties should be set before the creation of the object since, they are the key properties for creating the object. The runtime properties can be set at anytime and they alter the behavior of the bean at runtime.
Scrollability, user name, password are all object creation propertes. Auto-commit status, prefetch count et al, are all runtime properties. Typically the background object comes to life during execute/setCommand so all Statement creation attributes should be set before that. Since, a connetion object is required for creating a Statement URL, username, Password et al required for creating a should be set before setting the Command.
Yes, the serializable streams allow you to serialize the stream Object on to any serializable media like a flat file, network connection, et al. This feature applies only to CachedRowSet. It is possible to create a CachedRowSet on one machine where the Jdbc drivers are present and then move it on to a remote client where only the rowset binaries are present and not the driver binaries. The remote client could alter the RowSet by insert, delete or update. Then send it back to the place where the Jdbc drivers & the RowSet binaries are present to synchronize the modified values into the database.
Yes, the thin JDBC Driver can be used to develop Java applications. Unlike the JDBC OCI driver, the Thin JDBC driver only works with TCP/IP-based networks. Users who are running applications on non-TCP/IP networks are encouraged to use the JDBC OCI driver.
You should use the Server Internal Driver when you access the database in a Java Stored Procedure. A Java Stored Procedure is a Java method that executes inside the Oracle RDBMS just like PL/SQL executes in the RDBMS. Because it is executing in the RDBMS, it is necessarily executing in a database session. The Server Internal Driver connection is the handle to that database session. So, if your code is running in a Java Stored Procedure and you want to access the database, use the Server Internal Driver, except on those rare occasions when you should use the Server Thin Driver.
In a Java Stored Procedure you should usually use the Server Internal Driver. It connects to the same session in which the stored procedure is executing. However, on occasion you might want to connect to another database or to a new session in the same database. In either of those two cases you would use the Server Thin Driver.
Make sure that the driver is registered and that you use a connection URL consistent with your JDBC driver. See Using Oracle's JDBC Drivers for the correct values.
When using Win NT or Win95, the Java Virtual Machine complains that it cannot load OCI73JDBC.DLL, when one of the DLLs called by OCI73JDBC.DLL cannot be loaded. The JDBC OCI drivers use shared libraries that contain the C code portions of the driver. The library is OCI73JDBC.DLL for the Oracle7 client program. The shared library is normally installed in [ORACLE_HOME]\BIN when you install the JDBC driver from the distribution. Make sure that directory is in your PATH. Read the Installation section of the documentation for more details.
The shared library also depends on other libraries. If any of those DLLs are missing, you will end up with an error saying OCI73JDBC.DLL is missing. JDBC OCI7 requires the following Oracle7 files: CORE35.DLL, CORE35O.DLL, NLSRTL32.DLL, and ORA73.DLL
The Java Virtual Machine (JavaSoft JDK) is JAVAI.DLL.
The Microsoft Visual C++ runtime is MSVCRT.DLL, MSVCRTI.DLL, MSVCRT20.DLL, and MSVCRT40.DLL.
You can find the list of dependent DLLs by going to the Windows Explorer program, right-clicking on the DLL, and choosing Quick View. The Quick View screen shows, among other things, the Import Table which lists the dependent DLLs. You can reinstall missing required support files from the Oracle installation CD. Please install "Required Support Files 7.3.4", "SQL*Net Client 2.3.4 " and "Oracle TCP/IP Protocol Adapter 2.3.4"c.
You are using the OCI8 driver in an Oracle7 client installation. Use the OCI7 driver.
The number of cursors one client can open at a time on a connection is limited (50 is the default value). You do need to explicitly close the statement, by using the method stmt.close() in order to close and freeup the cursors.
If you don't close these cursors explicitly, you will get this error eventually. Simply increasing the "OPEN_CURSORS" limit can help you avoid the problem for a while, but that just hides the problem, not solve it. It is your responsibility to explicitly close out cursors that you no longer need.
A JDBC Connection by default has the AutoCommit turned ON. However, to use a SQL that has 'for update' you need to have autoCommit to be turned OFF.
Hence, the solution is to set autocommit to false.
Try explicitly setting NLS_LANG. If NLS_LANG is not set or is correctly set, then you may have a client other than Oracle7.3.4. Install Oracle7.3.4 on the client.
There is no Oracle installation on the client or the installation did not complete properly. If you haven't already done so, use the regular Oracle Server install CD and do a "Oracle Client" installation, to put the necessary software on your client machine. If you have already done this, check that the installation did actually complete properly, and if necessary, remove and reinstall.
Note that you can get this error by doing a client install, and then forgetting to set ORACLE_HOME. If you have not the ORACLE_HOME environment variable, then simply setting/exporting that environment variable should fix the problem, without having to reinstall the client side.
The JDBC Thin driver requires double quotes around literals that contain Unicode characters. For example:
ResultSet rset = stmt.executeQuery ("select * from \"\u6d82\u6d85\u6886\u5384\"");
By default the driver commits all INSERTs and UPDATEs as soon as you execute the statement. This is known as autoCommit mode in JDBC. You can get better performance by turning autoCommit off and using explicit commit statements. Use the setAutoCommit entrypoint of the Connection class to turn off autoCommit:
connection.setAutoCommit(false); See Batching Updates in the JDBC Documentation for information about the Oracle extensions for batching calls to INSERT and UPDATE. Batching these commands can achieve even more speed than turning off autoCommit.
Typically, this is the error you will see if the server crashes out while you are connected to it. You may be in the process of establishing a connection, or you could be midway through an established connection. Either way, you should check the server side log files to see what errors and stack dumps were thrown on the server.
Note that this error is different to what happens if you try to connect to a wrong/invalid port or even machine, you would get a different error, not this one. Its also different to the error you would get if the server is down and not accepting connection requests.
The Thin driver throws this exception when it reads something from the RDBMS that it did not expect. This means that the protocol engine in the Thin driver and the protocol engine in the RDBMS are out of synch. There is no way to recover from this error. The connection is dead. You should try to close it, but that will probably fail too.
If you get a reproducible test case that generates this error, please file a TAR with Oracle Global Support. Be sure to specify the exact version numbers of the JDBC driver and the RDBMS, including any patches.
Yes. Look in $ORACLE_HOME/jdbc/demo/demo.tar
on UNIX systems and $ORACLE_HOME/jdbc/demo/demo.zip
on Windows systems.
Unzip the demo.tar
or demo.zip file.
You'll see a Samples-Readme.txt file. Please read this file first to get an overview of JDBC demos, then run Makefile
on UNIX or invoke rundemo.bat
on Windows.
The JDBC demos should run without error. If you get an error that probably means a problem in your configuration. Check the following:
Samples-Readme.txt, Makefile,
and each .java file for pre-testing requirements.The JDBC Trace Facility is a runtime debugging aid built into previous versions of Oracle JDBC. When enabled, it prints messages about the execution of the Oracle JDBC driver. Typically these messages include method entry, parameter values, significant internal state, internal errors, method exit, and return values.
As of 10.1.0, the Oracle Trace Facility is only supported in classes12_g.jar and classes12dms_g.jar. All Oracle JDBC drivers supporting JDK 1.4 and later use the built in trace facility in java.util.logging. See the section on java.util.logging for info on how to get trace info when using JDBC 11 or ojdbc14_g.jar or ojdbc14dms_g.jar.
If you are having difficulty with your JDBC application, you might find the trace helpful. Most of the messages are about internal JDBC methods and so may be obscure. Still, you might get some help. I would suggest setting the trace volume to 1 to begin with.
If you think there is a bug in JDBC, the trace might help us in supporting you. In this case leave the trace volume at the default. Because of the large output this produces, you will need to either trace a small test case, or just trace a limited part of a larger application. Be sure and include the appropriate code prior to the failure.
See the section on java.util.logging for info on how to get trace info when using JDBC 11.
In order to use the JDBC Trace Facility, you must use a debug jar file: classes12_g.jar or classes12dms_g.jar. If you attempt to use the trace while using one of the other jar or zip files, you will get either an error message or no output at all.
There are two ways to control the trace: programatically or via properties. The programmatic api allows you to enable or disable the trace and change other properties while your application is executing. Given the often high volume of trace data, it is often a good idea to only enable the trace for particularly suspect bits of code. If it is not easy to change the application source, you can control the trace via properties. These properties are read once at application startup and are not read again. You can use both the properties and the api at the same time. The properties set the initial state and the api modifies that state.
The simplest way to turn the trace on programatically is to call
oracle.jdbc.driver.OracleLog.startLogging(); This sends the trace to System.out. To turn it off call
oracle.jdbc.driver.OracleLog.stopLogging(); You can also turn on the trace by setting the system property oracle.jdbc.Trace
to "true".
java -Doracle.jdbc.Trace=true MyApp Setting any of the other JDBC Trace Facility properties described below implicitly sets oracle.jdbc.Trace
to "true".
See the section on java.util.logging for info on how to get trace info when using JDBC 11.
The JDBC Trace Facility can produce a lot of output. The simplest way to control the volume is to only turn on the trace when needed.
oracle.jdbc.driver.OracleLog.startLogging(); myApp.suspectCode();
oracle.jdbc.driver.OracleLog.stopLogging(); Often this is not possible. You can also reduce the number of trace messages by setting the trace volume. oracle.jdbc.driver.OracleLog.setLogVolume(1); The default value is 2. The maximum value is 3, but that currently does not produce a whole lot more than 2. 1 is much less than the default.
You can control the size of each line either by setting an explicit line size, or by changing which fields are printed on each line. To change the maximum line length
oracle.jdbc.driver.OracleLog.setMaxPrintBytes(100); or java -Doracle.jdbc.MaxPrintBytes=100 MyApp
To control which fields are printed you can set the property oracle.jdbc.PrintFields.
java -Doracle.jdbc.PrintFields=none MyApp The valid values are:
See the section on java.util.logging for info on how to get trace info when using JDBC 11.
By default the trace output goes to System.out.
You can send it elsewhere either with the property oracle.jdbc.LogFile
java -Doracle.jdbc.LogFile=/tmp/jdbc.log MyApp or by calling the setLogStream api. oracle.jdbc.driver.OracleLog.setLogStream(System.err); Setting the log stream starts the trace as well. You can turn the trace off by setting the log stream to null.
There is a system property oracle.dms.console.DMSConsole. If that property is not set then DMS is active. If it is set to oracle.dms.instrument_stub.DMSConsole, then a stub implementation is used, which effectively disables DMS. One way for an application to disable it would be to call
System.setProperty( "oracle.dms.console.DMSConsole", "oracle.dms.instrument_stub.DMSConsole"); before executing any DMS code. Another way would be to use the -D option with the Java VM. java -Doracle.dms.console.DMSConsole=oracle.dms.instrument_stub.DMSConsole MyApp
Visual Cafe is no longer supported.
Visual J++ is no longer supported.
Yes, both the Oracle JDBC OCI Driver and the Thin JDBC Driver support execution of PL/SQL stored procedures and anonymous blocks. and anonymous blocks. They support both SQL:2003 escape syntax and Oracle escape syntax. The following PL/SQL calls are available from both of Oracle JDBC Drivers:
Yes, both the Oracle JDBC OCI Driver and the Thin JDBC Driver support streaming of data in either direction between the client and the server. They support all stream conversions - binary, ASCII, and Unicode. To get more information, read the stream tutorial in the Oracle JDBC Driver documentation.
Yes, both the Oracle JDBC OCI Driver and the Thin JDBC Driver support multibyte character sets - they can both access databases that use any Oracle character set. They convert multibyte characters to Unicode 1.2. The JDBC OCI Driver has been tested and supports all European character sets and all Asian character sets including Chinese, Japanese and Korean.
Yes, both the JDBC OCI driver and the thin JDBC driver can work in both an Intranet and in an Extranet setting. In an Extranet deployment, the drivers can be used with most industry leading firewalls which have been SQL*Net certified. Today, the following firewall vendors have certified their Firewalls with SQL*Net:
No. It is not feasible for Oracle JDBC drivers to support calling arguments or return values of the PL/SQL types TABLE (now known as indexed-by tables), RESULT SET, RECORD, or BOOLEAN. There are currently no plans to change this. Instead people are encouraged to use RefCursor, Oracle Collections and Structured Object Types.
As a workaround, you can create wrapper procedures that handle the data as types supported by JDBC.
For example, to wrap a stored procedure that uses PL/SQL booleans, you can create a stored procedure that takes a character or number from JDBC and passes it to the original procedure as BOOLEAN, or, for an output parameter, accepts a BOOLEAN argument from the original procedure and passes it as a CHAR or NUMBER to JDBC. Similarly, to wrap a stored procedure that uses PL/SQL records, you can create a stored procedure that handles a record in its individual components (such as CHAR and NUMBER). To wrap a stored procedure that uses PL/SQL tables, you can break the data into components or perhaps use Oracle collection types.
Here is an example of a PL/SQL wrapper procedure MY_PROC for a stored procedure PROC that takes a BOOLEAN as input:
PROCEDURE MY_PROC (n NUMBER) IS BEGIN IF n=0 THEN proc(false); ELSE proc(true); END IF; END; PROCEDURE PROC (b BOOLEAN) IS BEGIN ... END;
Yes. When you are connecting to a RAC server, Fast Connection Failover provides rapid response to failure events. This new High-Availability feature is driver independent and works in conjunction with the Implicit connection cache and RAC to provide maximum availability of connections in the cache. This is achieved by processing RAC's down events to remove invalid connections and up events to load balance existing connections.
If you are using the OCI driver and all you need is query fail-over, you might consider TAF. TAF primarily facilitates query failover in an application. It is not a general fail-over mechanism. Note that Fast Connection Failover and TAF can't be used together. Only one may be enabled and used at a time.
We do not support the getCursorName and setCursorName JDBC entrypoints. Instead we provide access to ROWIDs, which provide similar functionality. JDBC 4.0 defines java.sql.Rowid
which is fully compatible with oracle.sql.ROWID
and is supported in the JSE 6 (ojdbc6.jar) drivers.
If you add the ROWID pseudocolumn to a query you can retrieve it in JDBC with the ResultSet getString entrypoint. You can also bind a ROWID to a preparedStatement parameter with the setString entrypoint.
This allows in-place updates, as in the following example:
In the ResultSetMetaData class, columns containing ROWIDs are reported with the type oracle.jdbc.driver.OracleTypes.ROWID, whose value is -8.
The Oracle JDBC driver supports bind variables of type REFCURSOR. A REFCURSOR is represented by a JDBC ResultSet. Use the getCursor method of the CallableStatement to convert a REFCURSOR value returned by a PL/SQL block into a ResultSet. JDBC lets you call a stored procedure that executes a query and returns a results set. Cast the corresponding CallableStatement to oracle.jdbc.driver.OracleCallableStatement to use the getCursor method.
As of version 9.2 both the OCI and Thin drivers support ANO.
ANO works with 8.0.X OCI Drivers version 8.0.x and above. You need to have the latest patchsets for 8.0.4, 8.0.5 and 8.0.6 to have this feature working properly.
Note: There is a known bug (#899424) in 8.1.5 and 8.1.6sdk. While we do have a bugfix for this, the bugfix has not yet been backported and released as a patch to all previous releases. So far, this bug still exists for 8.1.5 and 8.1.6sdk.
The bugfix is already in the 8.1.6 code, so there is no patch needed for 8.1.6 - your code should just work! For more information, see bug #899424.
Yes. All of the oracle.sql.*
classes that represent SQL data types are serializeable.
Yes, the Oracle JDBC drivers do support Objects and Collections. This has been true since 8.1.5.
The WaitOption and AutoRollback rollback options for batching calls have been deprecated and are no longer available for use. You can no longer use the following methods:
public void setAutoRollback (int autoRollback); public int getAutoRollback(); public void setWaitOption(int waitOption); public int getWaitOption();
Yes, using the Thin-server driver. This has been supported since 8.1.6sdk.
The only known workaround at this time is to configure the first installation to use DBLINKS when contacting the second installation. This fakes the jdbc drivers into thinking that its still working in the same one instance, and relies on DBLINKS to take care of the details. However, there are rumored to be problems with using DBLINKS on an MTS server installation.
As always, it depends. There are some applications where the the Thin driver is faster, some where the OCI driver is faster. As of 10.1.0, the Thin driver is probably slightly faster than the OCI driver. In cases when the client and server are the same type of hardware and OS, the OCI driver puts a little less load on the RDBMS, even though the Thin client is faster. The differences are usually small, less than 10%. Most of our customers use the Thin driver because of its easier administration. Your mileage may vary.
Statements may be slightly faster if you are only going to execute the SQL once. PreparedStatements are much faster when the SQL will be executed more than once. If you are using the statement cache, which you should, getting a statement from the cache is the same as executing the same statement.
In general we strongly recommend that you use PreparedStatements. This is especially true if you are sending user provided data in the SQL. By binding the data to a PreparedStatement parameter you can prevent most SQL injection attacks. Any performance advantage of using Statements is negligible.
First, you must use a jar file that includes logging code. The JDBC driver ojdbc8.jar does not include any logging code. The non-debug DMS jar file, ojdbc8dms.jar include some logging code. The debug jar files, *_g.jar, include extensive logging code. Be sure that there are no extra Oracle JDBC jar files in your classpath.
Second, you must turn on Oracle JDBC logging. You can turn logging on globally by setting a system property -Doracle.jdbc.Trace=true or you can control it programatically using the Oracle JDBC Diagnosibility MBean.
// create name
javax.management.ObjectName name = new javax.management.ObjectName("com.oracle.jdbc:type=diagnosibility,name=*");
// get the MBean server
javax.management.MBeanServer mbs = java.lang.management.ManagementFactory.getPlatformMBeanServer();
// find out if logging is enabled or not
System.out.println("LoggingEnabled = " + mbs.getAttribute(name, "LoggingEnabled"));
// enable logging
mbs.setAttribute(name, new javax.management.Attribute("LoggingEnabled", true));
// disable logging
mbs.setAttribute(name, new javax.management.Attribute("LoggingEnabled", false));
Just turning on logging provides minimal output. For more detailed and more targeted output you must configure java.util.logging
.
java.util.logging
to get useful trace output from Oracle JDBC?The JDBC code creates a number of Loggers. In order to get interesting output you need to set the logLevel on each of these Loggers and add a Handler somewhere. See the JavaDoc for java.util.logging
for more information.
Or, you can use the convenient property file OracleLog.properties
provided in the demo.zip
file that is part of the Oracle JDBC drivers installation. The comments in this file explain how to use it. This is much easier and highly recommended.
Note that in either case you still have to enable logging to get trace output. You can toggle trace output on and off without reconfiguring the Loggers. The Diagnosibility MBean doesn't mess with the Loggers at all. If you don't want to change your source to call the MBean you can add -Doracle.jdbc.Trace=true
to your java execution command. This will log the entire execution.
For more info on configuring JDBC logging see the white paper on JDBC logging. A couple of hints: setting the Level to INFO will log the SQL that is executed, setting it to FINE will log entry and exit of all public methods, setting it to anything more than FINE will fill up all of your disk space with log files. You have been warned.
Server-Side Internal driver uses java.util.logging
for tracing output. You can use the convenient
OracleLog.properties file in the server by executing
System.setProperty("java.util.logging.config.file", "OracleLog.properties")
Put OracleLog.properties
into $ORACLE_HOME
.