Professional Documents
Culture Documents
Location: http://www.jguru.com/faq/JDBC
Ownership: http://www.jguru.com/misc/user-agree.jsp#ownership.
jdbc:[subprotocol]:[node]/[databaseName]
If you are accessing a database called wham on the server yoghurt.jguru.com using
the xyz subprotocol, your database URL could be:
jdbc:xyz:yoghurt.jguru.com/wham
If the database resides on the same computer node as the java program, the
hostname part and the corresponding double slashes of the jdbc can be skipped:
jdbc:odbc:wham
All standard database URLs should commence with the string jdbc.
The IP Port
Author: Guillermo Alvarez (http://www.jguru.com/guru/viewbio.jsp?EID=819342),
Apr 1, 2002
What happens with the IP port? is JDBC always "listening" by the same port, or we
have to define it in the URL? Thanks
why :odbc??
my RAD need the URL for success.
thanks...
View on browser
Author: Rati Naren (http://www.jguru.com/guru/viewbio.jsp?EID=990238), Aug 28,
2002
Can we use this URL to view some database details over the browser ?
Short answer:
Longer answer: Most relational databases handles a JDBC / SQL query in four steps:
A Statement will always proceed through the four steps above for each SQL query
sent to the database. A PreparedStatement pre-executes steps (1) - (3) in the
execution process above. Thus, when creating a PreparedStatement some pre-
optimization is performed immediately. The effect is to lessen the load on the database
engine at execution time.
Code samples
Statement example
Hi Lennart ,
I have couple of doughts regarding the execution of prepared statement.
Where do these 4 sequence of steps takes place ? whether at JDBC end or at the
Database end ?
If the these steps takes place at JDBC level , how does database executes the
statements that are parsed/complied by JDBC.
Where this data is stored ?
Thanks & regards,
Adi
For SQL statements that are executed repeatedly, using a PreparedStatement object
would almost always be faster than using a Statement object. This is because
creating a PreparedStatement object by explicitly giving the SQL statement causes
the statement to be precompiled within the database immediately. Thus, when the
PreparedStatement is later executed, the DBMS does not have to recompile the SQL
statement and prepared an execution plan - it simply runs the statement.
Typically, PreparedStatement objects are used for SQL statements that take
parameters. However, they can also be used with repeatedly executed SQL
statements that do not accept parameters.
At the begging, I had the same idea that using PreparedStatement to execute queries
should run faster than the Statement in most cases until I wrote a program to test.
I used the MS-SQL as my DBMS and the JDBC from Microsoft. I randomly fetched
10 records through a huge table. I found that using Statement in fact is faster than the
PreparedStatement. In the test program, I also carefully not to close Stament and
PreparedStatment objects to make sure that the driver potentially can take advantage
of it.
So far, I cannot found any good explation yet. But in the book, "Java Programming
with Oracle JDBC", the author has the same test result as me. He did raise the good
point of different application scenarios needs different choices.
Quite often in database processing, we come across the situation wherein one
transaction can change a value, and a second transaction can read this value before
the original change has been committed or rolled back. This is known as a dirty read
scenario because there is always the possibility that the first transaction may
rollback the change, resulting in the second transaction having read an invalid value.
While you can easily command a database to disallow dirty reads, this usually
degrades the performance of your application due to the increased locking overhead.
Disallowing dirty reads also leads to decreased system concurrency.
A good example of this is to timestamp each row in a result set and compare the
timestamps from one read to another.
Although you may want to avoid it, you can change the transaction isolation level in
the midst of executing a transaction. However, this will immediately freeze all the
changes made upto that point, as a commit() is automatically invoked.
// Get DatabaseMetaData
DatabaseMetaData dbmd = conn.getMetaData();
// Printout
System.out.println("" + dbObjectType + ": " + dbObjectName);
System.out.println(" Catalog: " + dbObjectCatalog);
System.out.println(" Schema: " + dbObjectSchema);
}
// Get DatabaseMetaData
DatabaseMetaData dbmd = conn.getMetaData();
The DatabaseMetaData interface has methods for discovering all the Catalogs, Schemas,
Tables and Stored Procedures in the database server. The methods are pretty intuitive,
returning a ResultSet with a single String column; use them as indicated in the code
below:
// Get DatabaseMetaData
DatabaseMetaData dbmd = conn.getMetaData();
// Get DatabaseMetaData
DatabaseMetaData dbmd = conn.getMetaData();
// Printout
System.out.println("Col(" + dbOrdinalPosition + "): " +
dbColumnName
+ " (" + dbColumnTypeName +")");
System.out.println(" Nullable: " + dbColumnIsNullable +
", Size: " + dbColumnSize);
System.out.println(" Position in table: " +
dbOrdinalPosition
+ ", Decimal digits: " + dbDecimalDigits);
}
How do I extract the SQL statements required to move all tables and views
from an existing database to another database?
Location: http://www.jguru.com/faq/view.jsp?EID=1185
Created: Nov 21, 1999
Author: Lennart Jorelid (http://www.jguru.com/guru/viewbio.jsp?EID=15)
// Get DatabaseMetaData
DatabaseMetaData dbmd = conn.getMetaData();
// Printout
System.out.println("Procedure: " + dbProcedureName
+ ", returns: " + procReturn);
System.out.println(" [Catalog | Schema]: [" +
dbProcedureCatalog
+ " | " + dbProcedureSchema + "]");
System.out.println(" Comments: " + dbProcedureRemarks);
}
How can I investigate the parameters to send into and receive from a
database stored procedure?
Location: http://www.jguru.com/faq/view.jsp?EID=1187
Created: Nov 21, 1999
Author: Lennart Jorelid (http://www.jguru.com/guru/viewbio.jsp?EID=15)
NOTE! This method can only discover parameter values. For databases where a returning
ResultSet is created simply by executing a SELECT statement within a stored procedure
(thus not sending the return ResultSet to the java application via a declared parameter),
the real return value of the stored procedure cannot be detected. This is a weakness for
the JDBC metadata mining which is especially present when handling Transact-SQL
databases such as those produced by SyBase and Microsoft.
// Get DatabaseMetaData
DatabaseMetaData dbmd = conn.getMetaData();
switch(dbColumnReturn)
{
case DatabaseMetaData.procedureColumnIn:
procReturn = "In";
break;
case DatabaseMetaData.procedureColumnOut:
procReturn = "Out";
break;
case DatabaseMetaData.procedureColumnInOut:
procReturn = "In/Out";
break;
case DatabaseMetaData.procedureColumnReturn:
procReturn = "return value";
break;
case DatabaseMetaData.procedureColumnResult:
procReturn = "return ResultSet";
default:
procReturn = "Unknown";
}
// Printout
System.out.println("Procedure: " + dbProcedureCatalog + "." +
dbProcedureSchema
+ "." + dbProcedureName);
System.out.println(" ColumnName
[ColumnType(ColumnPrecision)]: " + dbColumnName
+ " [" + dbColumnReturnTypeName + "(" +
dbColumnPrecision + ")]");
System.out.println(" ColumnReturns: " + procReturn + "(" +
dbColumnReturnTypeName + ")");
System.out.println(" Radix: " + dbColumnRadix + ", Scale: "
+ dbColumnScale);
System.out.println(" Remarks: " + dbColumnRemarks);
}
user
password
hostname
However, a JDBC driver may accept an arbitrary number of properties thrown at it.
Drivers can be interrogated for their supported properties using the
DriverPropertyInfo metadata class. Most drivers will also contain documentation
which should specify all properties and their meaning for creating the jdbc database
connection.
NOTE! The JDBC/ODBC bridge driver does not properly return an array of
DriverPropertyInfo objects, but instead throws a NullPointerException. Other database
drivers work better in this respect.
// Printout
System.out.println("" + propName +
" (Req: " + req + ")");
if(propChoices == null)
{
System.out.println(" No choices.");
}
else
{
System.out.print(" Choices: ");
for(int j = 0; j propChoices.length; j++)
{
System.out.print(" " + propChoices[j]);
}
}
java.sql.Blob, since it does not extract any data from the database until you
explicitly ask it to. The Java platform 2 type Blob wraps a database locator (which is
essentially a pointer to byte). That pointer is a rather large number (between 32 and
256 bits in size) - but the effort to extract it from the database is insignificant next to
extracting the full blob content. For insertion into the database, you should use a
byte[] since data has not been uploaded to the database yet. Thus, use the Blob
class only for extraction.
Conclusion: use the java.sql.Blob class for extraction whenever you can.
In EJB CMP i can't map one parameter to more than one type (i can choose
java.sql.Blob or byte[] - I would like use Blob
A BLOB (Binary Large OBject) is essentially an array of bytes (byte[]), stored in the
database. You extract the data in two steps:
Note that a Blob is essentially a pointer to a byte array (called LOCATOR in database-
talk), so the java.sql.Blob object essentially wraps a byte pointer. Thus, you must
extract all data from the database blob before calling commit or
<div align="center">
private void runGetBLOB()
{
try
{ // Prepare a Statement:
PreparedStatement stmnt = conn.prepareStatement("select aBlob
from BlobTable");
// Execute
ResultSet rs = stmnt.executeQuery();
while(rs.next())
{
try
{
// Get as a BLOB
Blob aBlob = rs.getBlob(1);
byte[] allBytesInBlob = aBlob.getBytes(1, (int)
aBlob.length());
}
catch(Exception ex)
{
// The driver could not handle this as a BLOB...
// Fallback to default (and slower) byte[] handling
byte[] bytes = rs.getBytes(1);
}
}
// Close resources
rs.close();
stmnt.close();
}
catch(Exception ex)
{
this.log("Error when trying to read BLOB: " + ex);
}
}
</div>
Comments and alternative answers
Seems much of jdbc is designed for database guys who think the world starts with 1,
rather than java/c/c++ programmers who know better... ;-)
--Joe
------------------------------------------------------------
import java.io.*;
import java.sql.*;
...
try {
String sql = "SELECT rowid, rowdata FROM blobs WHERE rowid = " +
rowid;
ResultSet rs = sment.executeQuery(sql);
if ( rs.next() ) {
try {
// Used to return how many bytes are read with each read() of
the input stream:
int bytesread = 0;
if ( (bytesread = bis.read(bindata,0,bindata.length)) != -1 ) {
}
}
rs.close();
sment.close();
} catch ( SQLException se ) {
System.err.println("Couldn't retrieve binary data: " + se);
} finally {
con.close();
}
return returndata;
}
java.sql.Clob, since it does not extract any data from the database until you explicitly
ask it to. The Java platform 2 type Clob wraps a database locator (which is
essentially a pointer to char). That pointer is a rather large number (between 32 and
256 bits in size) - but the effort to extract it from the database is insignificant next to
extracting the full Clob content. For insertion into the database, you should use a
String since data need not been downloaded from the database. Thus, use the Clob
class only for extraction.
Conclusion: Unless you always intend to extract the full textual data stored in the
particular table cell, use the java.sql.Clob class for extraction whenever you can.
Which is the preferred collection class to use for storing database result
sets?
Location: http://www.jguru.com/faq/view.jsp?EID=2286
Created: Dec 9, 1999 Modified: 2000-07-30 09:48:38.772
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7)
When retrieving database results, the best collection implementation to use is the
LinkedList. The benefits include:
Retains the original retrieval order
Has quick insertion at the head/tail
Doesn't have an internal size limitation like a Vector where when the
size is exceeded a new internal structure is created (or you have to
find out size beforehand to size properly)
Permits user-controlled synchronization unlike the pre-Collections
Vector which is always synchronized
Basically:
Sun maintains a fairly current list of JDBC drivers that support the JDBC 2.x and
JDBC 1.x APIs, at:
http://industry.java.sun.com/products/jdbc/drivers
If the underlying database doesn't support transactions, then all SQL statements will
be committed after execution, regardless of whether you have set auto commit or not.
See your database vendor's documentation and your JDBC driver's documentation for
detailed information about what features are supported in your specific case.
How can I retrieve only the first n rows, second n rows of a database using
a particular WHERE clause ? For example, if a SELECT typically returns a
1000 rows, how do first retrieve the 100 rows, then go back and retrieve
the next 100 rows and so on ?
Location: http://www.jguru.com/faq/view.jsp?EID=4757
Created: Jan 12, 2000 Modified: 2000-01-12 19:01:57.831
Author: Lennart Jorelid (http://www.jguru.com/guru/viewbio.jsp?EID=15)
Use the Statement.setFetchSize method to indicate the size of each database fetch.
Note that this method is only available in the Java 2 platform. For Jdk 1.1.X and Jdk
1.0.X, no standardized way of setting the fetch size exists. Please consult the Db
driver manual.
Comments and alternative answers
What does ResultSet actually contain? Is it the actual data of the result or
some links to databases? If it is the actual data then why can't we access it
after connection is closed?
Location: http://www.jguru.com/faq/view.jsp?EID=5053
Created: Jan 15, 2000 Modified: 2000-01-16 10:09:17.436
Author: Sameer Tyagi (http://www.jguru.com/guru/viewbio.jsp?EID=4381)
For example with the Odbc bridge what the underlying implementation layer contains
is an ODBC result set. A Type 4 driver executing a stored procedure that returns a
cursor - on an oracle database it actually returns a cursor in the databse. The oracle
cursor can however be processed like a ResultSet would be from the client.
Closing a connection closes all interaction with the database and releases any locks
that might have been obtained in the process.
Comments and alternative answers
What does ResultSet actually contain? Is it the actual data of the result or some
links to databases? If it is the actual data
Author: Parag Bharambe (http://www.jguru.com/guru/viewbio.jsp?EID=453237), Jul
12, 2001
I agree with that. But autually cursor is just a view of underlying Data. It need a
connection to view the data from DBMS. Once a connection is closed cursor is not
able to view the data. This is reason why you caanot view the Data once a connection
is closed. Am I right? If not please feel free to give ur sueeestion. Parag
One of the more advanced features of JDBC 2.0 is the ability to submit multiple
update statements to the database for processing as a single unit. This batch
updating can be significantly more efficient compared to JDBC 1.0, where each
update statement has to be executed separately.
try {
dbCon.setAutoCommit(false);
Before carrying out a batch update, it is important to disable the auto-commit mode
by calling setAutoCommit(false). This way, you will be able to rollback the batch
transaction in case one of the updates fail for any reason. When the Statement
object is created, it is automatically associated a "command list", which is initially
empty. We then add our SQL update statements to this command list, by making
successive calls to the addBatch() method. On calling executeBatch(), the entire
command list is sent over to the database, and are then executed in the order they
were added to the list. If all the commands in the list are executed successfully, their
corresponding update counts are returned as an array of integers. Please note that
you always have to clear the existing batch by calling clearBatch() before creating a
new one.
HI please let me know which verstion of Oracle supports Bach updates This is
an interesting article. I would appr...
Author: Gopi ch (http://www.jguru.com/guru/viewbio.jsp?EID=463010), Aug 27,
2001
Please let me know.which version of Oracle Jdbc Thni driver supports bach
updates.appreciated your earliest Response. Regards Gopi
batch updates
Author: venkata kumar merupula (http://www.jguru.com/guru/viewbio.jsp?
EID=1179305), Jun 16, 2004
this is very interesting concept and very useful when we update multiple rows
at a time.but this is not support all the drivers .I think this is support oracle 4th
driver. i want some more information about batch updates in jdbc.
cstmt.setString(1, "Colombian");
cstmt.setFloat(2, 8.49f);
cstmt.addBatch();
cstmt.setString(1, "Colombian_Decaf");
cstmt.setFloat(2, 9.49f);
cstmt.addBatch();
But I am not getting the above example working. The first update added to the batch
gets executed and the second one doesn't. I used DB2 Version 8 and the JDBC driver
shipped with that. So I want to know if i can run the same procedure in a batch with
different IN params as demonstrated in this example and does DB2 support that.
Please reply for this query.
Thankx
ramki
The next version of the ANSI/ISO SQL standard defines some new datatypes,
commonly referred to as the SQL3 types. The primary SQL3 types are:
STRUCT: This is the default mapping for any SQL structured type, and is manifest by
the java.sql.Struct type.
REF: Serves as a reference to SQL data within the database. Can be passed as a
parameter to a SQL statement. Mapped to the java.sql.Ref type.
ARRAY: Can store values of a specified type. Mapped to the java.sql.Array type.
You can retrieve, store and update SQL3 types using the corresponding getXXX(),
setXXX(), and updateXXX() methods defined in ResultSet interface
How can I manage special characters (for example: " _ ' % ) when I
execute an INSERT query? If I don't filter the quoting marks or the
apostrophe, for example, the SQL string will cause an error.
Location: http://www.jguru.com/faq/view.jsp?EID=8881
Created: Jan 26, 2000 Modified: 2000-10-26 17:48:58.547
Author: Tim Rohaly (http://www.jguru.com/guru/viewbio.jsp?EID=10) Question
originally posed by Stefano Cazzulani (http://www.jguru.com/guru/viewbio.jsp?
EID=5622
In JDBC, strings containing SQL commands are just normal strings - the SQL is not
parsed or interpreted by the Java compiler. So there is no special mechanism for
dealing with special characters; if you need to use a quote (") within a Java string,
you must escape it.
The Java programming language supports all the standard C escapes, such as \n for
newline, \t for tab, etc. In this case, you would use \" to represent a quote within a
string literal:
String stringWithQuote =
"\"No,\" he replied, \"I did not like that salted licorice.\"";
This only takes care of one part of the problem: letting us control the exact string
that is passed on to the database. If you want tell the database to interpret
characters like a single quote (') literally (and not as string delimiters, for instance),
you need to use a different method. JDBC allows you to specify a separate, SQL
escape character that causes the character following to be interpreted literally,
rather than as a special character.
Different flavors of SQL provide different methods to deal with this situation. JDBC
abstracts these methods and provides a solution that works for all databases. With
JDBC you could write the SQL as follows:
The characters "%" and "_" have special meaning in SQL LIKE clauses (to match
zero or more characters, or exactly one character, respectively). In order to interpret
them literally, they can be preceded with a special escape character in strings, e.g.
"\". In order to specify the escape character used to quote these characters, include
the following syntax on the end of the query:
{escape 'escape-character'}
For example, the query
SELECT NAME FROM IDENTIFIERS WHERE ID LIKE '\_%' {escape '\'}
finds identifier names that begin with an underbar.
Comments and alternative answers
Continuing
Author: glenn bullock (http://www.jguru.com/guru/viewbio.jsp?EID=846081), May
7, 2002
Another good way is to simply use PreparedStatements. Not only do you get the pre-
compile benefits PS's offer, but when you call the "add" methods, the escaping is done
for you.
Re: Continuing
Author: Willie Wheeler (http://www.jguru.com/guru/viewbio.jsp?EID=459006),
Sep 12, 2002
www.onjava.com/pub/a/onjava/excerpt/oraclejdbc_19/
Re[2]: Continuing
Author: Ashish Kapoor (http://www.jguru.com/guru/viewbio.jsp?
EID=1091036), Jun 4, 2003
I want to add the escape characters to all the apostophes in the SQL
commands. Does anyone know an efficient function that can add an escape
charachter to every apostrophe in a String. Eg String x = "Jame's garage";
should return "James''s garage"; and String x = "James's'g'a''"; should return
"James''s''g''a''''"); I am looking for some efficeint program possibly in java.
Regards Ashish www26.brinkster.com/akapoor/
Re[3]: Continuing
Author: David Bell (http://www.jguru.com/guru/viewbio.jsp?
EID=1096830), Jun 24, 2003
x = x.replaceAll("'","''");
% in where clause
Author: Nise Kuriakose (http://www.jguru.com/guru/viewbio.jsp?
EID=1142896), Feb 2, 2004
Hi Friends,
bye,
Nise
The java.sql package contains mostly interfaces. When and how are these
interfaces implemented while connecting to database?
Location: http://www.jguru.com/faq/view.jsp?EID=11164
Created: Feb 3, 2000 Modified: 2000-05-29 11:53:43.529
Author: Tim Rohaly (http://www.jguru.com/guru/viewbio.jsp?EID=10) Question
originally posed by arul senthil (http://www.jguru.com/guru/viewbio.jsp?EID=8904
The implementation of these interfaces is all part of the driver. A JDBC driver is not
just one class - it is a complete set of database-specific implementations for the
interfaces defined by the JDBC.
These driver classes come into being through a bootstrap process. This is best shown
by stepping through the process of using JDBC to connect to a database, using
Oracle's type 4 JDBC driver as an example:
First, the main driver class must be loaded into the VM:
Class.forName("oracle.jdbc.driver.OracleDriver");
The specified driver must implement the Driver interface. A class initializer
(static code block) within the OracleDriver class registers the driver with the
DriverManager.
So the purpose of a JDBC driver is to provide these implementations that hide all the
database-specific details behind standard Java interfaces.
Longer answer: You may create a digitally signed applet using a Certicate to
circumvent the security sandbox of the browser. See the Certificate jFAQ.
1. The hard way. Untrusted applets cannot touch the hard disk of a
computer. Thus, your applet cannot use native or other local files
(such as JDBC database drivers) on your hard drive. The first
alternative solution is to create a digitally signed applet which may use
locally installed JDBC drivers, able to connect directly to the database
on the server side.
2. The easy way. Untrusted applets may only open a network connection
to the server from which they were downloaded. Thus, you must place a
database listener (either the database itself, or a middleware server) on the
server node from which the applet was downloaded. The applet would
open a socket connection to the middleware server, located on the same
computer node as the webserver from which the applet was downloaded.
The middleware server is used as a mediator, connecting to and extract
data from the database. This is illustrated below:
How do I insert an image file (or other raw data) into a database?
Location: http://www.jguru.com/faq/view.jsp?EID=13000
Created: Feb 10, 2000 Modified: 2000-04-24 19:46:09.718
Author: Lennart Jorelid (http://www.jguru.com/guru/viewbio.jsp?EID=15) Question
originally posed by abhishek dubey (http://www.jguru.com/guru/viewbio.jsp?
EID=2207
All raw data types (including binary documents or images) should be read and
uploaded to the database as an array of bytes, byte[]. Originating from a binary file,
Having said that, the latest driver is 8.1.6 available on http://technet.oracle.com and
it should sort out the problems you are having.
I'm using a type 4 (pure Java) JDBC driver in an applet. It works fine in
Netscape, but doesn't work properly in Internet Explorer. Why not?
Location: http://www.jguru.com/faq/view.jsp?EID=15147
Created: Feb 17, 2000 Modified: 2000-09-14 06:26:53.349
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7) Question
originally posed by Rafal Kurianowicz (http://www.jguru.com/guru/viewbio.jsp?
EID=13323
With a 2.0 driver, you can use the setFetchSize() method within a Statement or a
ResultSet object.
For example,
You can also control the direction in which the rows are processed. For instance:
stmt.setFetchDirection(ResultSet.FETCH_REVERSE)
will process the rows from bottom up.
The driver manager usually defaults to the most efficient fetch size...so you may try
experimenting with different value for optimal performance.
Since your application retrieves a pooled connection, you don't consume your time to
connect / disconnect from your data source.
You can find some implementation of pooled connection over the net, for example:
You can look at the JDBC 2.0 standard extension API specification from SUN which
defines a number of additional concepts.
Comments and alternative answers
Enhydra
Build your own ObjectPool in Java to boost app speed
THE JDBC 2.0 OPTIONAL PACKAGE
Improved Performance with a Connection Pool
Writing Advanced Applications: Chapter 8 Continued: Connection Pooling
Connection Pools
Author: glenn bullock (http://www.jguru.com/guru/viewbio.jsp?EID=846081), May
7, 2002
Connection pools are nice, but most connections support concurrent statements,
which is much simpler to deal with (unless you're dealing with transactions, of
course).
Also, another nice idea is to have a Prepared Statement pool that will remove the
statement from the map when needed (don't want to execute it simultaneously), then
add it back in when you're done.
DBConnectionBroker Tips
Author: Nate McMorris (http://www.jguru.com/guru/viewbio.jsp?EID=929030), Jun
26, 2002
DbConnectionBroker from javexchange(http://www.javaexchange.com) is working
well. However...
There's almost no documentation. So here's what I found.
1) Start really simple, just create the broker object and NOTHING ELSE first.
2) When catching exceptions, use the method catching syntax ( public void method()
throws Exception {...} ) rather than using a "try {} catch(){}" clause.
3) You must create your log file first. The Broker won't create it if it doesn't exist.
4) If you're running this inside a JSP/Servlet container, you can't rely on the
container's class loader to find the database driver or any other classes you need from
the DbConnectionBroker class; you need to make sure the DB Driver etc. is
somewhere in your $CLASSPATH.
5) I needed to get this to work inside TOMCAT, and without using Servlets, so I
create the broker between the <jsp:useBean...> and </jsp:useBean> tags, then I load
that instance into a bean with an "application" cope. Then I can call that bean from
any page where I need a connection.
6) I couldn't get some of the methods (like idOfConnection() ) to work, so try the
methods out one by one to see if they work.
7) Lastly, the syntax for a MySQL connection is slightly different than the Oracle
Driver in the examples. I use DbConnectionBroker myBroker = new
DbConnectionBroker("org.gjt.mm.mysql.Driver","jdbc:mysql://yourdatabase
server/yourDb?user=user","","",4,5,"/path/to/brokerLog.log",1.0,true,0,3);
-
This method can be used with any database that supports timestamps and any driver
that supports PreparedStatement.
For Windows desktop databases, the JDataConnect driver (and a number of other
Windows specific type 3 drivers) support PreparedStatement. If the JDBC-ODBC
bridge isn't doing what you need, try a more industrial strength driver. You can
obtain a copy of JDataConnect from http://www.softsyn.com/.
I think that this should answer your question. It is recommended to retrieve the
results into an abitrary datastructure, but be aware that even if in Java parameters
are always passed per value; an object variable is a reference (i.e. can be seen as a
pointer to an object) and only that reference will be passed per value, but not the
object itself. That's a hint for the case that you suddenly get an exception accessing
an object you retrieved with myResultSet.getObject().
Comments and alternative answers
How do you find the number of records returned using the JDBC API? Is
there a direct function call(like in other languages)? Right now we have to
loop over the resultset to get the number(I guess the only way)
Location: http://www.jguru.com/faq/view.jsp?EID=26160
Created: Mar 20, 2000 Modified: 2000-03-23 14:22:55.823
Author: Dieter Wimberger (http://www.jguru.com/guru/viewbio.jsp?EID=25708)
Question originally posed by neal ravindran PREMIUM
(http://www.jguru.com/guru/viewbio.jsp?EID=17737
Well java.sql.ResultSet does not offer any method to retrieve the amount of rows
that have been selected.
Now I have following ideas that I hope might help:
1. It is recommended to retrieve the results into an abitray datastructure,
especially in case of pooled connections. Now ensure using a
datastructure that has an accessor method for its size.
2. Another possibility would be to use a seperate prepared statement that
returns nothing but a count of the rows that will be selected.
i.e. select count(*) from myTable
Instead of * you can also use any column existing in myTable.
3. A third way I could think of is to add the count(<column>) to the
request, thus retrieving the count of all rows as the first column of
each row.
i.e. select count(<existing column>),* from myTable
I am not sure if it really makes sense, but it's at least a possibility.
Is this incorrect behavior or are drivers allowed to behave this way? I'm assuming
that the -1 means "1 from the end of the resultset", similar to the semantics of
ResultSet's absolute(int row) method.
Anyone have any ideas apart from those already mentioned in this thread for how
to retrieve the number of rows in a RecordSet where the driver behaves this way?
If you do not use the suggested method or the correct parameters in that method, an
exception will be thrown if you attempt to access the first row again or you will have
to re-run the query and get a new Result Set.
I have stored image files in a database. Is there any way to display that
image in a web browser by querying the database?
Location: http://www.jguru.com/faq/view.jsp?EID=26164
Created: Mar 20, 2000 Modified: 2000-06-21 13:58:08.889
Author: Dieter Wimberger (http://www.jguru.com/guru/viewbio.jsp?EID=25708)
Question originally posed by chandra sekar
(http://www.jguru.com/guru/viewbio.jsp?EID=20353
I would recommend you to retrieve the image via JDBC from a simple HTTP servlet.
Ensure to set the correct Mime type. This has to be done calling
HttpServletResponse.setContentType(String type);
e.g. myHttpServletResponse.setContentType("image/jpeg");
Ensure that your RDBMS does not limit result sizes (i.e. check the
manuals if you get half images, and always the same block sizes).
Attach ?<param>=<value> to your src URL to specify the picture to be
retrieved. This param can be retrieved within your service method
very simple, using:
HttpServletRequest.getParameter(String name);
The HTML tag for the image would then be something like follows:
<img src="http://www.mydomain.com/PictureServlet?
id=35">
(Sure you can use more params if you need to do so.)
Use some simple or sophisticated caching algorithm to limit your
systems load.
Thanks!
With certain database systems, a stored procedure can return multiple result sets,
multiple update counts, or some combination of both. Also, if you are providing a
user with the ability to enter any SQL statement, you don't know if you are going to
get a ResultSet or an update count back from each statement, without analyzing
the contents. The Statement.execute() method helps in these cases.
How do I deal with multiple ResultSets that might have some empty result sets?
Author: tim chen (http://www.jguru.com/guru/viewbio.jsp?EID=387588), Apr 4, 2001
How do I deal with multiple ResultSets that might have some empty result sets? For
example, what happens when I run something like this: BEGIN SELECT name
FROM employees WHERE id <= 1 AND id >=10; SELECT name FROM
ex_employees WHERE id <=11 AND id >=20; SELECT name FROM bosses
WHERE id <=21 AND id >=30; END; I'm expecting 3 result sets back but what
happens if the second select statement returned no rows, but the other 2 select
statements return some rows. Will getMoreResults() return false or will it return true
and have getResultSet() return a null ResultSet? thanks, timbo
Here is an example on how to execute a stored procedure with JDBC (to use this in a
servlet is the same the only thing is that you create the connection and callable
statement in the init() of the servlet):
package DBTest;
import java.sql.*;
public JdbcTest() {
try {
Class.forName( msDbUrl ).newInstance();
mcDbAccess = DriverManager.getConnection( msJdbcClass,
"milestone", "milestone" );
msProcedure = mcDbAccess.prepareCall(
"{? = call sp_sav_Bom_Header( ?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) }"
);
msProcedure.registerOutParameter( 1,
java.sql.Types.VARCHAR );
msProcedure.setInt( 2, -1 );
msProcedure.setInt( 3, 39 );
msProcedure.setString( 4, "format" );
long ltTest = new java.util.Date().getTime();
System.out.println( "Today: " + ltTest );
msProcedure.setTimestamp( 5, new Timestamp( ltTest ) );
msProcedure.setString( 6, "type" );
msProcedure.setString( 7, "submitter" );
msProcedure.setString( 8, "email" );
msProcedure.setString( 9, "phone" );
msProcedure.setString( 10, "comments" );
msProcedure.setString( 11, "label" );
msProcedure.setInt( 12, 52 );
msProcedure.setBoolean( 13, true );
msProcedure.setBoolean( 14, false );
msProcedure.setInt( 15, 53 );
msProcedure.setString( 16, "runtime" );
msProcedure.setString( 17, "configuration" );
msProcedure.setBoolean( 18, true );
msProcedure.setBoolean( 19, false );
msProcedure.setString( 20, "special instructions" );
msProcedure.setInt( 21, 54 );
A cursor is actually always on the database server side. When you execute an SQL
SELECT and create a ResultSet in JDBC, the RDBMS creates a cursor in response.
When created, the cursor usually takes up temporary memory space of some sort
inside the database.
The SQLWarning class extends SQLException. You may therefore treat it as any normal
Exception type with respect to throwing and catching. However, the SQLException class
mimics a forward traversable, linked list of Exception objects. The reason for this
behavior is that a database generated SQLException rarely occurs alone - one syntactic
programming error leads to a suite of SQLException objects being generated. Use the
getNextException() method of the SQLException class, as seen in the class structure
below:
Creating SQLWarning
package se.jguru.dbTests;
// All OK.
System.out.println("Got all data.");
}
catch(SQLException ex)
{
// Printout root SQLException
System.err.println("An SQL exception occurred: " + ex);
if(somethingStrangeHappened)
{
// Create two custom SQL Warnings
SQLWarning rootWarning =
new SQLWarning("Business rules not properly regarded");
SQLWarning containedWarning =
new SQLWarning("Product too cheap!");
Although one may simply extract BLOB & CLOB data from the database using the
methods of the java.sql.CLOB and java.sql.BLOB, one must upload the data as normal
java datatypes. The example below inserts a BLOB in the form of a byte[] and a CLOB in
the form of a String into the database
// Perform insert
int rowsAffected = stmnt.executeUpdate();
}
The way I made it work was to insert data into the tables row first, then select
the clob columns back using a "select ... for update". Then you can use the
getCharacterOutputStream() api to write through to the clob columns. You also
have to have auto commit switched off to make this work.
I'm wondering if there is a better way. I'm using Oracle, but JDBC has no
support for the RETURNING clause in SQL, which would allow the lob
locators to be returned as part of the insert statement.
[END]
Since Excel comes with an ODBC driver, we'll use the JDBC-ODBC bridge driver that
comes packaged with Sun's JDK to connect to our spreadsheet.
In Excel, the name of the worksheet is the equivalent of the database table name,
while the header names found on the first row of the worksheet is the equivalent of
the table field names. Therefore, when accessing Excel via jdbc, it is very important
to place your data with the headers starting at row 1.
1. Create a new ODBC Data Source using the Microsoft Excel Driver. Name the DSN
"excel", and have it point to c:\users.xls.
package classes;
import java.sql.*;
try {
conn=DriverManager.getConnection("jdbc:odbc:excel","","");
stmt=conn.createStatement();
sql="select * from [Sheet1$]";
rs=stmt.executeQuery(sql);
while(rs.next()){
System.out.println(rs.getString("USERID")+
" "+ rs.getString("FIRST_NAME")+" "+
rs.getString("LAST_NAME"));
}
}
catch (Exception e){
System.err.println(e);
}
finally {
try{
rs.close();
stmt.close();
conn.close();
rs=null;
stmt=null;
conn=null;
}
catch(Exception e){}
}
}
}
Notice that we have connected to the Excel ODBC Data Source the same way we
would connect to any normal database server.
The only significant difference is in the SELECT statement. Although your data is
residing in the worksheet called "Sheet1", you'll have to refer to the sheet as
Sheet1$ in your SQL statements. And because the dollar sign symbol is a reserved
character in SQL, you'll have to encapsulate the word Sheet1$ in brackets, as shown
in the code.
Comments and alternative answers
I gave up on the idea to call it via JDBC & decided on using plain old file
reading to do the trick.
--Das
In my case, I have acolumn that has got both pure numeric(12345) and purely
alphanumeric(testing) type of data.
How can I get both the data? If alphanumeric data is the first data, it treats all the
values as alphanumerc and returns null for numeric and vice versa.
Thanks, Ajay
Without JDBC
Author: Stephen Ostermiller (http://www.jguru.com/guru/viewbio.jsp?EID=576685),
Apr 15, 2002
Export your data to Comma Separated Value (CSV) format and user libraries to read
and write this format:
http://ostermiller.org/utils/ExcelCSV.html
Use excelread by Andy Khan to get excel data into your java program:
http://www.andykhan.com/excelread/
The apache project has a library which called POI that can read and write the HSSF
(Horrible Spread Sheet Format) that excel uses.
http://jakarta.apache.org/poi/hssf/index.html
the reason im asking this is because, the example only used 1 excel file. you already
know the filename (user.xls) and its location (c:\)
for multiple excel files, you could probably configure them one by one in your
ODBC, but that is assuming you already know their filenames, and locations. what if
you don't know? what if you don't know how many excel files you will use?
[Updated Nov 20, 2002 to remove old description and point at some articles. TJP]
jGuru.com Case-Study.
Say that a returned ResultSet has 100 rows. After looping through 60 rows,
I want to return to row number 40 without querying the database again. Is
it possible?
Location: http://www.jguru.com/faq/view.jsp?EID=41183
Created: Apr 27, 2000 Modified: 2000-04-28 17:53:36.865
Author: Nicola Ken Barozzi (http://www.jguru.com/guru/viewbio.jsp?EID=39153)
Question originally posed by Monil Laddha
(http://www.jguru.com/guru/viewbio.jsp?EID=33536
To access rows in a database ResultSet you must use a JDBC 2.0 capable driver. If
the version number is lower you can only go forward; to go backwards or jump to a
specific row you must cache the results in a data structure on the client and use that
(if the table is big you might need a lot of memory, and things can get slow).
If you know how many rows you will be getting you can use an array of arrays,
otherwise a Vector of arrays (you know how many columns you have but not how
many rows).
If you need to do it because you need to show table data you can insert all the rows
in a DefaultTableModel (or your implementation of the TableModel interface) with
this DefaultTableModel method:
public void addRow(Object[] rowData)
Anyway here are some methods of Resultset you can use.
Javadoc:
/***************************************************/
public boolean next()
throws SQLException
Moves the cursor down one row from its current position. A ResultSet
cursor is initially positioned before the
first row; the first call to next makes the first row the current row;
the second call makes the second row the
current row, and so on.
If an input stream is open for the current row, a call to the method
next will implicitly close it. The ResultSet's
warning chain is cleared when a new row is read.
/***************************************************/
public boolean previous()
throws SQLException
JDBC 2.0
/***************************************************/
public boolean relative(int rows)
throws SQLException
JDBC 2.0
/***************************************************/
public boolean first()
throws SQLException
JDBC 2.0
/***************************************************/
public boolean last()
throws SQLException
JDBC 2.0
/***************************************************/
public boolean absolute(int row)
throws SQLException
JDBC 2.0
Moves the cursor to the given row number in the result set.
If the row number is positive, the cursor moves to the given row number
with respect to the beginning of the
result set. The first row is row 1, the second is row 2, and so on.
If the given row number is negative, the cursor moves to an absolute row
position with respect to the end of
the result set. For example, calling absolute(-1) positions the cursor
on the last row, absolute(-2)
indicates the next-to-last row, and so on.
/***************************************************/
What you see on the client side is the current row of the cursor which called a Result
(ODBC) or ResultSet (JDBC). The cursor is a server-side entity only and remains on
the server side.
Are prepared statements faster because they are compiled? if so, where and
when are they compiled?
Location: http://www.jguru.com/faq/view.jsp?EID=42139
Created: Apr 28, 2000 Modified: 2000-04-28 19:52:07.157
Author: Richard Katz (http://www.jguru.com/guru/viewbio.jsp?EID=25710) Question
originally posed by sharma MR (http://www.jguru.com/guru/viewbio.jsp?EID=4939
Prepared Statements aren't actually compiled, but they are bound by the JDBC
driver. Depending on the driver, Prepared Statements can be a lot faster - if you re-
use them. Some drivers bind the columns you request in the SQL statement. When
you execute Connection.prepareStatement(), all the columns bindings take place, so
the binding overhead does not occur each time you run the Prepared Statement. For
additional information on Prepared Statement performance and binding see JDBC
Performance Tips on IBM's website.
Does JDBC have support for Bulk copy utilities provided by RDBMS products.
Location: http://www.jguru.com/faq/view.jsp?EID=46395
Created: May 8, 2000 Modified: 2000-05-09 11:21:02.89
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Question originally posed by Lakshmy Ganapathy
(http://www.jguru.com/guru/viewbio.jsp?EID=11922
Most of the major databases have export, import and/or bulk load utility programs.
These are generally listed under administrative tools and utilities, and can be
accessed via program calls and APIs. These utilities are not only outside of JDBC, but
in some sense outside SQL, in the sense of meeting any standard. So the standards
based answer is no.
From the The JDBC 1.2 Specification: "JDBC allows any query string to be passed
through to an underlying DBMS driver." So, in theory, a JDBC driver could apply the
passed string to a bulk load utility. I'm not aware of any that do this and it would be
far from standard.
An alternative available with JDBC 2.0 compliant drivers is batch updates, which
"allows multiple update operations to be submitted to a database for processing at
once." ( JDBC 2.0 specification. )
But, the documentation for most databases have lists of SQLStates. Probably the
most complete ( and accessible ) online listings are in the DB2 manuals. Check the
DB2 Universal Messages manual, for instance. Oracle ( TechNet password required )
and Sybase, among others, also have online listings.
As to the second question, this is the intent of SQLState, however, the various
databases have varying degrees of compliance. For example, some map multiple
native error messages to the same SQLState. For generic use, one should probably
concentrate on the major code ( the first two characters of SQLState, ) then
determine if more specific info is available in the minor code ( beyond 000. )
Oracle basically has two JDBC drivers: an OCI driver which includes native code and
a Thin driver which is 100% Pure Java. Since the OCI driver includes native code, it
cannot be used in applets. You must use thin driver. You can get all Oracle JDBC
drivers from
http://technet.oracle.com/software/tech/java/sqlj_jdbc/software_index.htm.
As to the second part of the question, one needs special middleware to deal with
multiple databases in a single statement or to effectively treat them as one
database. DRDA ( Distributed Relational Database Architecture -- I, at least, make it
rhyme with "Gerta" ) is probably most commonly used to accomplish this.
Oracle has a product called Oracle Transparent Gateway for IBM DRDA and IBM has
a product called DataJoiner that make multiple databases appear as one to your
application. No doubt there are other products available. XOpen also has papers
available regarding DRDA.
However, the spec confirms that for JDBC Compliant(tm) drivers "We require that all
operations on all the java.sql objects be multi-thread safe and able to cope correctly
with having several threads simultaneously calling the same object." The spec goes
on to give an example with a connection. The bad news is that concurrency MAY be
achieved by serial behavior. For further information, see the JDBC Specification,
Chapter 9 - Asynchrony, Threading, and Transactions, section 9.2.
Yes, there are no special requirements to get SQLJ to work on top of any JDBC
driver. Specifically, SQLJ does not require a JDBC 2.x compliant driver.
A quick search as of late May, 2000 turns up 4 books, 3 of which are completely
devoted to SQLJ at fatbrain. A couple of these are also available at bookpool. IBM's
redbooks site also has 4 freely downloadable redbooks with sections on SQLJ.
Because new books come out often and existing books become outdated quickly, I
prefer to give easily searchable sites if possible ( all of these came up with a simple
"SQLJ" search at each site ) rather than specific titles -- unless someone knows a
classic.
What mailing lists, forums and other resources are available for information
about SQLJ?
Location: http://www.jguru.com/faq/view.jsp?EID=57330
Created: May 27, 2000 Modified: 2000-05-27 20:48:26.662
Author: Simon Brown (http://www.jguru.com/guru/viewbio.jsp?EID=44588)
Question originally posed by John Zukowski PREMIUM
(http://www.jguru.com/guru/viewbio.jsp?EID=7
The Oracle Technet site has some articles that may be of some use - including a FAQ
and technical documentation.
This list is not comprehensive ( more welcome ) but hits the documentation for the
major database engines.
Informix
Oracle
Sybase
One of the ISO-ANSI SQL defined "phenomena" that can occur with concurrent
transactions. If one transaction reads a row, then another transaction updates or
deletes the row and commits, the first transaction, on re-read, gets modified data or
no data. This is an inconsistency problem within a transaction and addressed by
isolation levels.
One of the ISO-ANSI SQL defined "phenomena" that can occur with concurrent
transactions. If one transaction selects a set of rows, then another transaction
inserts rows that meet the same criteria, when the first transaction re-executes the
query, a different set results. This is an inconsistency problem within a transaction
and addressed by isolation levels.
JDBC is based on ISO-ANSI SQL, which provides for database concurrency using
isolation levels. These are defined to deal with the "phonema" of dirty reads, non-
repeatable reads and phantom inserts. "The four isolation levels guarantee that each
SQL-transaction will be executed completely or not at all, and that no updates will be
lost." While almost all programs will be concerned with dirty reads, in the real world we
probably want to use and see the most current data, so non-repeatable reads and phantom
inserts may not be an issue. Here's a table that briefly summarizes what the defined
isolation levels guarantee:
Non-Repeatable
Isolation Level Dirty Read Phantom Insert
Read
Read Uncommitted Possible Possible Possible
Read Committed Not Possible Possible Possible
Repeatable Read Not Possible Not Possible Possible
Serializable Not Possible Not Possible NotPossible
Yes, although, as usual, technically we are passing object references. However, there
is a chain of dependency that must be kept in mind and should be tracked for
Connection, Statement and ResultSet.
For example, If a ResultSet is is not scrollable, rows already read are not available,
so passing the same ResultSet to different methods may not work as expected. If
the originating Statement is closed, the ResultSet is generally no longer viable.
If there are multiple Statements on a Connection, a commit will affect all of them.
Addtionally, as seen in Is Connection thread safe for Oracle drivers?, a Connection
may carry out its requirement to be threadsafe by executing Statements serially.
What is the best way to provide a unique identifier as a primary key that
will work in a database independent manner? I'm looking for functionality
similar to Oracle's proprietary MY_SEQ.NEXTVAL.
Location: http://www.jguru.com/faq/view.jsp?EID=59469
Created: May 29, 2000 Modified: 2000-05-29 11:44:17.799
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Question originally posed by Pankaj Tandon
(http://www.jguru.com/guru/viewbio.jsp?EID=50563
The "best way" probably lies in the eye of the beholder and/or the requirements of
the particular application. Here are some possibilities in no particular order:
1) For databases that support them, an insert trigger or stored procedure that uses a
proprietary means such as MY_SEQ.NEXTVAL OR that uses one of the following
methods.
2) Use a server socket whose job is to control and hand out new identifiers, either
with proprietary means or one of the following.
3) Use a singleton object whose job is to control and hand out identifiers. The
identifiers would typically be tracked in a table containing a row for each table in the
database which uses this mechanism. Each row would have the affected table name
as the key and a numeric column containing the next key. The singleton can get
identifiers one at a time or in groups ( at the potential price of skipping some
identifiers. )
4) Do the same as 3 in your own individual classes.
For 2), 3) and 4) either the supporting mechanism or your individual classes must be
prepared to handle identifier clashes, since there is no way to guarantee that all
database operations will use this mechanism in a production environment.
Other suggestions have included random numbers with checks for clashes and trying
to generate a totally unique number internally. The problem with the last is
complexity and the size of the generated key, which can impact performance.
import java.rmi.server.UID
Use a Java Bean to store the entire result of the search that you have found. The
servlet will then set a pointer to the first line to be displayed in the page and the
number of lines to display, and force a display of the page. The Action in the form
would point back to the servlet in the JSP page which would determine whether a
next or previous button has been pressed and reset the pointer to previous pointer +
number of lines and redisplay the page. The JSP page would have a scriplet to
display data from the Java Bean from the start pointer set to the maximum number
of lines with buttons to allow previous or next pages to be selected. These buttons
would be displayed based on the page number (i.e. if first then don't display previous
button).
There are many of methods to accomplish this. One way is to use the Pager Tag
Library, recently discussed at Implementing Page Scrolling on the servlet mailing list.
You may also want to look through the list Archives for other ideas.
Comments and alternative answers
The problem with the ResultSet object in the JDBC1.2.2...
Author: Alexandros Kotsiras (http://www.jguru.com/guru/viewbio.jsp?EID=64209),
Jun 3, 2000
The problem with the ResultSet object in the JDBC1.2.2 version is that it is not
scrollable. It is scrollable in the latest JDBC2.0 version which only the latest versions
of the RDBMS support. Note that you can still use a JDBC2.0 Type 4 driver (eg.
classes12.zip for Oracle) with an RDBMS that does not support JDBC2.0 features
(like Oracle 8.1.5) but you won't be able to use the new JDBC2.0 functionality. The
new features can only be used if the RDBMS supports them by itself like Oracle
8.1.6.
I found very useful the CachedRowSet API from Sun which is an extension to
java.sql. After you create your ResultSet object you wrap it arround a CachedRowSet
object which is disconnected and scrollable. It's like putting all you result records in a
Collection object but the CachedRowSet does this job for you plus it offers all the
methods that you need to scroll like : next(), previous(), relative(numberOfRows),
getRow(rowPosition), size() (to determine the number of records in your ResultSet)
etc.
Then you just need to put it in the users session, retrieve from the next page, scroll to
the appropriate position and display a range of records.
The above approach might not be the appropriate one if you have a very large
ResultSet since the CachedRowSet object that you will store in the session will take a
lot of memory. For ResultSets of some hundrends of records you should be fine. It
can be downloaded from the Sun/JDBC page at http://java.sun.com/products/jdbc/
The servlet then uses the count in its logic to determine the next set of records to
display.
This is NOT the same as re-executing the query and somehow restricting the number
of values returned to a page-full.
I actually want the resultset retained on the server side, since it seems this would be
MUCH more efficient for complex ad-hoc multi-table join queries on large tables
(which is what we do.)
this sounds like a good idea but how can i retrieve the total number of records
even after I set the rownum range?
eg. select rownum y, emp_name from emp where city='newyork' the total
number of employees.
I need to retrieve the total number so that I can determine the number of pages
needed to display all the records. (with PageCount=RecordSize/PageSize) where
PageSize is the rownum range.
Pls help..
See also
Author: Alex Chaffee (http://www.jguru.com/guru/viewbio.jsp?EID=3), Feb 13, 2002
How can I cache the results of my servlet, so the next request doesn't have to
go through all the calculation / database access / other time-consuming stuff
all over again?
Search Reasult
Author: Birendar Waldiya (http://www.jguru.com/guru/viewbio.jsp?EID=1131260),
Dec 1, 2003
One more way to acheive the result, in a page wise display of page r is by using
Scrollable ResultSet every time you want to get the next page shift the cursor to that
particular point in ResultSet.absolute(int) method.
How can I ensure that database security is applied to the current user when
I use a connection pool since the connections are created with a default
user ID and password?
Location: http://www.jguru.com/faq/view.jsp?EID=61453
Created: May 31, 2000 Modified: 2000-05-31 21:04:17.293
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Question originally posed by Daniel Weimer
(http://www.jguru.com/guru/viewbio.jsp?EID=25540
In general, you can't. Nearly all optimizations involve trade-offs and a large part of
the developer's job is to select those that make the most sense under a given set of
circumstamces. This is really a security question, which can easily evolve into a can
of worms. I'll start with a quote from JDBC Performance Tips that connection pooling
"may also be best suited to apps in which there is a certain class of users that can
share connections... This would not be well-suited to apps in which each user had to
have their own individual authority verified and used for the connection, since this
would conflict with the concept of saving away connections for use by any number of
users." While you may find some database engine that allows a temporary user, it
certainly isn't a common or standard feature.
Why do I get the exception: "ALTER TABLE only allows columns to be added
which can contain nulls. Column 'F' cannot be added to table..." with this
code?
When one adds a column to an existing table with an ALTER TABLE statement, the
database adds the column to every row and initializes the column to a value
depending on the values supplied in the ADD (COLUMN) clause. If a default value is
given, that value is applied; otherwise the column is set to null. SQL Server and
some other databases have a current default for assuming NULL/NOT NULL
constraints for new columns. If the current default is NOT NULL, but no default value
is given in the ADD (COLUMN) clause, this error occurs because the database would
otherwise set a null value in a NOT NULL column.
You are right about the JDBC-ODBC bridge. Since it does not support multi-threading
it is not of much use. But you can find 3rd-party drivers in the market that will allow
you to work with MS Access from EJBs.
For a list of those drivers search for MS Access drivers from the following page:
http://industry.java.sun.com/products/jdbc/drivers.
First, not all databases support row level locks, so check the documentation for your
DMBS. If you are using Oracle, you can issue a select...for update statement. Make
sure your JDBC connection has autocommit turned off- otherwise, you'll get an ORA-
01002- "Fetch out of sequence" error. Here's an example:
How can I pass data retrieved from a database by a servlet to a JSP page?
Location: http://www.jguru.com/faq/view.jsp?EID=73439
Created: Jun 12, 2000 Modified: 2000-08-14 11:16:49.756
Author: Govind Seshadri (http://www.jguru.com/guru/viewbio.jsp?EID=14) Question
originally posed by senthil kumar (http://www.jguru.com/guru/viewbio.jsp?
EID=57182
One of the better approaches for passing data retrieved from a servlet to a JSP is to
use the Model 2 architecture as shown below:
Basically, you need to first design a bean which can act as a wrapper for storing the
resultset returned by the database query within the servlet. Once the bean has been
instantiated and initialized by invoking its setter methods by the servlet, it can be
placed within the request object and forwarded to a display JSP page as follows:
The bean can then be accessed within the JSP page via the useBean tag as:
Also, it is best to design your application such that you avoid placing beans into the
session unless absolutely necessary. Placing large objects within the session imposes
a heavy burden on the performance of the servlet engine. Of course, there may be
additional design considerations to take care of - especially if your servlets are
running under a clustered or fault-tolerant architecture.
How can I read and write serialized objects to and from a database?
Location: http://www.jguru.com/faq/view.jsp?EID=74403
Created: Jun 13, 2000 Modified: 2000-06-13 12:12:18.258
Author: Simon Brown (http://www.jguru.com/guru/viewbio.jsp?EID=44588)
Question originally posed by edwin abiraham
(http://www.jguru.com/guru/viewbio.jsp?EID=41880
If your RDBMS supports them, you can store serialized objects as BLOBs.
These are JDBC 2.0 features, but take a look at java.sql.Blob, ResultSet and
PreparedStatement for more information.
Base64 Encoding
Author: Stephen Ostermiller (http://www.jguru.com/guru/viewbio.jsp?
EID=576685), Sep 24, 2002
Open source, GPL implementation from com.Ostermiller.util:
http://ostermiller.org/utils/Base64.html
It can encode and decode strings, byte arrays, files, and streams.
Open source, freeware (except military) from Roedy Green's Java Glossary:
http://mindprod.com/jglossbase64.html
http://mindprod.com/products.html#BASE64
Encodes from byte arrays to strings, decodes from strings to byte arrays.
JavaWorld tip with annotated code and nifty graphic that shows how Base64
encoding works (license unknown).
http://www.javaworld.com/javaworld/javatips/jw-javatip36-p2.html
Supports byte array to byte array operations.
JDBC 2.0, introduced with the 1.2 version of Java, added several capabilities to
JDBC. Instead of completely invalidating all the older JDBC 1.x drivers, when you try
to perform a 2.0 task with a 1.x driver, an UnsupportedOperationException will be
thrown. You need to update your driver if you wish to use the new capabilities.
Comments and alternative answers
Thanks!
Author: ax m (http://www.jguru.com/guru/viewbio.jsp?EID=944068), Jul 10, 2002
I guess I have the same problem, and your solution seems... cool :)
How do I set a default character encoding for file I/O operations, JDBC
requests and so on?
Location: http://www.jguru.com/faq/view.jsp?EID=78088
Created: Jun 16, 2000 Modified: 2001-08-18 17:31:58.349
Author: Sandip Chitale (http://www.jguru.com/guru/viewbio.jsp?EID=14537)
Question originally posed by Dmitry Popov
(http://www.jguru.com/guru/viewbio.jsp?EID=45003
The default encoding used by locale/encoding sensitive API in the Java libraries is
determined by the System property "file.encoding". This system property is
initialized by the JVM startup code after querying the underlying native operating
system. For example on my English USA NT box it is initialized to:
Cp1252
It is generally recommended that you do not modify it. However if you know what
you are doing you could override the system property either on the command line
using the -
java -Dfile.encoding=...
http://java.sun.com/products/jdk/1.2/docs/guide/internat/encoding.do
c.html
How can I store and retrieve Unicode or Double Byte data in a file using the java.io
libraries?
How can I store and retrieve Unicode or Double Byte data in a database
using JDBC?
Location: http://www.jguru.com/faq/view.jsp?EID=79756
Created: Jun 18, 2000 Modified: 2000-07-25 17:34:57.98
Author: Kalyanaraman Parthasarathy (http://www.jguru.com/guru/viewbio.jsp?
EID=61494) Question originally posed by Tian Hao
(http://www.jguru.com/guru/viewbio.jsp?EID=56209
The underlying DBMS must support Unicode or the desired encoding. Internally, Java
data are stored as Unicode only. So, if the Database supports Unicode and the table
was created that way, the data will be written to the encoding of the table. Nothing
needs to be done specifically, because the driver will handle the translation. See
Supported Encodings and your DBMS documentation for more on encodings, code
pages and so on.
The ability to choose the 'best' efficiency ( or evaluate tradeoffs, if you prefer, ) is, at
times, the most important piece of a mature developer's skillset. This is YAA ( Yet
Another Area, ) where that maxim applies. Apparently there is an effort to allow
prepared statements to work 'better' with connection pools in JDBC 3.0, but for now,
one loses most of the original benefit of prepared statements when the connection is
closed. A prepared statement obviously fits best when a statement differing only in
variable criteria is executed over and over without closing the statement.
However, depending on the DB engine, the SQL may be cached and reused even for
a different prepared statement and most of the work is done by the DB engine rather
than the driver. In addition, prepared statements deal with data conversions that can
be error prone in straight ahead, built on the fly SQL; handling quotes and dates in a
manner transparent to the developer, for example.
Portions of this answer are based on input from William Crawford and Craig R.
McClanahan.
I think the connection pool scenario is the more common of the two that you
mentioned. HTH
What is JDBC, anyhow?
Location: http://www.jguru.com/faq/view.jsp?EID=92327
Created: Jun 30, 2000 Modified: 2000-06-30 15:01:47.853
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Question originally posed by Joe Sam Shirah PREMIUM
(http://www.jguru.com/guru/viewbio.jsp?EID=42100
JDBC is Java's means of dynamically accessing tabular data, and primarily data in
relational databases, in a generic manner, normally using standard SQL statements.
While most developers think of it as Java Database Connectivity, actually JDBC is the
trademarked name and is not an acronym. JDBC is based on the X/Open SQL
Command Level Interface ( CLI ) and the API is composed of interfaces that allow
the same code to run against any data(base) that has a supporting JDBC driver.
JDBC drivers, of which there are four types, are loaded at runtime and provide the
implementation of the JDBC API interfaces.
If you are just beginning with JDBC, a good place to start is in the JDK
documentation, which includes the JDBC(tm) Technology Guide: Getting Started, the
specs and links to basic and advanced tutorials. For information regarding specific
databases, see "Where can I find online documentation for database xyz?" and for
general information, you are already in the right place.
These machines use CCSIDs ( Coded Character Set Identifiers ) for National
Language Support. While in general, data will be converted sensibly for Java, under
certain conditions data will be created, often inadvertently, with a CCSID of 65535.
This code means "binary data, do not convert." While the best answer is to get the
data to a proper CCSID, this is not always possible and a good JDBC driver for these
platforms will have a property like "convert binary" or "translate CCSID 65535 data."
Set this property and the garbage ( which is actually EBCDIC data being displayed on
an ASCII machine, ) becomes good data.
Could we get sample code for retrieving more than one parameter from a
stored procedure?
Location: http://www.jguru.com/faq/view.jsp?EID=93232
Created: Jul 1, 2000 Modified: 2000-07-02 08:06:01.675
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Question originally posed by Sakthivelu Sivaraman
(http://www.jguru.com/guru/viewbio.jsp?EID=70819
The code snippet to retrieve the OUT and INOUT parameters follows:
cs.execute();
int iParm2 = cs.getInt(2);
int iParm3 = cs.getInt(3);
cs.close();
The code really is just additive; be sure that for each IN parameter that setXXX() is
called and that for each INOUT and OUT parameter that registerOutParameter() is
called.
Comments and alternative answers
Erase parenthesis
Author: Amaury Quintero (http://www.jguru.com/guru/viewbio.jsp?EID=895098), Jul
31, 2002
Hello Your code with parenthesis before call has a problem, better erase parenthesis
that enclose CALL Best Regards
How can I find out the names of the ODBC data sources available through
the JDBC-ODBC driver?
Location: http://www.jguru.com/faq/view.jsp?EID=94778
Created: Jul 5, 2000 Modified: 2000-07-05 07:29:28.011
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7)
There is no Pure Java mechanism to get this information. If you don't mind locking
yourself into the Microsoft VM, the following program demonstrates:
import com.ms.wfc.app.*;
public class ODBCSource {
public static void main(String args[]) {
RegistryKey regKey =
Registry.CURRENT_USER.getSubKey
("Software\\ODBC\\ODBC.INI\\ODBC Data Sources");
if (regKey != null) {
String dsn[] = regKey.getValueNames();
for(int i = 0; i < dsn.length; i++) {
System.out.println(dsn[i]);
}
}
}
}
1 - Access is very limited as to the number of records it can manage. Once the
database gets to be near the size of 1 megabyte, Access is notorious for data
corruption.
2 - Access is not "thread safe" - only one connection to the database can be used at
a time.
4 - Access does not support complicated SQL joins and other features.
Comments and alternative answers
"Access targets the desktop category and works best for individuals and workgroups
managing megabytes of data. For multiuser access to the same database, Access uses
file-server architecture, rather than client-server architecture."
"Before Access 2000, users and developers were using the Jet data engine, whether
they knew it or not." BTW, this does not imply that people are not still using Jet if
they take the default installation.
If one goes to the MSDN Search Page and performs a boolean search with "Access
AND SQL", many articles appear. Here are some samples regarding compliance and
migration considerations that might make you think about using Access in a
production environment, particularly if you ever need to go to the real thing:
Most database engines support double byte character sets ( DBCS ) and this was the
primary method of supporting these languages in the past. While this is generally
still available, Unicode is probably a better answer now, along with some efficiency
gain in Java.
For SQL Server specifically, one can use the nchar, nvarchar and ntext types to
support Unicode. See Using Unicode Data for an overview. For more information,
see: Where can I find online documentation for database xyz?, along with Unicode
related questions in the FAQ.
regards,
Brian Snyder
Java Developer
SCJ2P
Cetova Corp.
W 201-938-0200 x355
This depends on your driver. If it supports JDBC 2.0, then the answer is yes,
although the functionality is in the driver. As you can see from Creating a
CallableStatement Object, there is no difference in the stored procedure itself.
Where do I find information about operations on Excel, Word, text files and
other non-DBMS products that can be accessed via the JDBC-ODBC Bridge?
Location: http://www.jguru.com/faq/view.jsp?EID=114331
Created: Jul 30, 2000 Modified: 2000-07-30 04:13:20.692
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Question originally posed by Joe Sam Shirah PREMIUM
(http://www.jguru.com/guru/viewbio.jsp?EID=42100
The best source is, the source, that is, Microsoft. See: Microsoft ODBC Desktop
Database Drivers, which includes considerations for non-DBMS operations.
You can also check The ODBC FAQ and here's a java example for Using MS-Excel and
JDBC.
Can I reuse a Statement or must I create a new one for each query?
Location: http://www.jguru.com/faq/view.jsp?EID=115621
Created: Jul 31, 2000 Modified: 2000-07-31 19:52:35.821
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Question originally posed by timo guenzel
(http://www.jguru.com/guru/viewbio.jsp?EID=115224
When using a JDBC compliant driver, you can use the same Statement for any
number of queries. However, some older drivers did not always "respect the spec."
Also note that a Statement SHOULD automatically close the current ResultSet before
executing a new query, so be sure you are done with it before re-querying using the
same Statement. For more information, see: Executing Statements Using Statement
Objects.
The driver's executeXXX() methods will always return a ResultSet object unless there
was some serious internal problem or error. Therefore the reference to the returned
ResultSet is never normally null. The ResultSet can be empty, that is, nothing met
the criteria, but the ResultSet object itself still is not null. Instead, the normal way of
checking if data was returned is to use the next() method, as if( rs.next() ) or while(
rs.next() ), which returns a boolean. For more information, see: ResultSet and the
API documentation for java.sql.ResultSet.
Are there any good books that will help me learn JDBC?
Location: http://www.jguru.com/faq/view.jsp?EID=120201
Created: Aug 5, 2000 Modified: 2000-08-05 22:20:42.292
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7)
If you already know SQL, the JDBC API Tutorial and Reference, Second Edition :
Universal Data Access for the Java 2 Platform book is probably the best of the bunch.
It covers the original JDBC 1.x capabilities like statements and resultsets as well as
the newer JDBC 2.0 capabilies like updatable cursors, BLOBS/CLOBS, as well as
rowsets.
If you don't know SQL (Structured Query Language), I like the SQL Database
Programming with Java book. While around 2 years old now, it will get you started
with database development with Java.
Comments and alternative answers
JDBC Tutorial
Author: Kevin 95112 (http://www.jguru.com/guru/viewbio.jsp?EID=847704), Apr 21,
2002
JDBC 3 is a good book for both veteran or newcomer
Applied to web applications and distributed programming, the three logical tiers
usually correspond to the physical separation between three types of devices or
hosts:
1. Browser or GUI Application
2. Web Server or Application Server
3. Database Server (often an RDBMS or Relational Database)
However, inside of the application server, there is a further division of program code
into three logical tiers. This is kind of fractal: the part (app server object design)
resembles the whole (physical system architecture). In a classic JSP/Servlet system,
these objects are usually implemented as:
1. JSPs or Servlets responsible for creating HTML or WML user interface
pages
2. Servlets or JavaBeans responsible for business logic
3. Servlets, JavaBeans, or Java classes responsible for data access.
These objects usually use JDBC to query the database.
In an EJB system, the three logical tiers are usually implemented somewhat
differently:
1. JSPs, Servlets, or Java client applications responsible for user
interface
2. Session Beans or Entity Beans whose methods implement business
logic and business rules
3. Entity Beans whose fields represent data; these fields are "persisted"
(stored and retrieved) either by the EJB server (for container-managed
persistence) or by the Entity Beans themselves (for bean-managed
persistence)
As you can see, the precise definition of "tiers" can vary widely depending on the
particular needs and choices of an application designer. However, they all maintain
the general division of client-logic-storage.
If the architecture contains more than three logical tiers -- for instance, multiple data
feeds, multiple transactional data sources, multiple client applications -- then it is
typically called an "N-tier" or "Distributed" architecture.
See also:
JDO and EJB are different and incompatible persistence models. While there may in
the future be an EJB server that uses JDO, no such thing currently exists, and IMHO
never should.
Comments and alternative answers
The Java InstantDB relational database management system has a command line
module called commsql for testing SQL, as well as a Swing based utility called
SQLBuilder. The classes are oriented towards InstantDB, but the source is included
to allow modification for accessing other databases.
Comments and alternative answers
Each of these tiers may be on separate physical machines or they may share the
same box.
The first answer is to stick with SQL standard types whenever possible; otherwise
you'll have costly migration headaches when moving to or working with other
databases.
If that's not possible, then the SQL/JDBC manuals for the specific database SHOULD
provide this information. See Where can I find online documentation for database
xyz? for links.
The JDK documentation, particularly for 1.3, also has mapping information and a
section on database specific type mapping. See: 8 Mapping SQL and Java Types ,
subsection 8.9.7 JDBC Types Mapped to Database-specific SQL Types.
SQL online resources are not nearly as plentiful as many other areas, but here is a
good basic tutorial: Introduction to Structured Query Language The page additionally
has a number of links to other resources.
Also, and I hope it is legal, Teach Yourself SQL in 21 Days, Second Edition is online.
And, of course, vendor manuals provide reference materials and some examples.
See Where can I find online documentation for database xyz?
For more detailed information, take a look at JDBC Performance Tips. While these
are aimed specifically at the AS/400, most of the tips are applicable to JDBC in
general.
The DB reference manuals covering JDBC for your own and other databases can also
provide valuable tips. See: Where can I find online documentation for database xyz?
How can I determine the value of a DBMS auto-generated key after record
insertion?
Location: http://www.jguru.com/faq/view.jsp?EID=131634
Created: Aug 21, 2000 Modified: 2000-08-21 16:32:18.391
Author: Hans Gerwitz (http://www.jguru.com/guru/viewbio.jsp?EID=100248)
Question originally posed by Hans Gerwitz
(http://www.jguru.com/guru/viewbio.jsp?EID=100248
I had to research this issue for both MySQL and MS SQL and was able to answer my
own question.
With JDBC 2.0 or greater, this can be accomplished using scroll-sensitive ResultSets.
See sections 5.8 and 5.9.
This is dependent on the JDBC driver and the database interface implementation and
is therefore vendor specific.
Joe Sam Shirah adds: In addition, not all databases support the SQL3 types, so you
should ensure that your database has this capability as well. However, at that point,
there should be little difference, keeping Nicholas' caveat in mind, between returning
an Array and any other type. Oracle supports the Array type and you might want to
look at their site for examples. See:
We are trying to access a large volume of data from a remote database, but
the time it takes to get the data from the database is more than the
maximum timeout for the web server, so the webpage is not getting
displayed. How can we solve this problem?
Location: http://www.jguru.com/faq/view.jsp?EID=132065
Created: Aug 22, 2000 Modified: 2000-08-25 20:14:51.715
Author: Nicholas Whitehead (http://www.jguru.com/guru/viewbio.jsp?EID=1260)
Question originally posed by Geetha Santhanam
(http://www.jguru.com/guru/viewbio.jsp?EID=63150
JDBC is not usually the root cause of the delay, so I'll make the obvious suggestions
first:
Extend the maximum timeout for the web page.
Optimize the query to return the data faster.
Reduce the amount of data you return.
Increase the bandwidth to the database.
Tune the transport protocol to carry more data per packet.
Last and most importantly for remote access across a slow line:
denormalize the query. One query returning many rows will have a far
faster throughput than many queries returning a small number of
rows. Differently put, the submission and processing of a query itself
can easily longer than the actual retrieval of the rows.
jGuru received several answers to this question on the JDBC side, most of which
emphasized narrowing the query to take less time. This is excellent advice, but not
always possible. Additionally, other tasks may bring up the same issues with
servlets. During January, 2000, there was an exchange of messages on Sun's servlet
mailing list which discussed the issue and provided a more general answer.
Essentially, the advice is to start a new thread in the servlet to do the work and
then, using refresh in the header, repeatedly send a status message until the long
running task is done.
See the series Timing out of response data. Interestingly, probably the one that
outlines the process best is http://archives.java.sun.com/cgi-bin/wa?
A2=ind0001&L=servlet-interest&D=0&P=80267 by one Nicholas Whitehead.
Swarraj "sk or raj" Kulkarni and Kesav Kumar Kolla also contributed to this answer.
Where can I find the API documentation for Java Database Connectivity
(JDBC)?
Location: http://www.jguru.com/faq/view.jsp?EID=134142
Created: Aug 24, 2000 Modified: 2000-08-25 22:31:33.435
Author: John Mitchell (http://www.jguru.com/guru/viewbio.jsp?EID=4)
You can find the core JDBC API documentation from Sun's J2SE API documentation
page. See the sections javax.sql, javax.transaction and javax.transaction.xa from
Sun's J2EE API documentation page for the JDBC extension API documentation.
Membership is free.
Where can I find code examples specific to the JDBC-ODBC bridge and
Access?
Location: http://www.jguru.com/faq/view.jsp?EID=217794
Created: Sep 28, 2000 Modified: 2000-09-28 08:02:53.807
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Question originally posed by Joe Sam Shirah PREMIUM
(http://www.jguru.com/guru/viewbio.jsp?EID=42100
Starting with what should be the source: JDBC Data Source Applet.
and
Why do I get "Driver Not Capable" errors and what does it mean?
Location: http://www.jguru.com/faq/view.jsp?EID=217917
Created: Sep 28, 2000 Modified: 2000-09-29 22:35:01.397
Author: swarraj kulkarni (http://www.jguru.com/guru/viewbio.jsp?EID=121306)
Question originally posed by Joe Sam Shirah PREMIUM
(http://www.jguru.com/guru/viewbio.jsp?EID=42100
This error indicates that: the operation is valid but not supported by either the
driver or the data source.
For example, if the user is trying to use the callable statement to call a stored
procedure but the database does not support stored procedures, then the operation
will fail and give this error.
To provide robust code, you should always work with the DatabaseMetaData to
find out whether the operation you are trying to perform with your database specific
classes is supported by the underlying database and have alternative mechanisms in
place to carry out the desired operation.
If you know that the database supports the operation and you get this error, then
change to a more robust JDBC driver.
The native driver and a version of the Toolbox for Java, which includes the type 4
driver, comes with OS/400. One can also purchase or get an evaluation copy of the
latest "official" version of the Toolbox. However, the open source version, JTOpen, is
generally more up to date and is free.
You can find both versions from the Java Home Page. For third party drivers, check
Where can I find a comprehensive list of JDBC drivers, including the databases they
support?
The base answer is that you should be using executeUpdate() for these operations.
The JDBC spec specifically "allows any query string to be passed through to an
underlying DBMS driver" and this is probably why a number of databases will actually
perform the requested operation. However, no ResultSet is returned. executeQuery()
expects a ResultSet, and so reports the error when none is returned.
Comments and alternative answers
Not true
Author: sri karthi (http://www.jguru.com/guru/viewbio.jsp?EID=948693), Jul 14,
2002
I am facing the same issue. I am getting the Invalid Cursor State even with a select
comment... My processing involves a query with 2 subqueries... I guess jdbc:odbc
connection cannot handle complex queries... or some other setup is required in SQL
server to handle queries...
Some initial considerations are sufficient memory to hold the data and possible
periodic refreshes. For the actual implementation you can use arrays, vectors or a
Collection, but the most blessed way at the moment is to implement or use a third
party implementation of Rowset. Javasoft has an Early Access JDBC(tm) Rowset
implementation at the Java Developer Connection. Note that you must be a member
to download the classes.
You may want to first review JDBC(tm) Technology Guide: Getting Started, Section
8: Mapping SQL and Java Types. You'll see that the JDBC ( java.sql ) Array is
consistently mapped to an array. Unfortunately, capitalization not particularly
enforced there.
ps.setObject( 1, as );
ORDINAL_POSITION"
I'm not aware of an alternative at this time. Obviously it is critical to read the driver
documentation for (un)supported features.
Connection.setAutoCommit(false);
Connection.Commit();
Joe Sam Shirah comments: This question could be taken a couple of ways, so we
included this answer as well:
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.
I've heard that the Sun JDBC-ODBC bridge driver is buggy. Are there any
commercial alternatives?
Location: http://www.jguru.com/faq/view.jsp?EID=229690
Created: Oct 16, 2000 Modified: 2000-10-17 09:22:02.726
Author: Alex Chaffee (http://www.jguru.com/guru/viewbio.jsp?EID=3)
I've heard that the Sun JDBC-ODBC bridge driver is buggy. Are there any
commercial alternatives?
Author: John Peters (http://www.jguru.com/guru/viewbio.jsp?EID=535674), Nov 1,
2001
We use the Easysoft JDBC-ODBC Bridge. Works fine.
www.easysoft.com
You can get scrollable ResultSets by using the JDBC 2.0 API. You must have a driver
that supports JDBC 2.0. The following code will give a Statement the capability to
create scrollable ResultSets:
Now use the Statement object to execute the query: For example:-
Yes. There is no reason that a ResultSet can't be used as a method parameter just
like any other object reference. You must ensure that access to the ResultSet is
synchronized. This should not be a problem is the ResultSet is a method variable
passed as a method parameter - the ResultSet will have method scope and multi-
thread access would not be an issue.
Aa an example, say you have several methods that obtain a ResultSet from the same
table(s) and same columns, but use different queries. If you want these ResultSets
to be processed the same way, you would have another method for that. This could
look something like:
Since the ResultSet always has method scope - sychronization is never an issue.
Joe Sam Shirah comments: Ryan's answer is exactly correct in the given context.
However, there are other possible areas and concerns as seen by these addtional
responses.
swarraj kulkarni notes that: ResultSet does not implement the Serializable
interface , so it can not be transferred across the network (for example in RMI
calls.)
1. There is only one ResultSet. Dont assume that the ResultSet is at the
start (or in any good state...) just because you received it as a
parameter. Previous operations involving the ResultSet will have had
the side-effect of changing its state.
2. You will need to be careful about the order in which you close the
ResultSet and CallableStatement/PreparedStatement/etc.
From my own experience using the Oracle JDBC drivers and CallableStatements the
following statements are true:
If you close the CallableStatement the ResultSet retrieved from that
CallableStatement immediately goes out-of-scope.
If you close the ResultSet without reading it fully, you must close the
CallableStatement or risk leaking a cursor on the database server.
If you close the CallableStatement without reading it's associated
ResultSet fully, you risk leaking a cursor on the database server.
No doubt, these observations are valid only for Oracle drivers. Perhaps only for some
versions of Oracle drivers.
John Zukowski adds: You have to be sure not to close the connection the result set
was acquired from or else the result set will become invalid. You should probably use
a CachedRowSet if the connection can/should close.
The JDBC 3.0 API is scheduled to be available with the JDK 1.4 release.
While Timesteamp extends Date, it stores the fractional part of the time within itself
instead of within the Date superclass. If you need the partial seconds, you have to
add them back in.
What is SQL?
Location: http://www.jguru.com/faq/view.jsp?EID=270926
Created: Dec 6, 2000 Modified: 2000-12-09 12:35:49.556
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7)
You can either spell it out S-Q-L or pronouce it like See - QueL (equal, but beginning
with an S).
IBM was the pioneer in this area and their first go was called Structured English
Query Language and pronounced "Sequel". The later version, which led to today's
SQL standard, was trimmed to Structured Query Language and technically
pronounced Ess-Que- Ell; that is, pronounce the letters individually.
In primarily the PC world, it became the vogue to pronounce it "sequel" and those in
the know often received snickers for saying Ess-Que-Ell. In today's world, either
pronounciation should be correctly understood as a "you say tom-A-to and I say
tom-AH-toe" thing. For some products, when in Rome..., so MS' and Sybase's SQL
Server products are always pronounced "sequel server".
How can I connect to an Oracle database not on the web server from an
untrusted applet?
Location: http://www.jguru.com/faq/view.jsp?EID=271882
Created: Dec 7, 2000 Modified: 2000-12-09 09:48:12.064
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7)
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.
"Java programmers do not need to distinguish among the three types of JDBC
strings, CHAR, VARCHAR, and LONGVARCHAR. Each can be expressed as a Java
String, and it is possible to read and write an SQL statement correctly without
knowing the exact data type that was expected."
If you, for some reason, feel better directly specifying the type, you should be able
to use this method, submitted by Gabriel Artaud:
Given a set of bytes, see How do I upload SQL3 BLOB & CLOB data to a database?
for how to insert it into a database that supports BLOBs.
To upload file data from a browser to a servlet, see: How do I upload a file to my
servlet?.
Jorge Jordão, Eduardo Estefano, and Trapix Smith also contributed to this answer.
conn.setAutoCommit(false);
String prepare = "insert into news_xml values(" + id + ", empty_blob())";
String cmd = "SELECT * FROM news_xml where id=" + id + " for update";
Statement stmt = conn.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
stmt.executeUpdate(prepare);
ResultSet rset = stmt.executeQuery(cmd);
rset.next();
BLOB blob = (BLOB)((OracleResultSet)rset).getBlob(2);
FileInputStream instream = new FileInputStream(f);
OutputStream outstream = blob.getBinaryOutputStream();
int size = blob.getBufferSize();
byte[] buffer = new byte[size];
int length = -1;
while ((length = instream.read(buffer)) != -1) outstream.write(buffer, 0, length);
instream.close();
outstream.close();
conn.commit();
How do I send e-mail through Oracle triggers?
Location: http://www.jguru.com/faq/view.jsp?EID=276261
Created: Dec 12, 2000 Modified: 2000-12-13 00:32:53.091
Author: Mark Bradley (http://www.jguru.com/guru/viewbio.jsp?EID=276260)
Question originally posed by Rajagopalan Varadarajan
(http://www.jguru.com/guru/viewbio.jsp?EID=273011
A good set of responses I've seen is from the Oracle Magazine. From there select the
"Ask Tom" column. You can search his articles for "JavaMail" or just "mail". It has
responses for Oracle 8i and previous releases. Versions prior to 8.1.5 rely on Oracle
packages instead of Java.
The questions and answers on that page are, naturally, heavily Oracle-specific!
It describes a way to load the activation.jar and mail.jar files (which cannot be
compressed) into the database using the "loadjava" program.
There is Java and PL/SQL sample code which supports attachments using BLOBs. It
has the repackaged JAR files.
You will need to modify the code to handle your specific needs. Load this code, then
just call the PL/SQL function from the trigger.
Yes, you can use the driver directly. Create an instance of the driver and use the
connect method from the Driver interface. Note that there may actually be two
instances created, due to the expected standard behavior of drivers when the class is
loaded.
The data is already in Unicode when it arrives in your program. Conversion from and
to the encoding/charset/CCSID in the database from/to Unicode in the program is
part of the JDBC driver's job.
If, for some reason, you want to see the data in '\uHHHH' format ( where 'H' is the
hex value ), the following code, while not very efficient, should give you some ideas:
public class UniFormat
{
} // end main
Are there any JDBC drivers available that support using SSL to communicate
between the Java program and the database server?
Location: http://www.jguru.com/faq/view.jsp?EID=289193
Created: Dec 29, 2000 Modified: 2000-12-29 20:14:34.385
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7) Question
originally posed by John Zukowski PREMIUM
(http://www.jguru.com/guru/viewbio.jsp?EID=7
For Oracle, the JDBC-OCI driver can use SSL with native threads, but not with green
threads. The JDBC-Thin driver cannot use SSL, but can use ANO encryption instead.
The the Novell JDBC Driver for NDS driver uses SSL by default, and must be disabled
to not use.
WebLogic / Tengah supports SSL when your protocol begins with t3s
(jdbc:weblogic:t3s I guess, or just create the T3Client with a t3s URL).
Cloudscape supports SSL through a special extended URL with the RmiJdbc driver.
(jdbc:cloudscape:weblogic-ssl:)
The HiT driver supports SSL communications with JDBC and DB2.
This list is not meant to be exhaustive. Feel free to add feedback if you know of any
others.
The AS/400 Toolbox for Java will also support SSL Connections, although there must
be a specific match between Toolbox and OS/400 versions. In addition, the
Connection must be made in a way specific to the Toolbox driver.
see http://www.starquest.com
On the client side, SSL is set up by using the appropriate port (default 448 rather than
446) and including an extra .jar file in the Classpath.
The Users Guide contains info on setting up the AS/400 for SSL :
StarSQL for Java User's Guide 79
To configure an iSeries host system to use the Secure Sockets Layer (SSL) protocol
you must have the following components:
Following are general procedures for configuring SSL on the iSeries host. Refer to
your IBM documentation for details, especially the AS/400 documentation and the
IBM iSeries Wired Network Security OS/400 V5R1 DCM and Cryptography
Enhancements Redbook.
1. Start the Admin HTTP instance and use a browser to configure the
Digital Certificate Manager.
a. Create a local Certificate Authority or obtain a certificate from
a public Internet Certificate Authority.
b. Create a *SYSTEM certificate store.
c. Use Manage Applications to assign a server certificate to the
OS/400 DDM/DRDA server.
d. After you assign the certificate, restart the DDM/DRDA server:
ENDTCPSVR *DDM
STRTCPSVR *DDM
2. If necessary, set the port on which the DDM/DRDA server listens for SSL
conversations. The default port for SSL is 448.
import java.sql.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.text.*;
import java.util.*;
public JDFDP()
{
super( "JDFDP" );
addWindowListener( this );
jb.addActionListener( this );
jp.add(jlI);
jp.add(jtI);
jp.add(jb);
jp.add(jlD);
jp.add(jtD);
jp.add(jlP);
jp.add(jtP);
show();
} // end constructor
// ActionListener Implementation
public void actionPerformed(ActionEvent e)
{
jtD.setText( "" );
jtP.setText( "" );
try
{
java.util.Date d = dfLocal.parse(
jtI.getText() );
jtI.setText( dfLocal.format( d ) );
jtD.setText( dfGermany.format( d ) );
d = dfGermany.parse( jtD.getText() );
// get new java.sql.Date
jsqlDate = new java.sql.Date( d.getTime() );
jtP.setText( jsqlDate.toString() );
}
catch( ParseException pe ) { jtI.setText( "" ); }
} // End actionPerformed
A search for "TDS" AND "JDBC" at altavista brought up a number of sites dealing
with the Tabular DataStream protocol. Probably most other search engines would do
the same. Obviously the Microsoft/Sybase sites make sense and you would probably
be interested in the FreeTDS site.
1) A database table.
For example, the AS/400 supports transactions via a process called journaling.
Journals must be specifically created and operational or SQL Collections, rather than
standard libraries, must be created for automatic journals.
To check whether transactions are valid, use
DatabaseMetaData.supportsTransactions().
autocommit
Author: Charles Xavier (http://www.jguru.com/guru/viewbio.jsp?EID=384410), Mar
28, 2001
If the autocommit status has been set to false, then shouldn't there be an explicit call
to commit the transaction using the commit method of the Connection object ?
Re: autocommit
Author: N Jain (http://www.jguru.com/guru/viewbio.jsp?EID=795169), Mar 13,
2002
See if there is a journal on the file that you are trying to update.
Re: autocommit
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100),
Mar 23, 2002
Of course, but the focus of the question was transactional support. If that is not
there, commit won't work.
JDBC is a relatively low level means of accessing tabular data. This was actually one
of the goals of the specification and there was an explicit expectation that alternate
tools could and would be built on top of the API. Java Blend is Sun's commercial
offering in this area. It claims to achieve transparent persistence across multiple
databases, to provide object-relational mapping that overcomes the "impedance
mismatch", and to eliminate the need for SQL and even JDBC programming, among
other things.
Please note that jGuru makes no judgements or recommendations about this or any
other product. For more information, see the Java Blend Overview and the Java
Blend Homepage.
GregorianCalendar cal =
new GregorianCalendar( YYYY, MM - 1, DD, HH, MM, SS );
OR
Note that valueOf() is a static method and that nanoseconds should still be set
separately.
A simpler approach
Author: Peter Heinrich (http://www.jguru.com/guru/viewbio.jsp?EID=389575), May
11, 2001
DateFormat df = new SimpleDateFormat( "MM/dd/yyyy" );
Timestamp ts = new Timestamp( df.parse( text ).getTime() );
Of course, you can change the format string used to initialize df as appropriate... peter
Remember that RowSets are extensions of ResultSets and were not designed as
mini-databases. Probably the easiest way to handle new orders is to use the
toCollection method, create an ordered Collection and work off the data from there.
The other way would be to read the data ( possibly again into a Collection ) sort it
and then create a new RowSet using the insertRow method or with your own Reader.
Re: CachedRowSet usability and accessibility from you Client and server
Author: Detlev Valentini (http://www.jguru.com/guru/viewbio.jsp?EID=540113),
Nov 6, 2001
The implementations of RowSet are still in Early Access Phase.
If you want to download it, you have to register at developers.java.sun.com.
You can get download (and register) by using this
address:http://developer.java.sun.com/developer/earlyAccess/crs.
They also provide you with some examples.
Why do I get "Unknown SQL Type" when I try to store an object with the
JAVA_OBJECT type?
Location: http://www.jguru.com/faq/view.jsp?EID=317278
Created: Jan 31, 2001 Modified: 2001-01-31 09:45:08.064
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
While the JDBC spec supports the JAVA_OBJECT type and has had getObject() and
setObject() for quite a while, the underlying DBMS engine must also specifically
understand and support Java objects ( not many do at this point ) or you will get this
type of exception.
Are there any Java classes available that provide SQL builder/SQL by
example functionality?
Location: http://www.jguru.com/faq/view.jsp?EID=317300
Created: Jan 31, 2001 Modified: 2001-01-31 10:23:18.737
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Question originally posed by Yongfeng Xiao
(http://www.jguru.com/guru/viewbio.jsp?EID=216776
Unfortunately, no. There are lots of databases and drivers out there with varying
levels of support. It's worth taking note of all the getXXX and supportsXXX methods
in the DatabaseMetaData class for those who want to provide and check everything.
However, a JDBC Compliant ( and that is a specific, meaningful term ) driver will
always support ANSI SQL-92 Entry Level. For more information, see the SQL
Conformance section in my JDBC 2.0 Fundamentals Short Course at the Java
Developer Connection.
In JDBC(tm) Technology Guide: Getting Started, Section 8: Mapping SQL and Java
Types, the table in 8.9.7, JDBC Types Mapped to Database-specific SQL Types,
shows that an Oracle VARRAY maps to a java.sql.Array, which should resolve your
issue.
How can I format, display, parse and update a java.sql.Date? Code examples
would be helpful.
Location: http://www.jguru.com/faq/view.jsp?EID=338014
Created: Feb 24, 2001 Modified: 2001-02-24 22:11:45.47
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Question originally posed by Steve Pence (http://www.jguru.com/guru/viewbio.jsp?
EID=250050
How do I display and parse a date? gives code to display and retrieve Date
information.
If the date value you need is not immediately available as a long, the Calendar, and
specifically the GregorianCalendar, class can be used. For examples and information,
see How can I get yesterday's date? and How can I generate a java.sql.Timestamp
from text fields formatted as MM/DD/YYYY and/or HH:MM:SS ( Month/Day/Year -
Hours/Minutes/Seconds )?
Thanks to
Arif Amjad
Jorge Jordão
CJ Jouhal
Dawei Jiang
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().
getDriverMajorVersion()
getDriverMinorVersion()
getDriverName()
getDriverVersion()
The requirements for a JDBC Compliant driver are spelled out at JDBC Data Access
API For Driver Writers in section A1. The additional sections A2 through A5 should be
thoroughly reviewed as allowed variants and suggested implementations are
discussed there. Note that some specifics are mentioned in the API descriptions as "A
JDBC Compliant driver will return..."
How can I determine whether a Statement and its ResultSet will be closed
on a commit or rollback?
Location: http://www.jguru.com/faq/view.jsp?EID=391306
Created: Mar 30, 2001
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Where can I find information about SQL-92 that a JDBC Compliant driver
must support?
Location: http://www.jguru.com/faq/view.jsp?EID=391318
Created: Mar 30, 2001
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
A JDBC Compliant driver must support SQL-92 at the entry level, A good resource for
these, as well as the Intermediate and Full levels, is FIPS PUB 127-2: The Standard
for Database Language SQL.
Where can I find information about the ODBC-defined SQL grammar that a
JDBC Compliant driver must support?
Location: http://www.jguru.com/faq/view.jsp?EID=391319
Created: Mar 30, 2001
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
A JDBC Compliant driver must support the ODBC Minimum SQL grammar. Some
resources for the grammar levels are CodeBase SQL/ODBC Conformance and
AcuODBC SQL Conformance. Also see What considerations apply if I want to write
portable SQL statements that work on many different databases? Is it enough to
follow the SQL-92 standard? for more information.
What is the best strategy to determine that the DBMS is up and that the
Connections from my pool are still viable before handing them out?
Location: http://www.jguru.com/faq/view.jsp?EID=391331
Created: Mar 30, 2001 Modified: 2002-03-23 22:34:15.73
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Question originally posed by Rakesh Sahu
(http://www.jguru.com/guru/viewbio.jsp?EID=127108
With these in mind, my own conclusions are that the application should handle any
problems with invalid Connections using a standard exception handler for this case
and that connection pools should have a returnInvalidConnection method to insure
that the bad Connection is not checked out again.
For those that still want to validate a Connection from within the pool, I did some
testing. One often sees Connection.getMetaData() used for validation. However,
some production quality drivers report zero time spent in this method, even over a
56K modem. This implies to me that those drivers just check for a
DatabaseMetaData object existence and return; clearly there is not a trip to the
DBMS server and back in zero time. I also considered just issuing a
Connection.commit(), but I suspect that there are drivers smart enough to know
when no transactions are pending and therefore just swallow the call for efficiency.
In the end, I have concluded that, for certainty across drivers, a query probably
must be issued. One possibility would be to create a table with no rows at pool
initialization time and perform a SELECT COUNT(*) on it for validation. COUNT() is
generally optimized for SELECTs without search criteria. jGuru would be happy to
receive feedback from anyone who has tested timings on other methods
guaranteed to force a response from the DBMS engine.
swarraj kulkarni, Modha Kumar, Harikrishna Neerkaje and Ari Manninen also
contributed to this answer.
"Note that the method Connection.isClosed is guaranteed to return true only when it
is called after the method Connection.close has been called. As a result, a
programmer cannot depend on this method to indicate whether a connection is valid
or not. Instead, a typical JDBC client can determine that a connection is invalid by
catching the exception that is thrown when a JDBC operation is attempted."
Validating a connection
Author: Sean Batten (http://www.jguru.com/guru/viewbio.jsp?EID=395165), Apr 4,
2001
Another way to validate a connection is to call Connection.getMetaData(). If the
connection has been closed, for whatever reason, you'll get a SQLException. This
approach saves you from having to issue a SQL request (such as SELECT COUNT(*)
from sometable) which is not generic.
Often the answer is given that the correct driver is not loaded. This may be the case,
but more typically, the JDBC database URL passed is not properly constructed. When
a Connection request is issued, the DriverManager asks each loaded driver if it
understands the URL sent. If no driver responds that it understands the URL, then
the "No Suitable Driver" message is returned.
Comments and alternative answers
Custom ClassLoaders
Author: Douglas Seifert (http://www.jguru.com/guru/viewbio.jsp?EID=460284), Jul
23, 2001
I have also seen this error when I load the driver class using a ClassLoader that is not
the same as the ClassLoader that loads the class where
DriverManager.getConnection() is called. I'm not sure if this is an error or a security
feature, however.
While this can be extra, duplicated work, it's much better than failing.
Note that, for a default ResultSet, the Statement is not complete until all rows have
been retrieved. However, this can be affected by the state of autocommit and the
capabilities of the driver. See: How can I determine whether a Statement and its
ResultSet will be closed on a commit or rollback?
The general answer to this is yes. If that were not true, connection pools, for
example, would not be possible. As always, however, this is completely dependent
on the JDBC driver.
You can find out the theoretical maximum number of active Connections that your
driver can obtain via the DatabaseMetaData.getMaxConnections method. Although
there is some ambiguity in the API documentation, the JDBC API Tutorial and
Reference, 2nd Ed: Java 2 clarifies with "that can be made through this driver
instance."
How can I get a DBMS to connect to and use data on... How can I get a
DBMS to connect to and use data on a CD?
Location: http://www.jguru.com/faq/view.jsp?EID=409336
Created: Apr 25, 2001
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Question originally posed by nidhi shanker
(http://www.jguru.com/guru/viewbio.jsp?EID=339706
In general you would need to use a DB engine that allows a connection to a database
by drive and directory, like InstantDB or Cloudscape, which would also be small
enough to run from the CD. Apparently this can also be done with Access, although
in that case you would need a DSN and deal with the non-production quality JDBC-
ODBC bridge.
Other DB engines often have an ATTACH command, but they usually expect to
connect via another DB engine or middleware. While this would seem to be an ideal
browser/applet combination, note that 1) without the plug-in you are limited to
partial 1.1 support and 2) you must deal with the sandbox security model even for
read-only data.
The primary rule to keep in mind is that the DB engine must be able to determine
the data type of the parameter. In addition, databases may have differing rules for
specific situations. Here's what DB2 ( see subsection Rules > Parameter Markers )
and Cloudscape have to say. For other databases, see Where can I find online
documentation for database xyz?
Comments and alternative answers
prepared statements
Author: Shirley C (http://www.jguru.com/guru/viewbio.jsp?EID=1243424), May 10,
2005
Can a parameter marker be used in an order by?
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.
Note that this can be quite expensive if the fetch size is high, causing multiple rows
to be returned ( see What does setFetchSize() really do? ) and obviously causes a
trip back to the server in any case. This will only work for a scrollable ResultSet
requested with ResultSet.TYPE_SCROLL_SENSITIVE; the method call is ignored for
other types. For more information, see 3.3.7 Getting the Most Recent Data in the
Advanced Tutorial at the JDC.
How can I tell if the data I get from a default ResultSet reflects changes
since the time the query was executed but not yet retrieved?
Location: http://www.jguru.com/faq/view.jsp?EID=411927
Created: Apr 28, 2001
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
You can't, with complete confidence. That's because some ResultSets ( those that
need to be sorted, for example ) require the creation of temporary tables using a
data snapshot. However, those that can effectively read along an index can be
checked for what is termed "incremental materialization" by using the
DatabaseMetaData methods othersDeletesAreVisible(int type),
othersInsertsAreVisible(int type) and othersUpdatesAreVisible(int type). The "type"
parameter is one of ResultSet.TYPE_FORWARD_ONLY ( for a default ResultSet ),
ResultSet.TYPE_SCROLL_SENSITIVE or ResultSet.TYPE_SCROLL_SENSITIVE.
Keep the initial caveat in mind: The methods will still return true ( if the DB engine is
capable ) even when a sorted ResultSet is returned.
Aside from driver bugs, some queries cannot be updatable due to identification,
integrity or DB limitation issues. For that reason, ResultSet.getConcurrency()
generally should be invoked to determine if an updatable ResultSet was returned.
For more information and a list of guidelines that should return an updatable
ResultSet, see 5.1.17 Queries That Produce Updatable Result Sets.
What scalar functions can I expect to be supported by JDBC?
Location: http://www.jguru.com/faq/view.jsp?EID=412811
Created: Apr 30, 2001
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
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.
See Escape Syntax and Scalar Functions in the JDBCTM 2.0 Fundamentals short
course.
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:
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.
Comments and alternative answers
java.sql.Time
Author: Prasanna Tuladhar (http://www.jguru.com/guru/viewbio.jsp?EID=875912),
May 13, 2002
To create a java.sql.Time simply use this
java.sql.Time tm = new java.sql.Time(System.currentTimeMillis());
//ly to get date java.sql.Date dt = new java.sql.Date(System.currentTimeMillis());
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:
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,
Normalization
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100), Mar
23, 2002
The point of the "so complicated" code is to properly create a normalized Date that
works correctly in all circumstances. java.util.Date, which underlies java.sql.Date, has
some major flaws. If one creates a java.sql.Date by just grabbing milliseconds, as
most of the suggestions do, one will have serious problems with date comparisons and
arithmetic.
Re: Normalization
Author: Yishai Hornbacher (http://www.jguru.com/guru/viewbio.jsp?
EID=1008981), Oct 7, 2002
Good point, but the suggestions create an unnecessary Calendar object, which
may or may not be an issue, depending on how often you do this for a given JDBC
call.
Re[2]: Normalization
Author: Yishai Hornbacher (http://www.jguru.com/guru/viewbio.jsp?
EID=1008981), Oct 7, 2002
Actually, the above does not account for time zones. That is just a warning, but
having the Calendar take care of it for you can be useful.
Re[3]: Normalization
Author: David Thirakul (http://www.jguru.com/guru/viewbio.jsp?
EID=1205929), Oct 18, 2004
Indeed, it doesn't consider time zones or locale values. Use Calendar
especially if you need to manipulate your date.
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.
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
):
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.
Comments and alternative answers
I've retrieved a Time value from a table and compared it to the current
Time. Why don't the java.sql.Time methods before() and after() work
properly?
Location: http://www.jguru.com/faq/view.jsp?EID=422114
Created: May 15, 2001 Modified: 2001-07-26 12:02:44.899
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
There is one root cause to this problem, although it may come from two different
directions. In order for Time comparisons to work properly, the Time objects must be
normalized ( see How do I create a java.sql.Time object? ).
If the application doesn't normalize its Time object OR if the JDBC driver does not
normalize returned Time objects ( this is a bug, but I know of one otherwise
production quality driver that does not do this ), before() and after() will show
seemingly erroneous results.
The best resource is the source, even though Oracle has an annoying habit of giving
examples using proprietary methods, which hinders portability. See: Oracle8i
Application Developer's Guide - Large Objects (LOBs), especially section 6 Frequently
Asked Questions, as well as the Oracle8i JDBC Developer's Guide and Reference.
Note that Oracle Technical Network registration is required to access these
documents.
Does catching an SQLException mean that the transaction was definitely not
completed and/or that the invoked method did not execute?
Location: http://www.jguru.com/faq/view.jsp?EID=431032
Created: May 30, 2001
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Not necessarily, and, unfortunately, there is no generic means of determining current
state. As noted in JDBC API Tutorial and Reference, 2nd Ed: Java 2, "The safest
course is to call the method rollback when there is any doubt and then to start
again."
There are often multiple reasons for a JDBC problem. SQLException has a method,
getNextException, which returns either the next exception or null when all exceptions
have been retrieved. Obtaining multiple exceptions this way is termed "chaining".
You can see a minimal form of this at How to raise a custom SQLWarning?.
For more information and a complete code example, see the SQL Exceptions section
in my JDBC 2.0 Fundamentals Short Course at the Java Developer Connection.
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.
i have also got same type of error.but when i checked the code i have
closed the connection & was trying to call createStatement() method
Connection con;
Statement st;
con.close();
st=con.createStatement();
Where can I learn (more) about Java running on IBM's AS/400 series
computers?
Location: http://www.jguru.com/faq/view.jsp?EID=431194
Created: May 30, 2001
Author: John Mitchell (http://www.jguru.com/guru/viewbio.jsp?EID=4)
Where can I learn (more) about Java's support for transaction processing?
Location: http://www.jguru.com/faq/view.jsp?EID=431948
Created: May 31, 2001
Author: John Mitchell (http://www.jguru.com/guru/viewbio.jsp?EID=4)
Getting a newly created id Is there any way I can determine the auto-
generated number with MySQL after performing an insert without sending
another query?
Location: http://www.jguru.com/faq/view.jsp?EID=440259
Created: Jun 16, 2001
Author: Alessandro A. Garbagnati (http://www.jguru.com/guru/viewbio.jsp?
EID=32727) Question originally posed by Brian Smith
(http://www.jguru.com/guru/viewbio.jsp?EID=13411
This is "MMSQL" specific functionality and you can get information on how to access
it on the Using MySQL specific functionality page of the MM.MySQL
Documentation.
Comments and alternative answers
That depends...
Author: James Chen (http://www.jguru.com/guru/viewbio.jsp?EID=452107), Jul 23,
2001
This kind of solution depends on how the java.sql.Driver to be implemented and how
the connection url string handled. You could provide an implementation to support
URL and remote database connection.
What are the components of the JDBC URL for Oracle's "thin" driver and
how do I use them?
Location: http://www.jguru.com/faq/view.jsp?EID=444466
Created: Jun 24, 2001
Author: Luigi Viggiano (http://www.jguru.com/guru/viewbio.jsp?EID=101985)
Question originally posed by lakshman prasad
(http://www.jguru.com/guru/viewbio.jsp?EID=423825
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
I've found sometime user/password encoded in the URL. I never used this form, but
here's an example:
jdbc:oracle:thin:scott/tiger@MyOracleHost:1521:MyDB
where user=scott and pass=tiger.
Let's start from the last one. TableName is the name of a Table; Schema is the name
of the container of tables ( some DBMSes normally call it 'user' ) and Catalog is a
collection of Schemas ( some DBMS normally refer to it as Database ).
The word 'pattern' is just added to underline that you can insert not just a fixed
name, but a pattern to narrow your search.
For example, if I use "", I will get back all the tables for the given Schema, in the
given Catalog, while if I use "TAB%" I'll get a list of all the tables whose name starts
with "TAB".
Where is console output sent (System.out/System.err) in stored procedures
written in Java?
Location: http://www.jguru.com/faq/view.jsp?EID=448096
Created: Jun 30, 2001
Author: Luigi Viggiano (http://www.jguru.com/guru/viewbio.jsp?EID=101985)
Question originally posed by John Zukowski PREMIUM
(http://www.jguru.com/guru/viewbio.jsp?EID=7
source: Oracle FAQ: Java Database Connectivity (JDBC) and JSQL, "What happens
when you write to the console from a Java Stored Procedure?"
This is apparently one of those cases that is OS and/or DBMS engine dependent. On
the AS/400, for example, any Java batch program ( one not running in an interactive
subsystem ) sends System out and err to a spooled file ( queued printer output ).
Therefore, if one wants to be portable, it might be best to redirect these streams to
standard files.
If you execute your stored procedure from sqlplus, then you can run the following
commands before you call the procedure, and you should see the output from within
sqlplus.
set serveroutput on
call dbms_java.set_output(2000);
I need to have result set on a page where the user can sort on the column
headers. Any ideas?
Location: http://www.jguru.com/faq/view.jsp?EID=448101
Created: Jun 30, 2001 Modified: 2001-06-30 20:03:18.499
Author: Christopher Schultz (http://www.jguru.com/guru/viewbio.jsp?EID=138382)
Question originally posed by Vasu S (http://www.jguru.com/guru/viewbio.jsp?
EID=422150
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.
I need to have result set on a page where the user can sort on the column
headers. Any ideas? -Solution
Author: Poornima Singh (http://www.jguru.com/guru/viewbio.jsp?EID=555639), Nov
21, 2001
I had done the very same thing a couple of weeks back. i had a jsp
page which was display the result set and i had to sort by the column
header. I had the sql query built in the jsp page on which the
selection crietria was done. Here I set the session variable.
session.setAttribute("ssql",sql); The column Names, had a "href link"
with the same request parameter ,but equaled to different Ints and
checked the values in the jsp page in a switch case stmt.
switch(nsortby)
{
case 1: { orderby=" order by cum "; break;}
case 2: { orderby=" order by ctitle ";break;}
case 3: { orderby=" order by cnames ";break;}
}
Some like this and then , add this string to the SQl string which is
in the session with is retirved by,
sessSQL=(String)session.getAttribute("ssql");
And excute it as ususal.
It really worked cool with me.
All the best !
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.
See section 3.4.1 Using Statement Objects for Batch Updates in the Advanced
Tutorial for more information.
Why does the JDBC specification recommend using getDouble() for SQL
FLOAT types?
Location: http://www.jguru.com/faq/view.jsp?EID=448108
Created: Jun 30, 2001
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
For the full answer, see the JDBC(tm) Technology Guide: Getting Started, Section
8.3.10: FLOAT. Briefly, "in practice all the major databases supporting FLOAT
support a mantissa precision of at least 15 digits." That is, the equivalent of a Java
double.
1)SUN has reported that this Function Sequence error is a bug in JDK 1.2 Check out
Sun's BUG List for more info on this.
2) If you are using JDK 1.2 try switching to JDK 1.3. It helped us.
Cheers, Pramod.
myStatement.close();
myStatement = myConnection.createStatement();
This is ugly and incurs a performance hit (though not as bad as recycling the
connection object) but it does work (at least in our case). Hope this helps.
Darrell Teague
Architect
Canopy International
Thanks,
Rahul
Re: Re: Sun JDBC-ODBC Bridge (JRE 1.2.2) Bug work-around
Author: Darrell Teague (http://www.jguru.com/guru/viewbio.jsp?EID=517558),
Oct 15, 2001
Yours sounds like a slightly different situation (CallableStatement Interface and
stored procedures on MS SQLServer). However, if you will post a code snippet
with all of the relavent pieces (creation of the CallableStatement, stored
procedure execution calls, creation of ResultSets, closing of ResultSets, closing
of Statement, etc), I (and perhaps others) will be glad to take a look at it.
Re: Re: Re: Sun JDBC-ODBC Bridge (JRE 1.2.2) Bug work-around
Author: Rahul Pawar (http://www.jguru.com/guru/viewbio.jsp?
EID=520149), Oct 15, 2001
Hi,
Thanks for the prompt reply.
The code snippet follows:
JavaBean code
//get connection obj into mxConn var
cs = mxConn.prepareCall("{call xt_someStoredProc(?)}");
cs.setInt(1,pk_activity);
rs = cs.executeQuery();
while (rs.next())
{ //do something; }
rs.close();
cs.close();
//close connection in the finally block
The error occurs even for a simple select query when the functionality is
used simultaneously by many users.
Declaring the cs & rs obj at class or function level made no difference
My mail adddress is rp_jguru@yahoo.com. Pls mail if you require more
info.
Thanks
CSV stands for "Comma Separated Values", so just keep any record and separe each
field with a comma and each record with a newline ('\n'). You'll have a perfect CSV
file, easy readable by any program supporting this simple format.
It's very common to put as first line the names of fields.
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:
The only generally effective way to "rollback" table creation is to delete the table.
The closest thing to a JDO FAQ is the Transparent Persistence FAQ available with
Forte.
Sun answers this question in their JDBC FAQ: Relationship of JDO and Java 2
Platform, Enterprise Edition APIs.
The home of JDO is off the beaten path at Sun. You can find its home at
http://access1.sun.com/jdo/.
Comments and alternative answers
regards. shivaram.
What is JDO?
Location: http://www.jguru.com/faq/view.jsp?EID=460410
Created: Jul 23, 2001
Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7) Question
originally posed by John Zukowski PREMIUM
(http://www.jguru.com/guru/viewbio.jsp?EID=7
JDO provides for the transparent persistence of data in a data store agnostic
manner, supporting object, hierarchical, as well as relational stores.
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.
setmaxrow, setfetchsize
Author: max laenzlinger (http://www.jguru.com/guru/viewbio.jsp?EID=429148), Jul
25, 2001
i am using mmmysql driver for mysql-database. setfetchsize has unfort. no effect in
this driver (seems to be just dummy implementation), but astonishing setmaxrows
helped me and speeded up my getnext calls; play with different values. depends on
driver+database...
So, while a java.sql.Date may show 2001-07-26, it's normalized only if the
java.util.Date value is:
A quick & dirty (but usable) solution to obtain all data from DATE fields
Author: German DZ (http://www.jguru.com/guru/viewbio.jsp?EID=504469), Sep 26,
2001
Resultset res;
int field_num; // the ordinal number of a DATE field
.
.
// here make your query
.
.
GregorianCalendar fecha = new GregorianCalendar();
GregorianCalendar hora = new GregorianCalendar();
fecha.setTime(res.getDate(field_num));
hora.setTime(res.getTime(field_num));
fecha.add(Calendar.HOUR_OF_DAY, tm.get(Calendar.HOUR_OF_DAY));
fecha.add(Calendar.MINUTE, tm.get(Calendar.MINUTE));
/*
Now you have fecha with date & time data, probably you want add the
seconds to, just add another fecha.add(...) sentence.
*/
Re: A quick & dirty (but usable) solution to obtain all data from DATE fields
Author: Magne Groenhuis (http://www.jguru.com/guru/viewbio.jsp?
EID=516289), Oct 10, 2001
In the example above:
replace tm with hora
The creators of mySQL are doing a great job in maintaining in the documentation
pages with all the differences between the two databases (and others, like
PostgreSQL). Personally I don't think these pages are fully objective, but many of the
points are often confirmed on newsgroups and mailing lists. See:
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:
FromDatabase=A; ToDatabase=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
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.
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.
Joe Sam Shirah adds: Prepared statements and batch updates should be used
wherever possible in this scenario. Also see responses by Suresh Rangan and Ivo
Limmen for other views.
Yes. Use ResultSet.getStatement(). From the resulting Statement you can use
Statement.getConnection().
Comments and alternative answers
About Statement.getConnection()
Author: Erki Suurjaak (http://www.jguru.com/guru/viewbio.jsp?EID=501734), Sep
22, 2001
You should keep in mind that Statement.getConnection() is not guaranteed to work.
For example the JDBC driver org.gjt.mm.mysql.Driver (for MySQL) throws an
AbstractMethodError.
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.
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.
Comments and alternative answers
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.
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.
A ResultSet can validly contain zero, one or many rows. For a related question and
additional information see Why does my "if(rs==null)" condition always evaluate to
false after executing a query?.
Are the code examples from the JDBC API Tutorial and Reference, Second
Edition available online?
Location: http://www.jguru.com/faq/view.jsp?EID=480723
Created: Aug 21, 2001
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Yes. The code examples for both the first and second editions of the closest thing to
a JDBC bible can be downloaded from JDBC Data Access API BOOK CODE SAMPLES.
Which Java and java.sql data types map to my specific database types?
Location: http://www.jguru.com/faq/view.jsp?EID=480892
Created: Aug 21, 2001
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
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. See How do I map database specific
( non-standard ) types to JDBC types? for more information.
You can also ask the driver and DBMS for this information programmatically, which
should be the final word. See How do I extract SQL table column type information?
and the examples TypeInfo.java, DataType.java and CreateNewTable.java in the
JDBC API Tutorial and Reference, Second Edition. ( For download information, see
Are the code examples from the JDBC API Tutorial and Reference, Second Edition
available online?. ) These examples deal generically with the
DatabaseMetaData.getTypeInfo method. Some of this information, like column type
and DBMS specific type name, is also available from ResultSetMetaData for specific
columns.
Additionally, with JDBC 2.0 drivers that support the method ( not all do ),
ResultSetMetaData also has a getColumnClassName method available.
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?
Location: http://www.jguru.com/faq/view.jsp?EID=482649
Created: Aug 23, 2001
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
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.
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.
Some downsides are: 1) Vendor specific set up tools must be used, with no particular
standards specified. To quote from the source: "Now he ( the developer - JS ) needs
to have his system administrator, SoLan, deploy the DataSource objects so that he...
can start using them". 2) JNDI must be used to implement a lookup for the
DataSource.
What types of DataSource objects are specified in the Optional Package?
Location: http://www.jguru.com/faq/view.jsp?EID=483838
Created: Aug 25, 2001
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
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.
What is DML?
Location: http://www.jguru.com/faq/view.jsp?EID=506544
Created: Sep 28, 2001
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Question originally posed by Joe Sam Shirah PREMIUM
(http://www.jguru.com/guru/viewbio.jsp?EID=42100
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.
What is DDL?
Location: http://www.jguru.com/faq/view.jsp?EID=506546
Created: Sep 28, 2001
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Question originally posed by Joe Sam Shirah PREMIUM
(http://www.jguru.com/guru/viewbio.jsp?EID=42100
DDL is an abbreviation for Data Definition Language. This portion of the SQL
standard is concerned with the creation, deletion and modification of database
objects like tables, indexes and views. The core verbs for DDL are CREATE, ALTER
and DROP. While most DBMS engines allow DDL to be used dynamically ( and
available to JDBC ), it is often not supported in transactions. See 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 for more information.
Does anyone know of a JDBC driver for SQL Server 2000 that supports
Windows Authentication?
TWFreeTDS from ThinWeb is a free type 4 JDBC driver that uses the
TDS protocol and can be used with SQL 7.0 and 2000.
Microsoft will release a beta JDBC driver for use with SQL 2000. The
original driver is not from Microsoft but bought from Merant. The press
release was issued on September 25, 2001.
For other possible drivers, see: Where can I find a comprehensive list of JDBC
drivers, including the databases they support?.
The answer is yes, but they're all commercial (with 1 open source one in
development).
I'm looking for a mature, fully developed, reasonably priced one myself. Most of the
drivers out there that accomplish this goal are, to say the least, unreasonably priced.
This may be too late to help you guys, but there are two that I know of:
Martin
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 curently used
before invoking specific operations.
How can I determine where a given table is referenced via foreign keys?
Location: http://www.jguru.com/faq/view.jsp?EID=507045
Created: Sep 29, 2001
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Question originally posed by Joe Sam Shirah PREMIUM
(http://www.jguru.com/guru/viewbio.jsp?EID=42100
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. In
other words, what tables have foreign keys that reference this table?
No, because there is no SQL standard method. The basis is mostly historical,
because almost every DBMS uses a different syntax and arguments and often
requires special permissions. In my JDBC 2.0 Fundamentals Short Course, for
example, the Cloudscape database was created with a JDBC driver URL attribute,
while DB2 on NT used CREATE DATABASE and AS/400 DB2 used CREATE COLLECTION.
If you want to use a DBMS specific means and are willing to account for ( or trade off
) portability, it is potentially possible to achieve it with JDBC. See: Can I use JDBC to
execute non-standard features that my DBMS provides?
What is the JDBC syntax for using a date literal or variable in a standard
Statement?
Location: http://www.jguru.com/faq/view.jsp?EID=507218
Created: Sep 30, 2001
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Question originally posed by Vipin Mathew
(http://www.jguru.com/guru/viewbio.jsp?EID=507095
While you are generally advised to use a PreparedStatement and let the driver
handle the syntax, the following is the standard form for regular Statements. The
general escape syntax for standard SQL date columns is:
{d 'yyyy-mm-dd'}
For literals:
String sSQL =
"SELECT colName FROM aTable " +
"WHERE colDate = {d '2001-10-21'}"
For variables ( note that toString() is implicitly called on the date variable ):
java.sql.Date jsqlDate;
... // set date
String sSQL =
"SELECT colName FROM aTable " +
"WHERE colDate = {d '" + jsqlDate + "'}"
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.
How does one get column names for rows returned in a ResultSet?
Location: http://www.jguru.com/faq/view.jsp?EID=524526
Created: Oct 18, 2001 Modified: 2002-03-23 22:59:11.612
Author: Jason Stell (http://www.jguru.com/guru/viewbio.jsp?EID=50780) Question
originally posed by Maxim Markaitis (http://www.jguru.com/guru/viewbio.jsp?
EID=521563
ResultSet rs = ...
...
ResultSetMetaData rsmd = rs.getMetaData();
int numCols = rsmd.getColumnCount();
i < numCols+1
Author: Maxim Markaitis (http://www.jguru.com/guru/viewbio.jsp?EID=521563),
Nov 9, 2001
.
Column count off by 1
Author: Corellian Trader (http://www.jguru.com/guru/viewbio.jsp?EID=774641), Feb
27, 2002
Correction
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100), Mar
23, 2002
Thanks to both responders, the code has been corrected.
I have an application that queries a database and retreives 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();
Is there another way of dealing with the result set that could execute
faster?
Location: http://www.jguru.com/faq/view.jsp?EID=524658
Created: Oct 18, 2001
Author: Dermot Hennessy (http://www.jguru.com/guru/viewbio.jsp?EID=390903)
Question originally posed by Jeffrey Mutonho
(http://www.jguru.com/guru/viewbio.jsp?EID=513649
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.
Joe Sam Shirah adds: For another view on the best collection class, see Which is the
preferred collection class to use for storing database result sets? Either way,
Dermot's point on speed issues with Vectors is certainly valid.
Performace Tips
Author: Chantal Ackermann (http://www.jguru.com/guru/viewbio.jsp?EID=88569),
Oct 22, 2001
I've just visited a site about jdbc performance tips:
http://www.as400.ibm.com/developer/java/topics/jdbctips.html
One thing they mention is, that the method getObject() is slower than the methods
that specify the type of the retrieved data.
Another hint for the table model comes from this place:
http://java.sun.com/products/jfc/tsc/articles/javaOne2001/1339/index.html
It says that the table model works fastest based on a hash table where the key is of
class Point, using the parameters to specify the column and the row, and the value is
the value in the cell specified by this Point.
Chantal
There is not a JDBC specific equivalent, but the Java way, typically, is to use
properties files or ResourceBundles. For an example, see Generalizing Connection
Information--Batch in my JDBC 2.0 Fundamentals course.
Different DBMS engines use different statement terminators. The usual advice is to
use none at all and let the driver handle it. Unless the driver is smart enough to
figure out where each statement begins and ends, in this case you really can't do
that. Unfortunately, there doesn't seem to be a method in the driver or metadata
classes to get the DBMS specific terminator used. So, this area doesn't appear to be
very portable. If you are certain that there actually is nothing invalid in your
statements, the other possibility is that your driver just won't handle this properly,
so the last step is to check with your DBMS's technical support.
Comments and alternative answers
I'm using the Oracle thin driver to update a batch of records using a
prepared statement, addBatch() and executeBatch(). All of the updates go
through fine and the data is updated correctly, but all of the updateCounts
returned are "-2". I haven't been able to find any documentation for the
thin driver, so I don't know if this return code is something I should be
worried about, or if I should just ignore it.
Location: http://www.jguru.com/faq/view.jsp?EID=525335
Created: Oct 19, 2001
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Question originally posed by Tim Duggan (http://www.jguru.com/guru/viewbio.jsp?
EID=506387
Although you are always dependent on your driver capabilities, JDBC does provide a
means of handling this sort of situation. execute() returns a boolean - true if the
rusult is a ResultSet, false if an int is returned ( for update count or DDL ). From the
API documentation: "The methods execute, getMoreResults, getResultSet, and
getUpdateCount let you navigate through multiple results. The execute method
executes an SQL statement and indicates the form of the first result. You can then
use the methods getResultSet or getUpdateCount to retrieve the result, and
getMoreResults to move to any subsequent result(s)."
A more complete explanation and example code is provided in JDBC API Tutorial and
Reference, 2nd Ed: Java 2 in "Statements - 40.1.8 Executing Special Kinds of
Statements". Unfortunately, this particular section does not appear to be available
online.
Stored Procedure
Author: Cenan Yesiltas (http://www.jguru.com/guru/viewbio.jsp?EID=937310), Jul 3,
2002
if you use the CalableStatement interface before don't use execute() method you must
register the Out parameter with registerOutParameter method that the method takes
parameter java.sql.Types which decides your parametertyp forexample : if your out
parameter tweice par. CallableStatement statement;
statement=conn.prepareCall("{call procedurename[(?,?)]}");
statement.registerOutParameter(2,java.sql.Types.FlOAT); .... . . then you use with
statement.getFloat(2); your out parameter. I hope that i help you. cu
How can I write a CLOB object in weblogic using type 4 driver with Oracle?
Location: http://www.jguru.com/faq/view.jsp?EID=525871
Created: Oct 20, 2001
Author: Denis Navarre (http://www.jguru.com/guru/viewbio.jsp?EID=495283)
Question originally posed by Atam Govil (http://www.jguru.com/guru/viewbio.jsp?
EID=89203
The following documentation from Oracle should help: Working with BLOBs and
CLOBs
TOMCAT 4.0.1 on NT4 throws the foll exception when i try to connect to Oracle DB
from JSP.
javax.servlet.ServletException : oracle.jdbc.driver.OracleDriver
But, the Oracle JDBC driver ZIP file (classes111.zip)is avbl in the system classpath.
My problem was solved. I copied the Oracle Driver class file (classes111.zip) in
%TOMCAT_HOME%\lib directory and renamed it to classess111.jar. It worked.
Now i am able to connect to Oracle DB from TOMCAT 4.01 via Oracle JDBC-Thin
Driver.
thanks
Author: shankar ram thyagarajan (http://www.jguru.com/guru/viewbio.jsp?
EID=573833), Dec 5, 2001
i had the same problem with classes12.zip. as per ur suggestion, i renamed it to
classes12.jar, and it works fine. thanks a lot.
Re: thanks
Author: Jason ye (http://www.jguru.com/guru/viewbio.jsp?EID=795899), Mar 13,
2002
yes. after renamed it to lasses12.jar. it works . but i getting other problem . the
same jsp file . the same jdbc connection pool . in tomcat3.2 it can working fine .
but in tomcat4.0 the jsp program can't get any data without any errors . why ?
Re: thanks
Author: Ramadevan MadhuSudanan (http://www.jguru.com/guru/viewbio.jsp?
EID=733076), Jul 20, 2002
i got the problem solved.i renamed the classes12.zip to classes12.jar. it worked.
thanks a lot.I had faced the same problem with my WebSphere- Oracle-
JDBC.Thanks once again.
Re[2]: thanks
Author: srinivasa prasad (http://www.jguru.com/guru/viewbio.jsp?
EID=1170424), May 13, 2004
Yes. Renaming the classes12.zip to classes12.jar works fine. after renaming
just place it in the web-inf/lib folder. Dont forget to restart the tomcat.
Here some possible solutions for your problem: It's Excel-lent and The Java-Excel
solution revisited.
Joe Sam Shirah adds: Also see How can I connect to an Excel spreadsheet file using
jdbc? and Where do I find information about operations on Excel, Word, text files
and other non-DBMS products that can be accessed via the JDBC-ODBC Bridge?.
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.
Location: http://www.jguru.com/faq/view.jsp?EID=534011
Created: Oct 30, 2001
Author: Percy Wong (http://www.jguru.com/guru/viewbio.jsp?EID=522735)
Question originally posed by Andrew Holm-Hansen
(http://www.jguru.com/guru/viewbio.jsp?EID=529043
Could you please tell me about the other db server 's index syntax especially
oracle and sybase?
Author: Imam Raza (http://www.jguru.com/guru/viewbio.jsp?EID=863442), May 2,
2002
Hi!
Referring to your following answere:
==================================================
//Note: index "PrimaryKey" is Access DB specific // other db server has diff. index
syntax. ====================================================
Could you please tell me about the other db server 's index syntax especially oracle
and sybase?
Thank You
Good Bye
while (foreignKeys.next())
{
String fkName = foreignKeys.getString(1);//FK_NAME
// if FK has no name - make it up (use tablename instead)
if (fkName == null)
{
fkName = foreignKeys.getString(2);//PKTABLE_NAME
}
String fkey = foreignKeys.getString(3); //local column
//FKCOLUMN_NAME
String pkey = foreignKeys.getString(4); //foreign
column //PKCOLUMN_NAME
Joe Sam Shirah adds: Note that 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.
How do I SELECT records with some of the columns having NULL value?
Author: Fernando Cardoso (http://www.jguru.com/guru/viewbio.jsp?EID=717068),
Jan 11, 2002
I tried this example in some DBMS (Oracle 9i/SqlServer2000/DB2/Ms-access) with
no results: ps = con.prepareStatement("Select * from COUNTRY where dbisocode
= ?"); ps.setNull(1,java.sql.Types.VARCHAR); What's wrong with this code? Also, i
tried with numeric fields.
Re: How do I SELECT records with some of the columns having NULL
value?
Author: Heng Cao (http://www.jguru.com/guru/viewbio.jsp?EID=735111), Jan 25,
2002
The null check should be "is", instead of "=", "=" always return false if any of its
operands is null.
Re[2]: How do I SELECT records with some of the columns having NULL
value?
Author: Ramesh Sakala (http://www.jguru.com/guru/viewbio.jsp?
EID=1102113), Jul 17, 2003
isNull(index, Types.VARCHAR) should work as per JDBC spec. With Oracle
thin driver, it is not working. Can someone think of any other way of doing
without changing the query back to "is null" because with this solution, query
has to be written based on the values being passed into preparedstatement,
which is not elegant.
But an error gets thrown because there are some NULL fields in the table.
Location: http://www.jguru.com/faq/view.jsp?EID=545713
Created: Nov 12, 2001
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Question originally posed by YU CUI (http://www.jguru.com/guru/viewbio.jsp?
EID=539652
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 numerics
( 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. For
more information, see the JDBC(tm) Technology Guide: Getting Started 5.1.19 NULL
Result Values.
Null capability is a column integrity constraint, normally aplied 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
)
I've heard that I can save space by allowing NULLs for columns where no
value is supplied. Is that correct?
Location: http://www.jguru.com/faq/view.jsp?EID=561332
Created: Nov 26, 2001
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
While the answer is ultimately dependent on your specific DBMS, most databases
create an extra byte for every null capable column to mark whether or not it contains
a null value. This clearly means that more space is used and processing time is also
usually longer, since the additional byte value must be checked.
How can I overwrite blob data in an Oracle database? I want to replace the
blob in the selected row with byte[] blobData using the following code:
OracleResultSet rset=null;
OutputStream os=null;
CallableStatement stmt=null;
conn.setAutoCommit(false);
stmt = conn.prepareCall("select myblob from mytable " +
"where mycolumn='foobar' for update");
stmt.execute();
rset=(OracleResultSet)stmt.getResultSet();
rset.next();
BLOB bdata=rset.getBLOB("myblob");
os=bdata.getBinaryOutputStream();
os.write(blobData);
os.flush();
os.close();
conn.commit();
However, this only replaces the first blobData.length bytes of the blob and
leaves the rest. How can I replace the entire blob with the byte[]?
Location: http://www.jguru.com/faq/view.jsp?EID=564073
Created: Nov 27, 2001
Author: Bernie Acs (http://www.jguru.com/guru/viewbio.jsp?EID=540259) Question
originally posed by Joe R (http://www.jguru.com/guru/viewbio.jsp?EID=535256
This behavior is exactly how the function is designed to work; to accomplish a
complete replacement of the orginal data you could set the blob column to the value
empty_blob() prior to inputting your new data which would do the trick, or you must
use the length written to determine the point to trim out the old blob data. The first
is probably the best approach and would look something like the following:
OracleResultSet rset=null;
OutputStream os=null;
CallableStatement stmt=null;
Statement stmt1 = null;
conn.setAutoCommit(false);
BLOB privileges?
Author: Marie Ricketts (http://www.jguru.com/guru/viewbio.jsp?EID=575334), Dec
6, 2001
When I use the method above I get:
Instead of this:
BLOB bdata=rset.getBLOB("myblob");
os=bdata.getBinaryOutputStream();
You need to do this:
BLOB bdata=rset.getBLOB("myblob");
bdata.trim(0);
os=bdata.getBinaryOutputStream();
The DatabaseMetaData class has a large number of supportsXXX methods which you
can use to ensure that the operation will proceed or otherwise provide a workaround.
See the API documentation for detailed information.
How can I ensure that my SQL statements meet SQL standards to get
maximum portability?
Location: http://www.jguru.com/faq/view.jsp?EID=564466
Created: Nov 27, 2001
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
One tool to use is Mimer SQL Validator. This page links to validators for SQL-92 and
SQL-99 ( SQL3 ). In addition, there is a list of SQL reserved words.
DB2 Universal claims to support JDBC 2.0, But I can only get JDBC 1.0
functionality. What can I do?
Location: http://www.jguru.com/faq/view.jsp?EID=564469
Created: Nov 27, 2001
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
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.
The first thing is to be sure that this does not occur when running non-JDBC apps. If
so, there is a faulty JDK/JRE installation. If it happens only when using JDBC, then
it's time to check the documentation that came with the driver or the driver/DBMS
support. JDBC driver types 1 through 3 have some native code aspect and typically
require some sort of client install. Along with the install, various environment
variables and path or classpath settings must be in place. Because the requirements
and installation procedures vary with the provider, there is no reasonable way to
provide details here. A type 4 driver, on the other hand, is pure Java and should
never exhibit this problem. The trade off is that a type 4 driver is usually slower.
/**
* package6.executableTester
*
* @author Me
*/
public class executableTester {
protected static myConnectionPoolDataSource dataSource = null;
static int i = 0;
/**
* Constructor
*/
public executableTester() throws java.sql.SQLException
{
}
/**
* main
* @param args
*/
public static void main(String[] args) {
try{
dataSource = new myConnectionPoolDataSource();
}
catch ( Exception ex ){
ex.printStackTrace();
}
worker.setConnectionPoolDataSource( dataSource.getConnectionPoolDataSour
ce() );
worker.start();
System.out.println( "Started Thread#"+i );
}
catch ( Exception ex ){
ex.printStackTrace();
}
}
}
}
The DataSource Member
// Copyright (c) 2000
package package6;
import oracle.jdbc.pool.*;
/**
* package6.myConnectionPoolDataSource.
*
* @author Me
*/
public class myConnectionPoolDataSource extends Object {
protected OracleConnectionPoolDataSource ocpds = null;
/**
* Constructor
*/
public myConnectionPoolDataSource() throws java.sql.SQLException {
// Create a OracleConnectionPoolDataSource instance
ocpds = new OracleConnectionPoolDataSource();
}
The Worker Thread Member
// Copyright (c) 2000
package package6;
import oracle.jdbc.pool.*;
import java.sql.*;
import javax.sql.*;
/**
* package6.workerClass .
*
* @author Me
*/
public class workerClass extends Thread {
protected OracleConnectionPoolDataSource ocpds = null;
protected PooledConnection pc = null;
public workerClass() {
}
// Create a Statement
Statement stmt = conn.createStatement ();
}
The OutPut Produced
Started Thread#1
Started Thread#2
Started Thread#3
Started Thread#4
Started Thread#5
Started Thread#6
Started Thread#7
Started Thread#8
Started Thread#9
Started Thread#10
workerClass.thread# 1 completed..
workerClass.thread# 10 completed..
workerClass.thread# 3 completed..
workerClass.thread# 8 completed..
workerClass.thread# 2 completed..
workerClass.thread# 9 completed..
workerClass.thread# 5 completed..
workerClass.thread# 7 completed..
workerClass.thread# 6 completed..
workerClass.thread# 4 completed..
The oracle.jdbc.pool.OracleConnectionCacheImpl class is another subclass of the
oracle.jdbc.pool.OracleDataSource which should also be looked over, that is what
you really what to use. Here is a similar example that uses the
oracle.jdbc.pool.OracleConnectionCacheImpl. The general construct is the same as
the first example but note the differences in workerClass1 where some statements
have been commented ( basically a clone of workerClass from previous example ).
/**
* package6.executableTester2
*
* @author Me
*/
public class executableTester2 {
static int i = 0;
protected static myOracleConnectCache connectionCache = null;
/**
* Constructor
*/
public executableTester2() throws SQLException
{
}
/**
* main
* @param args
*/
public static void main(String[] args) {
OracleConnectionPoolDataSource dataSource = null;
try{
}
catch ( Exception ex ){
ex.printStackTrace();
}
}
The ConnectCacheImpl Member
// Copyright (c) 2000
package package6;
import javax.sql.ConnectionPoolDataSource;
import oracle.jdbc.pool.*;
import oracle.jdbc.driver.*;
import java.sql.*;
import java.sql.SQLException;
/**
* package6.myOracleConnectCache
*
* @author Me
*/
public class myOracleConnectCache extends OracleConnectionCacheImpl {
/**
* Constructor
*/
public myOracleConnectCache( ConnectionPoolDataSource x) throws
SQLException {
initialize();
}
}
The Worker Thread Member
package package6;
import oracle.jdbc.pool.*;
import java.sql.*;
import javax.sql.*;
/**
* package6.workerClass1
*
* @author Me
*/
public class workerClass1 extends Thread {
// protected OracleConnectionPoolDataSource ocpds = null;
// protected PooledConnection pc = null;
public workerClass1() {
}
// Create a Statement
Statement stmt = conn.createStatement ();
// public void
setConnectionPoolDataSource(OracleConnectionPoolDataSource x){
// ocpds = x;
// }
}
The OutPut Produced
Started Thread#1
Started Thread#2
workerClass1.thread# 1 completed..
workerClass1.thread# 2 completed..
Started Thread#3
Started Thread#4
Started Thread#5
workerClass1.thread# 5 completed..
workerClass1.thread# 4 completed..
workerClass1.thread# 3 completed..
Started Thread#6
Started Thread#7
Started Thread#8
Started Thread#9
workerClass1.thread# 8 completed..
workerClass1.thread# 9 completed..
workerClass1.thread# 6 completed..
workerClass1.thread# 7 completed..
Started Thread#10
workerClass1.thread# 10 completed..
First, it should be pointed out that PreparedStatement handles many issues for the
developer and normally should be preferred over a standard Statement.
Otherwise, the JDBC syntax is really the same as SQL syntax. One problem that
often affects newbies ( and others ) is that SQL, like many languages, requires
quotes around character ( read "String" for Java ) values to distinguish from
numerics. So the clause:
Also see: What is the JDBC syntax for using a date literal or variable in a standard
Statement?.
Database table columns of type CHAR, when extracted from a ResultSet (using
getString) will be padded with trailing spaces, e.g.
Few companies can really afford NOT to use a DBMS. If nothing else, developer time
spent on custom persistence methods can quickly surpass the cost of a DBMS. If the
company doesn't understand this, one option often offered in jest may get serious:
Find another company.
But there are low cost, production quality options available and it's worth using the
drivers list ( see Where can I find a comprehensive list of JDBC drivers, including the
databases they support? ) in reverse to check out DBMS candidates.
Open source DBMS engines are another possibility. For some options there, see Tools
for the Open-Source Database
Another, possibly larger, consideration for a cost concious company is that a number
of the large commercial databases effectively require a full time DBA, meaning
another salary. For that reason, you'll want to look for an easy to use, low
maintenance product.
This is not the problem it once was, although your hard drive may groan. Many of
the major DBMS vendors now offer personal or developer versions for download at
no cost. The J2EE download also includes a supporting DBMS. In addition, there are
several open source databases available. For more information on where to look for
these products, see: My company says it can't aford a DBMS. What can I do?
How do I set properties for a JDBC driver and where are the properties
stored?
Location: http://www.jguru.com/faq/view.jsp?EID=593758
Created: Dec 21, 2001
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Question originally posed by Pradeep Kharvi
(http://www.jguru.com/guru/viewbio.jsp?EID=342402
A JDBC driver may accept any number of properties to tune or optimize performance
for the specific driver. There is no standard, other than user and password, for what
these properties should be. Therefore, the developer is dependent on the driver
documentation to automatically pass properties. For a standard dynamic method that
can be used to solicit user input for properties, see What properties should I supply
to a database driver in order to connect to a database?
In addition, a driver may specify its own method of accepting properties. Many do
this via appending the property to the JDBC Database URL. However, a JDBC
Compliant driver should implement the connect(String url, Properties info) method.
This is generally invoked through DriverManager.getConnection(String url, Properties
info).
The passed properties are ( probably ) stored in variables in the Driver instance.
This, again, is up to the driver, but unless there is some sort of driver setup, which is
unusual, only default values are remembered over multiple instantiations.
A Locator is an SQL3 data type that acts as a logical pointer to data that resides on a
database server. Read "logical pointer" here as an identifier the DBMS can use to
locate and manipulate the data. A Locator allows some manipulation of the data on
the server. While the JDBC specification does not directly address Locators, JDBC
drivers typically use Locators under the covers to handle Array, Blob, and Clob data
types. For more information, see SQL Locators.
Why do I have to reaccess the database for Array, Blob, and Clob data?
Location: http://www.jguru.com/faq/view.jsp?EID=594583
Created: Dec 23, 2001
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Most DBMS vendors have implemented these types via the SQL3 Locator type ( see
What is an SQL Locator? and the JDBC 2.1 core API specifies "By default, a JDBC
driver should implement the Blob and Clob interfaces using the appropriate locator
type." The same is true for the Array interface.
Some rationales for using Locators rather than directly returning the data can be
seen most clearly with the Blob type. By definition, a Blob is an arbitrary set of
binary data. It could be anything; the DBMS has no knowledge of what the data
represents. Notice that this effectively demolishes data independence, because
applications must now be aware of what the Blob data actually represents. Let's
assume an employee table that includes employee images as Blobs.
Say we have an inquiry program that presents multiple employees with department
and identification information. To see all of the data for a specific employee,
including the image, the summary row is selected and another screen appears. It is
only at this pont that the application needs the specific image. It would be very
wasteful and time consuming to bring down an entire employee page of images
when only a few would ever be selected in a given run.
Now assume a general interactive SQL application. A query is issued against the
employee table. Because the image is a Blob, the application has no idea what to do
with the data, so why bring it down, killing performance along the way, in a long
running operation?
Clearly this is not helpful in those applications that need the data everytime, but
these and other considerations have made the most general sense to DBMS vendors.
This term generally refers to Array, Blob and Clob data which is referred to in the
database via SQL locators ( see What is an SQL Locator? ) "Materializing" the data
means to return the actual data pointed to by the Locator.
How can I get or redirect the log used by DriverManager and JDBC drivers?
Location: http://www.jguru.com/faq/view.jsp?EID=594586
Created: Dec 23, 2001
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
How can I write to the log used by DriverManager and JDBC drivers?
Location: http://www.jguru.com/faq/view.jsp?EID=594587
Created: Dec 23, 2001
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Stored procedures can return a result parameter, which can be a result set. For a
discussion of standard JDBC syntax for dealing with result, IN, IN/OUT and OUT
parameters, see Stored Procedures. In addition, see How do I execute stored
procedures?, How can I get data from multiple ResultSets?, Could we get sample
code for retrieving more than one parameter from a stored procedure?.
Comments and alternative answers
I've tried setting the out param as java.sql.Types.OTHER and NULL as well,
but then I get an error 'invalid column type' what am I doing wrong here? Can't
I just drop the output param name and use the ResultSet returned by
executeQuery() instead?
cstmt.execute();
I assume that your proxy is set to accept http requests only on port 80. If you want
to have a local class behind the proxy connect to the database for you, then you
need a servlet/JSP to receive an HTTP request and use the local class to connect to
the database and send the response back to the client.
You could also use RMI where your remote computer class that connects to the
database acts as a remote server that talks RMI with the clients. if you implement
this, then you will need to tunnel RMI through HTTP which is not that hard.
In summary, either have a servlet/JSP take HTTP requests, instantiate a class that
handles database connections and send HTTP response back to the client or have the
local class deployed as RMI server and send requests to it using RMI.
What isolation level is used by the DBMS when inserting, updating and
selecting rows from a database?
Location: http://www.jguru.com/faq/view.jsp?EID=740645
Created: Jan 30, 2002
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Question originally posed by ani ani (http://www.jguru.com/guru/viewbio.jsp?
EID=706510
The answer depends on both your code and the DBMS. If the program does not
explicitly set the isolation level, the DBMS default is used. You can determine the
default using DatabaseMetaData.getDefaultTransactionIsolation() and the level for
the current Connection with Connection.getTransactionIsolation(). If the default is
not appropriate for your transaction, change it with
Connection.setTransactionIsolation(int level). See also: How does one manage
concurrency issues with JDBC?
Are you using a CHAR or a VARCHAR data field? I remember having the same
problem with a CHAR type, and then we switched to a VARCHAR.
Joe Sam Shirah adds: In the SQL standard, CHAR is a fixed length data type. In
many DBMSes ( but not all), that means that for a WHERE clause to match, every
character must match, including size and trailing blanks. As Alessandro indicates,
defining CHAR columns to be VARCHAR is the most general answer.
UPDATE int(5) zerofill key with 00003 instead of 3 in the WHERE clause of my
prepared statement ??
Author: mad driver (http://www.jguru.com/guru/viewbio.jsp?EID=865419), Jun 29,
2002
I currently have the same problem. I'm using MYSQL int(5) autoincrement with
zerofill as only key.
So far I used INSERT-statements.fine. Now I try my first UPDATE.
No exception,error,nothing...but nothing got updated too!
Do i need to change the input in the WHERE clause from 3 to 00003 ?? Is there a
varint?:)
Is there the same problem with no zerofill option ?
I see that real 0000's are different from blanks, but I never had a problem with blanks
in my varchar, and I obviously have been a little naiv when I just expected leading
zeros to be ignored?
Is there a standard routine I could use with the jdbc?
thanks for help in advance
mad
Any given database may not support all of these levels. To find out if yours does,
see: How can I determine the isolation levels supported by my DBMS?
Comments and alternative answers
jdbc
Author: jagadish varma (http://www.jguru.com/guru/viewbio.jsp?EID=1127658),
Nov 11, 2003
hi plz write me a sample code to demonstrate how to use constants defined
java.sql.connection as well as java.sql.statement
I think you mean "lock a table in exclusive mode". You cannot open a connection
with exclusive mode. Depending on your database engine, you can lock tables or
rows in exclusive mode.
Re: jdbc
Author: payal ahuja (http://www.jguru.com/guru/viewbio.jsp?EID=991966), Aug
30, 2002
good
comment
Author: payal ahuja (http://www.jguru.com/guru/viewbio.jsp?EID=991966), Aug 30,
2002
good
jguru Disclaimer: The following views and opinions are entirely those of the
respondents and provided for our readers to consider. jGuru is not in the business of
evaluating products.
Disclaimer: I'm still in the process of evaluating some of these tools so you should do
your own tests before making any final decisions.
I think an O/R mapping tool could help a lot. After all, there is nothing more tedious
and error prone than writing code to move data from a database to a Java class and
back again!
If you are lucky enough that you have a database schema that reflects the object
model reasonably well then I think these tools will help a lot.
Unfortunately, I think I'm coming to the conclusion that it is not worth trying to use
these tools with a legacy database. By legacy, I mean one that was never designed
in an object-oriented way. Instead, you should probably use a DAO approach.
I've looked at quite a few: TopLink, CocoBase, OJB, Castor. Of those, I favour
TopLink and OJB. OJB is open source, if that appeals, and is nearing a 1.0 release.
It's continuously improving, has active development and the lead developer is
extremely responsive to both suggestions and bug reports.
You need to choose carefully. In particular, think about how you want to manage
connections and transactions. Perhaps you want to use these tools inside an EJB
container and take advantage of the container's transaction management?
Unless the application is fairly simple, I suspect there will always be the need for
writing JDBC but hopefully that would be the exception.
I would recommend reading Scott Ambler's white papers on the subject, just to get a
feel for what an O/R tool should do:
There is plenty more information on the internet. Please post your findings back
here.
Jay Meyer adds: I have used Toplink in a large Weblogic environemnt, and it has
good and bad points. You were right: do NOT use Toplink on a legacy database, it
will not be able to handle some of the complex relationships. We ended up
redesigning some tables to make Toplink work with our old schema. But once we did
that it would gen the EJBs and change tables anytime we needed to add columns or
tables to the database. This was useful in the large dev team. The downside to
Toplink or any O-R mapping tool is that you invariably have to learn yet another
query language. Toplink's query builder was really hard to understand especially
when you have dozens of programmers who already know SQL and want to use SQL
directly. For our next project, we used the Ambler persistence (mentioned in Matt's
message) technique and wrote our own mapping classes. It turned out to be about
the same amount of work/time as installing/configuring Toplink, we just needed
some skilled Java/JDBC programmers to build it. But now we have full controll over
queries and performance using the JDBC calls and we do not have to figure out
Toplink's cryptic product.
Joe Sam Shirah adds: Object databases are certainly an option, but there are many
reasons the relational model has remained the data backbone. My own opinion is
that when evaluating an object database, an important criteria should be that it also
supports the relational model as much as possible.
Another open source O/R tool to review is the Java Layered Frameworks ( JLF ).
Note that a specific DBMS may provide some combination of all of these. Outside of
those scenarios, you would, in general, have to handle encoding yourself. For all
intents and purposes, you would have binary data in a character column. Aside from
being error prone, you would lose virtually all benefits of a DBMS other than identity,
structure, security and, presumably, reliability.
The problem I found is that if I create a statement for each operation the
memory used increases fast! I am closing each of the statements... and
autocommit is true! Please help!
Location: http://www.jguru.com/faq/view.jsp?EID=761133
Created: Feb 16, 2002
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Question originally posed by Filipe Lima de Souza
(http://www.jguru.com/guru/viewbio.jsp?EID=756154
Regardless of DBMS, there's no particular reason to close a Statement until you are
done with your operations - assuming 1) a JDBC compliant driver works normally; 2)
that there aren't extended periods when the Statement isn't used and 3) you aren't
using a connection pool, which would mean closing the Statement before returning
the connection to the pool.
Depending on what you are doing, the memory usage may be completely normal; In
the JVM, memory usage will rise until the garbage collector kicks in. It may well be
that the driver has memory leaks - you should check their site/support/forums - but
the factors above are still true.
Can you scroll a result set returned from a stored procedure? I am returning
a result set from a stored procedure with type SQLRPGLE but once I reach
the end of the result set it does not allow repositioning. Is it possible to
scroll this result set?
Location: http://www.jguru.com/faq/view.jsp?EID=761196
Created: Feb 16, 2002
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Question originally posed by Shannon Clement
(http://www.jguru.com/guru/viewbio.jsp?EID=754297
For more information, see 7.1.1 Creating a CallableStatement Object, Can a stored
procedure return an updatable ResultSet?, and How do I receive a ResultSet from a
stored procedure?.
Hai Auro I have the same problem.Can u help me out if u have got the answer.It is very urgent.
my code goes like this my code goes like this
import oracle.jdbc.*;
import java.sql.*;
import javax.sql.*;
class TestProcedure
{
public static void main(String args[])
{
TestProcedure test = new TestProcedure();
test.Test();
}
public void Test()
{
java.sql.CallableStatement cstmtObject = null;
java.sql.ResultSet rulesObject = null;
try{
String conStr = "jdbc:oracle:thin:@172.20.10.7:1521:BAS";
String user = "test";
String pass = "test123";
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
java.sql.Connection conn = (java.sql.Connection)DriverManager.getConnection(conStr,user,pass);
System.out.println("connected");
String sqlquery = "{call test.COMPUTATION(?,?,?,?)}";
cstmtObject =
conn.prepareCall(sqlquery,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_O
cstmtObject.setString(1,"BSD");
cstmtObject.setString(2,"BG");
cstmtObject.setString(3,"monthly");
cstmtObject.registerOutParameter(4,OracleTypes.CURSOR);
rulesObject = (java.sql.ResultSet)cstmtObject.getObject(4);
System.out.println("resultset type="+rulesObject.getType());
while(rulesObject.next())
{
int ruleid = rulesObject.getInt("rule_id");
String rulename = rulesObject.getString("rule_name");
String expression = rulesObject.getString("expression");
}
rulesObject.first(); //Error here
conn.close();
}catch(SQLException e){System.out.println(e);}
}
}
When I give rulesObject.first(); it gives SQL Exception of forwardly only resultset. How can I scroll th
the resultset. thanks in advance.
For more information, see My application uses a database and doesn't seem to scale
well. What could be going on? on the FREQUENTLY ASKED QUESTIONS ABOUT THE
JAVA HOTSPOT VIRTUAL MACHINE page.
Joe Sam Shirah adds: You can also get this information in a portable way, and
potentially avoid another database access, by capturing SQLState messages. Some
databases get more specific than others, but the general code portion is 23 -
"Constraint Violations". UDB2, for example, gives a specific such as 23505, while
others will only give 23000. For more information, see Where can I find a list of the
possible SQLStates returned by SQLException.getSQLState()? and my JDBC 2.0
Fundamentals Short Course at the Java Developer Connection.
Conclusion: JAD decompiles things easily and obfuscation would not help you. But
you'd have the same problem with C/C++ because the connect string would still be
visible in the executable.
SSL JDBC network drivers fix the password sniffing problem (in MySQL 4.0), but not
the decompile problem. If you have a servlet container on the web server, I would
go that route (see other discussion above) then you could at least keep people from
reading/destroying your mysql database.
Make sure you use database security to limit that app user to the minimum tables
that they need, then at least hackers will not be able to reconfigure your DBMS
engine.
Joe Sam Shirah adds: Aside from encryption issues over the internet, it seems to me
that it is bad practise to embed user ID and password into program code. One could
generally see the text even without decompilation in almost any language. This
would be appropriate only to a read-only database meant to be open to the world.
Normally one would either force the user to enter the information or keep it in a
properties file.
A production quality database will support security and user rights. Also, for more
information regarding JDBC and SSL, see: Are there any JDBC drivers available that
support using SSL to communicate between the Java program and the database
server?
Can I set up a conection pool with multiple user IDs? The single ID we are
forced to use causes probelems when debugging the DBMS.
Location: http://www.jguru.com/faq/view.jsp?EID=773655
Created: Feb 26, 2002
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Question originally posed by John Murphy
(http://www.jguru.com/guru/viewbio.jsp?EID=749811
Since the Connection interface ( and the underlying DBMS ) requires a specific user
and password, there's not much of a way around this in a pool. While you could
create a different Connection for each user, most of the rationale for a pool would
then be gone. Debugging is only one of several issues that arise when using pools.
However, for debugging, at least a couple of other methods come to mind. One is to
log executed statements and times, which should allow you to backtrack to the user.
Another method that also maintains a trail of modifications is to include user and
timestamp as standard columns in your tables. In this last case, you would collect a
separate user value in your program.
How can I instantiate and load a new CachedRowSet object from a non-
JDBC source?
Location: http://www.jguru.com/faq/view.jsp?EID=776543
Created: Feb 28, 2002 Modified: 2002-02-28 10:15:29.257
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
Question originally posed by Covenant apoptygma
(http://www.jguru.com/guru/viewbio.jsp?EID=747571
The following code works with the Early Access JDBC RowSet download available
from the Java Developer Connection and is an expansion of one of the examples:
public RowSetEx1()
{
try
{
crs = new CachedRowSet();
crs.setReader(this);
crs.execute(); // load from reader
System.out.println(
"Fetching from RowSet...");
while(crs.next())
{
showTheData();
} // end while next
if(crs.isAfterLast() == true)
{
System.out.println(
"We have reached the end");
System.out.println("crs row: " +
crs.getRow());
}
System.out.println(
"And now backwards...");
while(crs.previous())
{
showTheData();
} // end while previous
if(crs.isBeforeFirst() == true)
{ System.out.println(
"We have reached the start");
}
crs.first();
if(crs.isFirst() == true)
{ System.out.println(
"We have moved to first");
}
if(crs.isBeforeFirst() == false)
{ System.out.println(
"We aren't before the first row."); }
crs.last();
if(crs.isLast() == true)
{ System.out.println(
"...and now we have moved to the last");
}
if(crs.isAfterLast() == false)
{
System.out.println(
"we aren't after the last.");
}
} // end try
catch (SQLException ex)
{
System.err.println("SQLException: " +
ex.getMessage());
}
} // end constructor
iCol2 = crs.getInt(2);
if (crs.wasNull() == false)
{ System.out.println("iCol2: " + iCol2); }
else { System.out.println("iCol2 is null"); }
sCol3 = crs.getString(3);
if (crs.wasNull() == false)
{
System.out.println("sCol3: " +
sCol3 + "\n" );
}
else
{ System.out.println("sCol3 is null\n"); }
} // end showTheData
// RowSetReader implementation
public void readData(RowSetInternal caller)
throws SQLException
{
rsmdi = new RowSetMetaDataImpl();
rsmdi.setColumnCount(3);
rsmdi.setColumnType(1, Types.VARCHAR);
rsmdi.setColumnType(2, Types.INTEGER);
rsmdi.setColumnType(3, Types.VARCHAR);
crs.setMetaData( rsmdi );
crs.moveToInsertRow();
crs.updateString( 1, "StringCol11" );
crs.updateInt( 2, 1 );
crs.updateString( 3, "StringCol31" );
crs.insertRow();
crs.updateString( 1, "StringCol12" );
crs.updateInt( 2, 2 );
crs.updateString( 3, "StringCol32" );
crs.insertRow();
crs.moveToCurrentRow();
crs.beforeFirst();
} // end readData
import java.sql.*;
import javax.sql.*;
import sun.jdbc.rowset.*;
// RowSetReader implementation
public void readData(RowSetInternal caller)
throws SQLException {
RowSetMetaDataImpl rsmdi;
rsmdi = new RowSetMetaDataImpl();
rsmdi.setColumnCount(3);
rsmdi.setColumnType(1, Types.VARCHAR);
rsmdi.setColumnType(2, Types.INTEGER);
rsmdi.setColumnType(3, Types.VARCHAR);
crs.setMetaData(rsmdi);
crs.moveToInsertRow();
crs.updateString(1, "StringCol11");
crs.updateInt(2, 1);
crs.updateString(3, "StringCol31");
crs.insertRow();
crs.updateString(1, "StringCol12");
crs.updateInt(2, 2);
crs.updateString(3, "StringCol32");
crs.insertRow();
crs.moveToCurrentRow();
crs.beforeFirst();
} // end readData
if (crs.wasNull() == false) {
System.out.println("sCol1: " + sCol1);
} else {
System.out.println("sCol1 is null");
}
iCol2 = crs.getInt(2);
if (crs.wasNull() == false) {
System.out.println("iCol2: " + iCol2);
} else {
System.out.println("iCol2 is null");
}
sCol3 = crs.getString(3);
if (crs.wasNull() == false) {
System.out.println("sCol3: " +
sCol3 + "\n");
} else {
System.out.println("sCol3 is null\n");
}
} // end showTheData
System.out.println(
"Fetching from RowSet...");
while (crs.next()) {
showTheData(crs);
} // end while next
if (crs.isAfterLast() == true) {
System.out.println(
"We have reached the end");
System.out.println("crs row: " +
crs.getRow());
}
System.out.println(
"And now backwards...");
while (crs.previous()) {
showTheData(crs);
} // end while previous
if (crs.isBeforeFirst() == true) {
System.out.println(
"We have reached the start");
}
crs.first();
if (crs.isFirst() == true) {
System.out.println(
"We have moved to first");
}
System.out.println("crs row: " +
crs.getRow());
if (crs.isBeforeFirst() == false) {
System.out.println(
"We aren't before the first row.");
}
crs.last();
if (crs.isLast() == true) {
System.out.println(
"...and now we have moved to the last");
}
if (crs.isAfterLast() == false) {
System.out.println(
"we aren't after the last.");
}
} // end try
catch (SQLException ex) {
System.err.println("SQLException: " +
ex.getMessage());
}
}
The documentation says "It can be implemented in a wide variety of ways..." and is
pretty vague about what can actually be done. In general, readData() would obtain
or create the data to be loaded, then use CachedRowSet methods to do the actual
loading. This would usually mean inserting rows, so the code would move to the
insert row, set the column data and insert rows. Then the cursor must be set to to
the appropriate position.
For a working code example, see How can I instantiate and load a new
CachedRowSet object from a non-JDBC source?
After instantiation, any of the RowSetMetaData setter methods may be used. The
bare minimum needed for a RowSet to function is to set the Column Count for a row
and the Column Types for each column in the row. For a working code example that
includes a custom RowSetMetaData, See How can I instantiate and load a new
CachedRowSet object from a non-JDBC source?
I don't know about existing drivers, but JavaPro had a good article on writing your
own driver. The example was a driver to access XML files. check it out at JavaPro
December, 2001.
Joe Sam Shirah adds: There are also a number of resources for EDI <----> XML
conversion. We don't make recommendations, but m-e-c eagle is an open source
integrattion suite with such converters you can review. A good search engine will
probably show more.
Where can I find info, frameworks and example source for writing a JDBC
driver?
Location: http://www.jguru.com/faq/view.jsp?EID=809257
Created: Mar 23, 2002
Author: Joe Sam Shirah (http://www.jguru.com/guru/viewbio.jsp?EID=42100)
There a several drivers with source available, like MM.MySQL, SimpleText Database,
FreeTDS, and RmiJdbc. There is at least one free framework, the jxDBCon-Open
Source JDBC driver framework. Any driver writer should also review For Driver
Writers.
Ian Darwin has two classes ( CSV.java and CSVRE.java ) to handle CSV files in his
Java Cookbook, including a way with regular expressions. You can download the code
from his site, probably best to do so from the examples by chapter ( see Chapter 3,
"Strings and Things" ) page. Not a bad idea to buy the book, either.
Comments and alternative answers
Another CSVReader
Author: Roshan Shrestha (http://www.jguru.com/guru/viewbio.jsp?EID=130068),
Mar 26, 2002
Ian Darwin's class parses the file one line at a time. Many times, a field may span
multiple lines. I think a better class is the CSVReader described in
http://www.objectmentor.com/resources/articles/tfd.pdf. As an added bonus, it also
desscribes unit testing with JUnit!
CSV Libraries
Author: Stephen Ostermiller (http://www.jguru.com/guru/viewbio.jsp?EID=576685),
Apr 17, 2002
There are free open source libraries for parsing and printing CSV files available here:
http://ostermiller.org/utils/CSVLexer.html
Re: CSV Libraries
Author: Anjan Bacchu (http://www.jguru.com/guru/viewbio.jsp?EID=283891),
Jun 1, 2004
FYI,
The library from ostermiller.org is licensed with GPL. This prevents usage of this
library in commercial products (unless they are themselves GPL compatible). So,
effectively you cannot use them unless your open source product is also GPL
compatible.
BR,
~A
I am not currently aware of any open source CSV Java parsers that are under
BSD or similar licenses that allow commercial use, but I could be wrong.
Library
Author: davide consonni (http://www.jguru.com/guru/viewbio.jsp?EID=1190420),
Aug 3, 2004
can use csvToSql (http://sourceforge.net/projects/csvtosql/)
Re: Library
Author: azad kans (http://www.jguru.com/guru/viewbio.jsp?EID=1249830), Jun
22, 2005
using
WStringTokenizer
as an implementation of
StringTokenizer(String,deleimter)
is a good implementation and we have used it successfully in our projects .Another
approach is to use
String[] values = String.split(delimiter,no. Of Fields)
.This is effective when you know that each row will have fixed no. of
columns(delimter separated values). The value returned is an array and each field
can be retrieved by
values[i]
which is very handy compared to StringTokenizer.I think this was introduced in 1.4
version of java
CSVFile classes
Author: Fabrizio Fazzino (http://www.jguru.com/guru/viewbio.jsp?EID=1255529),
Jul 28, 2005
I've modified Ian Darwin's classes (preserving the copyright message) and created a
new project on SourceForge:
There are 3 classes, CSVFile (abstract), CSVFileReader (that makes use of Ian's code)
and CSVFileWriter; they are very easy to use since the fields are handles as
Vector<String> variables.
I also made it possible to customize the text qualifier (e.g. can be a tick or backtick
rather than double quote) and the filed separator (e.g. can be a dot rather than a
comma or semicolon).
http://sourceforge.net/projects/pzfilereader
Paul Zepernick
First, let me assure you that something has changed, whether driver, database
column definition, or database update. Even so, you were just lucky in the past.
Some numbers can't be properly represented in binary and using floats/doubles for
fixed decimal values is a classic trap for programmers.
While it doesn't help much at this point, it does highlight the value of proper planning
for database definition and manipulation. The column should be defined as NUMERIC
or DECIMAL, with the expected scale ( decimal point digits ) and get/setBigDecimal()
should be used for retrieval and update.
Here is how I usually handle, 1st multiply the fp by the 10 to the power precision, 2nd
round the number from the previous multiplication 3rd divide by integer 10 to the
power precision
How can I know when I reach the last record in a table, since JDBC doesn't
provide an EOF method?
Location: http://www.jguru.com/faq/view.jsp?EID=809342
Created: Mar 23, 2002
Author: Yusuf Dönmez (http://www.jguru.com/guru/viewbio.jsp?EID=758654)
Question originally posed by Juan José Gonzalez
(http://www.jguru.com/guru/viewbio.jsp?EID=762739
Joe Sam Shirah adds: You can also use isLast() as you are reading the ResultSet.
One thing to keep in mind, though, is that both methods tell you that you have
reached the end of the current ResultSet, not necessarily the end of the table. SQL
and RDBMSes make no guarantees about the order of rows, even from sequential
SELECTs, unless you specifically use ORDER BY. Even then, that doesn't necessarily
tell you the order of data in the table.
If you are really looking for something that tells you the last ( in this case, latest )
data, you probably need something in a key ( or sequence, date/time, etc ) that
provides that information on an ORDER BY basis.
next()
Author: Terry Laurenzo (http://www.jguru.com/guru/viewbio.jsp?EID=706411), Mar
25, 2002
Assuming you mean ResultSet instead of Table, the usual idiom for iterating over a
forward only resultset is:
ResultSet rs=statement.executeQuery(...);
while (rs.next()) {
// Manipulate row here
}
It is the magic of polymorphism, and of Java interface vs. implementation types. Two
objects can both be "instanceof" the same interface type, even though they are not
of the same implementation type.
When you call "getConnection()" on a pooled connection cache manager object, you
get a "logical" connection, something which implements the java.sql.Connection
interface.
But it is not the same implementation type as you would get for your Connection, if
you directly called getConnection() from a (non-pooled/non-cached) datasource.
So the "close()" that you invoke on the "logical" Connection is not the same "close()"
method as the one on the actual underlying "physical" connection hidden by the pool
cache manager.
The close() method of the "logical" connection object, while it satisfies the method
signature of close() in the java.sql.Connection interface, does not actually close the
underlying physical connection.
In addition
Author: Steven Martin (http://www.jguru.com/guru/viewbio.jsp?EID=430104), Apr
15, 2002
Typically a connection pool keeps the active/in-use connections in a hashtable or
other Collection mechanism. I've seen some that use one stack for ready-for-use, one
stack for in-use.
Some connection pools periodically test their connections to see if queries work on
the ready-for-use connections or they may test that on the close() method before
returning to the ready-for-use pool.
Re: A question
Author: Roberto Surdich (http://www.jguru.com/guru/viewbio.jsp?
EID=1028690), Feb 20, 2003
How many active connections should a databade see once a connection pool has
been opened?
I mean, only one connection (the pool itself) at any time, or the number of
"logical" active connections in that moment?
Re[2]: A question
Author: Steven Martin (http://www.jguru.com/guru/viewbio.jsp?
EID=430104), Feb 20, 2003
The database would see the number of active physical connections. It has no
acknowledgement that a connection comes from a raw connection or through a
connection pool. The only difference I've seen is you often need to increase the
statement cache on Oracle since you are reusing the same connection.
What is the best way to generate a universally unique object ID? Do I need
to use an external resource like a file or database, or can I do it all in
memory?
Location: http://www.jguru.com/faq/view.jsp?EID=1030397
Created: Nov 25, 2002 Modified: 2003-02-28 08:01:34.258
Author: Alessandro A. Garbagnati (http://www.jguru.com/guru/viewbio.jsp?
EID=32727) Question originally posed by Andy Brown
(http://www.jguru.com/guru/viewbio.jsp?EID=1027054
[I need to generate unique id's that will be used for node 'ID' attribute values within
XML documents. This id must be unique system-wide. The generator must be
available to a number of servlets that add various node structures to my XML docs as
a service. What is the best way to tackle this? The 'possible' ways I can see:
Keep the maximum ID value in a flat-file where the service would read
it upon start-up and increment it. Upon shutdown or failure, it would
write the latest max id to the file.
Calculate the max id by searching the XML itself. This will be tougher
since XML requires an alpha-numeric value (not strictly numeric).
Use a database (MySQL) with a two-field table where one field is the
incremental counter.
I just have this feeling that none of the above are the most efficient ways of doing
this.
Regards, -Andy]
There is an additional way to do that that doesn't rely on an external file (or
database) like the one you have presentred. If has been presented in the EJB Design
Patterns book, written by Floyd Marinescu, and available in a pdf format for free from
the given link.
The suggested solution is based on the UUID for EJB pattern, that comes out from
this question:
How can universally unique primary keys can be generated in menory without
requiring a database or a singleton?
Without enetring in the specifics (you can fully check out the pattern by reading the
appropriate chapter), the solution is to generate a 32 digit key, encoded in
hexadecimal composed as follows:
1: Unique down to the millisecond. Digits 1-8 are are the hex encoded lower 32 bits
of the System.currentTimeMillis() call.
2: Unique across a cluster. Digits 9-16 are the encoded representation of the 32 bit
integer of the underlying IP address.
3: Unique down to the object in a JVM. Digits 17-24 are the hex representation of
the call to System.identityHashCode(), which is guaranteed to return distinct
integers for distinct objects within a JVM.
- Alex Chaffee]
Comments and alternative answers
Random class
Author: P Manchanda (http://www.jguru.com/guru/viewbio.jsp?EID=344357), Feb
28, 2003
Hi,
Try using the java.util.Random class to generate random numbers that can be used as
IDs.
(BTW,you don't need to use rmi nor know anything about rmi to use these classes)
-Nathan
Making it Faster
Author: Kimbo Mundy (http://www.jguru.com/guru/viewbio.jsp?EID=1120338), Oct
8, 2003
It seems to me that you could speed up the algorithm above by modifying step #4.
Instead of computing the random number every time, just compute it the first time,
and then increment it after that. 2 different JVMs should still just have a 1 in 4 billion
chance of overlap.
Millisecond overlap
Author: Thomas Paré (http://www.jguru.com/guru/viewbio.jsp?EID=1238395), Apr
14, 2005
Thanks for the very interesting pointer on 'Ejb design patterns'. I've read the
implementation details and found something troublesome.
In step 1 : "Unique down to the millisecond. Digits 1-8 are are the hex encoded lower
32 bits of the System.currentTimeMillis() call". Only the lower 32 bits of time are
considered, which makes the uniqueness of that part only valuable for a period of 50
days. Looks like a serious issue.