Set - 4

Question 1 :

DB2 Universal claims to support JDBC 2.0, But I can only get JDBC 1.0 functionality. What can I do?

Answer :

DB2 Universal defaults to the 1.0 driver. You have to run a special program to enable the 2.0 driver and JDK support. For detailed information, see Setting the Environment in Building Java Applets and Applications. The page includes instructions for most supported platforms.


Question 2 :

How do I disallow NULL values in a table?

Answer :

Null capability is a column integrity constraint, normally applied at table creation time. Note that some databases won't allow the constraint to be applied after table creation. Most databases allow a default value for the column as well. The following SQL statement displays the NOT NULL constraint:
CREATE TABLE CoffeeTable (
Type VARCHAR(25) NOT NULL,
Pounds INTEGER NOT NULL,
Price NUMERIC(5, 2) NOT NULL
)


Question 3 :

How to get a field's value with ResultSet.getxxx when it is a NULL? I have tried to execute a typical SQL statement:

Answer :

select * from T-name where (clause);
But an error gets thrown because there are some NULL fields in the table. ?

You should not get an error/exception just because of null values in various columns. This sounds like a driver specific problem and you should first check the original and any chained exceptions to determine if another problem exists. In general, one may retrieve one of three values for a column that is null, depending on the data type. For methods that return objects, null will be returned; for numeric ( get Byte(), getShort(), getInt(), getLong(), getFloat(), and getDouble() ) zero will be returned; for getBoolean() false will be returned. To find out if the value was actually NULL, use ResultSet.wasNull() before invoking another getXXX method.


Question 4 :

How do I insert/update records with some of the columns having NULL value?

Answer :

Use either of the following PreparedStatement methods:
public void setNull(int parameterIndex, int sqlType) throws SQLException
public void setNull(int paramIndex, int sqlType, String typeName) throws SQLException
These methods assume that the columns are nullable. In this case, you can also just omit the columns in an INSERT statement; they will be automatically assigned null values.


Question 5 :

Is there a way to find the primary key(s) for an Access Database table? Sun's JDBC-ODBC driver does not implement the getPrimaryKeys() method for the DatabaseMetaData Objects?

Answer :

// Use meta.getIndexInfo() will
//get you the PK index. Once
// you know the index, retrieve its column name

DatabaseMetaData meta = con.getMetaData();

String key_colname = null;

// get the primary key information
rset = meta.getIndexInfo(null,null, table_name, true,true);
while( rset.next())
{
String idx = rset.getString(6);
if( idx != null)
{
//Note: index "PrimaryKey" is Access DB specific
// other db server has diff. index syntax.
if( idx.equalsIgnoreCase("PrimaryKey"))
{
key_colname = rset.getString(9);
setPrimaryKey( key_colname );
}
}
}


Question 6 :

Why can't Tomcat find my Oracle JDBC drivers in classes111.zip?

Answer :

TOMCAT 4.0.1 on NT4 throws the following exception when I try to connect to Oracle DB from JSP.
javax.servlet.ServletException : oracle.jdbc.driver.OracleDriver
java.lang.ClassNotFoundException: oracle:jdbc:driver:OracleDriver
But, the Oracle JDBC driver ZIP file (classes111.zip)is available in the system classpath.
Copied the Oracle Driver class file (classes111.zip) in %TOMCAT_Home - Home%\lib directory and renamed it to classess111.jar.
Able to connect to Oracle DB from TOMCAT 4.01 via Oracle JDBC-Thin Driver.


Question 7 :

I have an application that queries a database and retrieves the results into a JTable. This is the code in the model that seems to be taken forever to execute, especially for a large result set:
while ( myRs.next() ) {
Vector newRow =new Vector();

for ( int i=1;i<=numOfCols;i++ )
{
newRow.addElement(myRs.getObject(i));
}
allRows.addElement(newRow);
}
fireTableChanged(null);

newRow stores each row of the resultset and allRows stores all the rows.
Are the vectors here the problem?
Is there another way of dealing with the result set that could execute faster?

Answer :

java.util.Vector is largely thread safe, which means that there is a greater overhead in calling addElement() as it is a synchronized method. If your result set is very large, and threading is not an issue, you could use one of the thread-unsafe collections in Java 2 to save some time. java.util.ArrayList is the likeliest candidate here.
Do not use a DefaultTableModel as it loads all of your data into memory at once, which will obviously cause a large overhead - instead, use an AbstractTableModel and provide an implementation which only loads data on demand, i.e. when (if) the user scrolls down through the table.


Question 8 :

How does one get column names for rows returned in a ResultSet?

Answer :

ResultSet rs = ...
...
ResultSetMetaData rsmd = rs.getMetaData();
int numCols = rsmd.getColumnCount();

for (int i = 1; i <= numCols; i++)
{
System.out.println("[" + i + "]" +
rsmd.getColumnName(i) + " {" +
rsmd.getColumnTypeName(i) + "}");
}


Question 9 :

What are the considerations for deciding on transaction boundaries?

Answer :

Transaction processing should always deal with more than one statement and a transaction is often described as a Logical Unit of Work ( LUW ). The rationale for transactions is that you want to know definitively that all or none of the LUW completed successfully. Note that this automatically gives you restart capability. Typically, there are two conditions under which you would want to use transactions:
* Multiple statements involving a single file - An example would be inserting all of a group of rows or all price updates for a given date. You want all of these to take effect at the same time; inserting or changing some subset is not acceptable.
* Multiple statements involving multiple files - The classic example is transferring money from one account to another or double entry accounting; you don't want the debit to succeed and the credit to fail because money or important records will be lost. Another example is a master/detail relationship, where, say, the master contains a total column. If the entire LUW, writing the detail row and updating the master row, is not completed successfully, you A) want to know that the transaction was unsuccessful and B) that a portion of the transaction was not lost or dangling.
Therefore, determining what completes the transaction or LUW should be the deciding factor for transaction boundaries.


Question 10 :

How can I determine where a given table is referenced via foreign keys?

Answer :

DatabaseMetaData.getExportedKeys() returns a ResultSet with data similar to that returned by DatabaseMetaData.getImportedKeys(), except that the information relates to other tables that reference the given table as a foreign key container.


Question 11 :

How can I get information about foreign keys used in a table?

Answer :

DatabaseMetaData.getImportedKeys() returns a ResultSet with data about foreign key columns, tables, sequence and update and delete rules.


Question 12 :

Can I use JDBC to execute non-standard features that my DBMS provides?

Answer :

The answer is a qualified yes. As discussed under SQL Conformance: "One way the JDBC API deals with this problem is to allow any query string to be passed through to an underlying DBMS driver. This means that an application is free to use as much SQL functionality as desired, but it runs the risk of receiving an error on some DBMSs. In fact, an application query may be something other than SQL, or it may be a specialized derivative of SQL designed for specific DBMSs (for document or image queries, for example)."
Clearly this means either giving up portability or checking the DBMS currently used before invoking specific operations.


Question 13 :

What is DML?

Answer :

DML is an abbreviation for Data Manipulation Language. This portion of the SQL standard is concerned with manipulating the data in a database as opposed to the structure of a database. The core verbs for DML are SELECT, INSERT, DELETE, UPDATE, COMMIT and ROLLBACK.


Question 14 :

What is the significance of DataBaseMetaData.tableIndexStatistics? How to obtain and use it?

Answer :

To answer the second question first, the tableIndexStatistic constant in the TYPE column will identify one of the rows in the ResultSet returned when DatabaseMetaData.getIndexInfo() is invoked. If you analyze the wordy API, a tableIndexStatistic row will contain the number of rows in the table in the CARDINALITY column and the number of pages used for the table in the PAGES column.


Question 15 :

What types of DataSource objects are specified in the Optional Package?

Answer :

* Basic - Provides a standard Connection object.
* Pooled - Provides a Connection pool and returns a Connection that is controlled by the pool.
* Distributed - Provides a Connection that can participate in distributed transactions ( more than one DBMS is involved). It is anticipated, but not enforced, that a distributed DataSource will also provide pooling.

However, there are no standard methods available in the DataSource class to determine if one has obtained a pooled and/or distributed Connection.


Question 16 :

What is a JDBC 2.0 DataSource?

Answer :

The DataSource class was introduced in the JDBC 2.0 Optional Package as an easier, more generic means of obtaining a Connection. The actual driver providing services is defined to the DataSource outside the application ( Of course, a production quality app can and should provide this information outside the app anyway, usually with properties files or ResourceBundles ). The documentation expresses the view that DataSource will replace the common DriverManager method.


Question 17 :

Does the database server have to be running Java or have Java support in order for my remote JDBC client app to access the database?

Answer :

The answer should always be no. The two critical requirements are LAN/internet connectivity and an appropriate JDBC driver. Connectivity is usually via TCP/IP, but other communication protocols are possible. Unspoken, but assumed here is that the DBMS has been started to listen on a communications port. It is the JDBC driver's job to convert the SQL statements and JDBC calls to the DBMS' native protocol. From the server's point of view, it's just another data request coming into the port, the programming language used to send the data is irrelevant at that point.


Question 18 :

Which Java and java.sql data types map to my specific database types?

Answer :

JDBC is, of necessity, reliant on the driver and underlying DBMS. These do not always adhere to standards as closely as we would like, including differing names for standard Java types. To deal with this, first, there are a number of tables available in the JDK JDBC documentation dealing with types.


Question 19 :

Are the code examples from the JDBC API Tutorial and Reference, Second Edition available online?

Answer :

Yes.


Question 20 :

When an SQL select statement doesn't return any rows, is an SQLException thrown?

Answer :

No. If you want to throw an exception, you could wrap your SQL related code in a custom class and throw something like ObjectNotFoundException when the returned ResultSet is empty.


Question 21 :

Why should I consider optimistic versus pessimistic approaches to database updates?

Answer :

In a modern database, possibly the two most important issues are data integrity and concurrency ( multiple users have access to and can update the data ). Either approach can be appropriate, depending on the application, but it is important to be aware of possible consequences to avoid being blindsided.
A pessimistic approach, with locks, is usually seen as good for data integrity, although it can be bad for concurrency, especially the longer a lock is held. In particular, it guarantees against 'lost updates' - defined as an update performed by one process between the time of access and update by another process, which overwrites the interim update. However, other users are blocked from updating the data and possibly reading it as well if the read access also tries to acquire a lock. A notorious problem can arise when a user accesses data for update and then doesn't act on it for a period of time. Another situation that occurred with one of my clients is that a batch ( non-interactive ) process may need to update data while an interactive user has an update lock on the same data. In that case, data integrity goes out the window and, depending on how the application is written, more problems may be introduced. ( No, we did not write the interactive update program and yes, we had recovery procedures in place. )
An optimstic approach can alleviate lock concurrency problems, but requires more code and care for integrity. The "optimistic" definition usually says that expectations of update clashes are rare, but I view them as normal occurrances in a heavily used database. The basics are that any changes between time of access and time of update must be detected and taken into account. This is often done by comparing timestamps, but one must be sure that the timestamp is always changed for an update and, of course, that the table contains a timestamp column. A more involved, but more complete method involves saving the original columns and using them in the 'Where' clause of the Update statement. If the update fails, the data has changed and the latest data should be reaccessed.


Question 22 :

What is optimistic concurrency?

Answer :

An optimistic approach dispenses with locks ( except during the actual update ) and usually involves comparison of timestamps, or generations of data to ensure that data hasn't changed between access and update times. It's generally explained that the term optimistic is used because the expectation is that a clash between multiple updates to the same data will seldom occur.


Question 23 :

What is pessimistic concurrency?

Answer :

With a pessimistic approach, locks are used to ensure that no users, other than the one who holds the lock, can update data. It's generally explained that the term pessimistic is used because the expectation is that many users will try to update the same data, so one is pessimistic that an update will be able to complete properly. Locks may be acquired, depending on the DBMS vendor, automatically via the selected Isolation Level. Some vendors also implement 'Select... for Update', which explicitly acquires a lock.


Question 24 :

Can I get information about a ResultSet's associated Statement and Connection in a method without having or adding specific arguments for the Statement and Connection?

Answer :

Yes. Use ResultSet.getStatement(). From the resulting Statement you can use Statement.getConnection().


Question 25 :

How can I tell if my JDBC driver normalizes java.sql.Date and java.sql.Time objects?

Answer :

To actually determine the values, the objects must be converted to a java.util.Date and examined. See What does normalization mean for java.sql.Date and java.sql.Time? for the definition of normalization. Notice that even a debugger will not show whether these objects have been normalized, since the getXXX methods in java.sql.Date for time elements and in java.sql.Time for date elements throw an exception.
So, while a java.sql.Date may show 2001-07-26, it's normalized only if the java.util.Date value is:
Thu Jul 26 00:00:00 EDT 2001
and while a java.sql.Time may show 14:01:00, it's normalized only if the java.util.Date value is:
Thu Jan 01 14:01:00 EST 1970


Question 26 :

What is the most efficient method of replicating data between databases using JDBC?

Answer :

Within Java, the most efficient method would be, opening connections using the JDBC and inserting or updating the records from one database to the other database, but it depends upon the databases being replicated. If you are using Oracle databases, it has standard methods for replication, and you do not need the JDBC for the replication. Use snapshots like updateable and read-only.
There are different kind of replication. Let us consider the most widely used ones:

A) One Master - One slave
I) If there is not a significant difference between the structure of the database tables, the following method would be useful.
FromDatabase=A; ToDatabase=B
1) Open JDBC connections between the databases A and B.
2) Read a record (RA ) from A using an SQL query.
3) Store the values in the local variables in the Java program.
4) Insert the record in B if PK does not exist for the record RA in B.
5) If the PK exists in B, update the record in B.
6) Repeat the steps 2-5 'til all the records are read by the query.
7) If there are multiple tables to be replicated, repeat steps 2-7 using the different queries.
II)If there is significant difference between the structure of the database tables, the following method would be useful.
FromDatabase=A; ToDatabase=B
1) Open the JDBC connections to the databases A.
2) Read a record ( RA ) from A using an SQL query.
3) Write the output to an XML file-XMLA, according to the DTD for the records for the database A structure.
4) Repeat steps 2 & 3 'til all the records are written to XMLA.
5) If there are more queries, repeat steps repeat steps from 2-4 and write the records to the different entities in the XML file.
6) Transform the XMLA file using the XSL and XSLT to the format useful for the database B and write to the XML file-XMLB.
7) Open the second JDBC connection to the Database B.
8) Read the XMLB file, one record at a time.
9) Insert the record in B if PK does not exist for the record RA in B.
10) If the PK exists in B, update the record in B.
B) One Master - Multiple slaves
The difference here is to open multiple JDBC connections to write to the different databases one record at a time.
C) Multiple Masters:
For multiple masters, use timestamps to compare the times of the records to find out which is the latest record when a record is found in all the master databases. Alternatively, create a column to store the time and date a record is inserted or updated. When records are deleted, record the event in a log file along with the PK.
Prepared statements and batch updates should be used wherever possible in this scenario.


Question 27 :

What is the difference between setMaxRows(int) and SetFetchSize(int)? Can either reduce processing time?

Answer :

setFetchSize(int) defines the number of rows that will be read from the database when the ResultSet needs more rows. The method in the java.sql.Statement interface will set the 'default' value for all the ResultSet derived from that Statement; the method in the java.sql.ResultSet interface will override that value for a specific ResultSet. Since database fetches can be expensive in a networked environment, fetch size has an impact on performance.
setMaxRows(int) sets the limit of the maximum nuber of rows in a ResultSet object. If this limit is exceeded, the excess rows are "silently dropped". That's all the API says, so the setMaxRows method may not help performance at all other than to decrease memory usage. A value of 0 (default) means no limit.
Since we're talking about interfaces, be careful because the implementation of drivers is often different from database to database and, in some cases, may not be implemented or have a null implementation. Always refer to the driver documentation.


Question 28 :

What is JDO?

Answer :

JDO provides for the transparent persistence of data in a data store agnostic manner, supporting object, hierarchical, as well as relational stores.


Question 29 :

When I intersperse table creation or other DDL statements with DML statements, I have a problem with a transaction being commited before I want it to be. Everything ( commit and rollback ) works fine as long as I don't create another table. How can I resolve the issue?

Answer :

While the questioner found a partially workable method for his particular DBMS, as mentioned in the section on transactions in my JDBC 2.0 Fundamentals Short Course:
DDL statements in a transaction may be ignored or may cause a commit to occur. The behavior is DBMS dependent and can be discovered by use of DatabaseMetaData.dataDefinitionCausesTransactionCommit() and DatabaseMetaData.dataDefinitionIgnoredInTransactions(). One way to avoid unexpected results is to separate DML and DDL transactions.
The only generally effective way to "rollback" table creation is to delete the table.


Question 30 :

What's the best way, in terms of performance, to do multiple insert/update statements, a PreparedStatement or Batch Updates?

Answer :

Because PreparedStatement objects are precompiled, their execution can be faster than that of Statement objects. Consequently, an SQL statement that is executed many times is often created as a PreparedStatement object to increase efficiency.
A CallableStatement object provides a way to call stored procedures in a standard manner for all DBMSes. Their execution can be faster than that of PreparedStatement object.
Batch updates are used when you want to execute multiple statements together. Actually, there is no conflict here. While it depends on the driver/DBMS engine as to whether or not you will get an actual performance benefit from batch updates, Statement, PreparedStatement, and CallableStatement can all execute the addBatch() method.


Question 31 :

I need to have result set on a page where the user can sort on the column headers. Any ideas?

Answer :

One possibility: Have an optional field in your form or GET url called (appropriately) ORDER with a default value of either "no order" or whatever you want your default ordering to be (i.e. timestamp, username, whatever). When you get your request, see what the value of the ORDER element is. If it's null or blank, use the default. Use that value to build your SQL query, and display the results to the page. If you're caching data in your servlet, you can use the Collection framework to sort your data (see java.util.Collections) if you can get it into a List format. Then, you can create a Collator which can impose a total ordering on your results.


Question 32 :

What are the components of the JDBC URL for Oracle's "thin" driver and how do I use them?

Answer :

Briefly: jdbc:oracle:thin:@hostname:port:oracle-sid
1. in green the Oracle sub-protocol (can be oracle:oci7:@, oracle:oci8:@, racle:thin:@, etc...) is related on the driver you are unsign and the protocol to communicate with server.
2. in red the network machine name, or its ip address, to locate the server where oracle is running.
3. in blue the port (it is complementary to the address to select the specific oracle service)
4. in magenta the sid, select on which database you want to connect.

example:
jdbc:oracle:thin:@MyOracleHost:1521:MyDB
IHere's an example:
jdbc:oracle:thin:scott/tiger@MyOracleHost:1521:MyDB
where user=scott and pass=tiger.


Question 33 :

Why doesn't JDBC accept URLs instead of a URL string?

Answer :

In order for something to be a java.net.URL, a protocol handler needs to be installed. Since there is no one universal protocol for databases behind JDBC, the URLs are treated as strings. In Java 1.4, these URL strings have a class called java.net.URI. However, you still can't use a URI to load a JDBC driver, without converting it to a string.


Question 34 :

What JDBC objects generate SQLWarnings?

Answer :

Connections, Statements and ResultSets all have a getWarnings method that allows retrieval. Keep in mind that prior ResultSet warnings are cleared on each new read and prior Statement warnings are cleared with each new execution. getWarnings() itself does not clear existing warnings, but each object has a clearWarnings method.


Question 35 :

What's the fastest way to normalize a Time object?

Answer :

Of the two recommended ways when using a Calendar( see How do I create a java.sql.Time object? ), in my tests, this code ( where c is a Calendar and t is a Time ):

c.set( Calendar.YEAR, 1970 );
c.set( Calendar.MONTH, Calendar.JANUARY );
c.set( Calendar.DATE, 1 );
c.set( Calendar.MILLISECOND, 0 );

t = new java.sql.Time( c.getTime().getTime() );
was always at least twice as fast as:

t = java.sql.Time.valueOf(
c.get(Calendar.HOUR_OF_DAY) + ":" +
c.get(Calendar.MINUTE) + ":" +
c.get(Calendar.SECOND) );

When the argument sent to valueOf() was hardcoded ( i.e. valueOf( "13:50:10" ), the time difference over 1000 iterations was negligible.


Question 36 :

What does normalization mean for java.sql.Date and java.sql.Time?

Answer :

These classes are thin wrappers extending java.util.Date, which has both date and time components. java.sql.Date should carry only date information and a normalized instance has the time information set to zeros. java.sql.Time should carry only time information and a normalized instance has the date set to the Java epoch ( January 1, 1970 ) and the milliseconds portion set to zero.


Question 37 :

How do I create a java.sql.Date object?

Answer :

java.sql.Date descends from java.util.Date, but uses only the year, month and day values. There are two methods to create a Date object. The first uses a Calendar object, setting the year, month and day portions to the desired values. The hour, minute, second and millisecond values must be set to zero. At that point, Calendar.getTime().getTime() is invoked to get the java.util.Date milliseconds. That value is then passed to a java.sql.Date constructor:
Calendar cal = Calendar.getInstance();
// set Date portion to January 1, 1970
cal.set( cal.YEAR, 1970 );
cal.set( cal.MONTH, cal.JANUARY );
cal.set( cal.DATE, 1 );

cal.set( cal.HOUR_OF_DAY, 0 );
cal.set( cal.MINUTE, 0 );
cal.set( cal.SECOND, 0 );
cal.set( cal.MILLISECOND, 0 );

java.sql.Date jsqlD =
new java.sql.Date( cal.getTime().getTime() );

The second method is java.sql.Date's valueOf method. valueOf() accepts a String, which must be the date in JDBC time escape format - "yyyy-mm-dd". For example,

java.sql.Date jsqlD = java.sql.Date.valueOf( "2010-01-31" );
creates a Date object representing January 31, 2010. To use this method with a Calendar object, use:

java.sql.Date jsqlD = java.sql.Date.valueOf(
cal.get(cal.YEAR) + ":" +
cal.get(cal.MONTH) + ":" +
cal.get(cal.DATE) );

which produces a Date object with the same value as the first example.


Question 38 :

How do I create a java.sql.Time object?

Answer :

java.sql.Time descends from java.util.Date, but uses only the hour, minute and second values. There are two methods to create a Time object. The first uses a Calendar object, setting the year, month and day portions to January 1, 1970, which is Java's zero epoch. The millisecond value must also be set to zero. At that point, Calendar.getTime().getTime() is invoked to get the time in milliseconds. That value is then passed to a Time constructor:

Calendar cal = Calendar.getInstance();
// set Date portion to January 1, 1970
cal.set( cal.YEAR, 1970 );
cal.set( cal.MONTH, cal.JANUARY );
cal.set( cal.DATE, 1 );

cal.set( cal.MILLISECOND, 0 );
java.sql.Time jsqlT =
new java.sql.Time( cal.getTime().getTime() );

The second method is Time's valueOf method. valueOf() accepts a String, which must be the time in JDBC time escape format - "hh:mm:ss". For example,
java.sql.Time jsqlT = java.sql.Time.valueOf( "18:05:00" );
creates a Time object representing 6:05 p.m. To use this method with a Calendar object, use:
java.sql.Time jsqlT = java.sql.Time.valueOf(
cal.get(cal.HOUR_OF_DAY) + ":" +
cal.get(cal.MINUTE) + ":" +
cal.get(cal.SECOND) );

which produces a Time object with the same value as the first example.


Question 39 :

What scalar functions can I expect to be supported by JDBC?

Answer :

JDBC supports numeric, string, time, date, system, and conversion functions on scalar values. For a list of those supported and additional information, see section A.1.4 Support Scalar Functions in the JDBC Data Access API For Driver Writers. Note that drivers are only expected to support those scalar functions that are supported by the underlying DB engine.


Question 40 :

What does setFetchSize() really do?

Answer :

The API documentation explains it pretty well, but a number of programmers seem to have a misconception of its functionality. The first thing to note is that it may do nothing at all; it is only a hint, even to a JDBC Compliant driver. setFetchSize() is really a request for a certain sized blocking factor, that is, how much data to send at a time.
Because trips to the server are expensive, sending a larger number of rows can be more efficient. It may be more efficient on the server side as well, depending on the particular SQL statement and the DB engine. That would be true if the data could be read straight off an index and the DB engine paid attention to the fetch size. In that case, the DB engine could return only enough data per request to match the fetch size. Don't count on that behavior. In general, the fetch size will be transparent to your program and only determines how often requests are sent to the server as you traverse the data.
Also, both Statement and ResultSet have setFetchSize methods. If used with a Statement, all ResultSets returned by that Statement will have the same fetch size. The method can be used at any time to change the fetch size for a given ResultSet. To determine the current or default size, use the getFetchSize methods.


Question 41 :

Is there a practical limit for the number of SQL statements that can be added to an instance of a Statement object

Answer :

While the specification makes no mention of any size limitation for Statement.addBatch(), this seems to be dependent, as usual, on the driver. Among other things, it depends on the type of container/collection used. I know of at least one driver that uses a Vector and grows as needed. I've seen questions about another driver that appears to peak somewhere between 500 and 1000 statements. Unfortunately, there doesn't appear to be any metadata information regarding possible limits. Of course, in a production quality driver, one would expect an exception from an addBatch() invocation that went beyond the command list's limits.


Question 42 :

How can I determine whether a Statement and its ResultSet will be closed on a commit or rollback?

Answer :

Use the DatabaseMetaData methods supportsOpenStatementsAcrossCommit() and supportsOpenStatementsAcrossRollback().


Question 43 :

How do I get runtime information about the JDBC Driver?

Answer :

Use the following DatabaseMetaData methods:
getDriverMajorVersion()
getDriverMinorVersion()
getDriverName()
getDriverVersion()


Question 44 :

How do I create an updatable ResultSet?

Answer :

Just as is required with a scrollable ResultSet, the Statement must be capable of returning an updatable ResultSet. This is accomplished by asking the Connection to return the appropriate type of Statement using Connection.createStatement(int resultSetType, int resultSetConcurrency). The resultSetConcurrency parameter must be ResultSet.CONCUR_UPDATABLE. The actual code would look like this:

Statement stmt = con.createStatement( ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE );

Note that the spec allows a driver to return a different type of Statement/ResultSet than that requested, depending on capabilities and circumstances, so the actual type returned should be checked with ResultSet.getConcurrency().


Question 45 :

How can I connect to an Oracle database not on the web server from an untrusted applet?

Answer :

You can use the thin ORACLE JDBC driver in an applet (with some extra parameters on the JDBC URL). Then, if you have NET8, you can use the connection manager of NET8 on the web server to proxy the connection request to the database server.


Question 46 :

How can I insert multiple rows into a database in a single transaction?

Answer :

//turn off the implicit commit
Connection.setAutoCommit(false);
//..your insert/update/delete goes here
Connection.Commit();
a new transaction is implicitly started.
JDBC 2.0 provides a set of methods for executing a batch of database commands. Specifically, the java.sql.Statement interface provides three methods: addBatch(), clearBatch() and executeBatch(). Their documentation is pretty straight forward.
The implementation of these methods is optional, so be sure that your driver supports these.