| Home: www.vipan.com | Vipan Singla | e-mail: vipan@vipan.com |
|
Then, in his/her Visual C++ or Visual Basic program, the user specifies the ODBC datasource name and, if required, username and password. When the program runs, ODBC manager looks at its mapping, gets the underlying database's ODBC driver, name and location, and connects to it using the user-supplied username and password. The user can then issue SQL or database-specific commands either in their program or interactively. The database-specific ODBC driver translates the commands in a database-specific manner, issues those commands on the underlying database, gets results back, retranslates those results in the ODBC format and passes them to the user's program.
sun.jdbc.odbc.JdbcOdbcDriver and it is always included with Java. (Perl's driver is called DBD::ODBC.)
.-. .----------------. .--------------------. .--------.
.-------. | |--|DBD::ODBC Driver|--|Oracle's ODBC Driver|--| Oracle |
| Perl | | | `----------------' `--------------------' `--------'
| script| |A| |D| .----------------------------------------. .--------.
| using |--|P|--|B|--|DBD::Oracle Driver |--| Oracle |
| DBI | |I| |I| `----------------------------------------' `--------'
| API | | |...
|methods| | |... Other drivers
`-------' | |...
`-'
.-. .----------------. .--------------------. .--------.
.-------. | |--|sun.jdbc.odbc |--|Oracle's ODBC Driver|--| Oracle |
| | | | |.JdbcOdbcDriver | | | | |
| Java | | | `----------------' `--------------------' `--------'
| prog | |A| |J| .----------------------------------------. .--------.
| using |--|P|--|D|--|oracle.jdbc.driver.OracleDriver |--| Oracle |
| JDBC | |I| |B| `----------------------------------------' `--------'
| API | |C|...
|methods| | |... Other drivers
`-------' | |...
`-'
sun.jdbc.odbc.JdbcOdbcDriver.
Type 1, 2 and 4 are two-tier (client-server) drivers. There is no application server in the middle.
Using a Type 3 driver, you should never have to change the client code when the back-end database changes.
// package dbtest;
import java.net.URL;
import java.sql.*;
import java.io.PrintWriter;
class TestDatabase
{
public static void main (String args[])
{
try
{
// Load driver's class, inilialize, register with DriverManager
//Class.forName("oracle.jdbc.driver.OracleDriver");
Class.forName("org.gjt.mm.mysql.Driver");
}
catch (ClassNotFoundException e)
{
System.out.println("Unable to load driver class");
return;
}
ResultSet rs = null;
try
{
//
// Call DriverManager's methods (all are static)
//
// To print log on sysout
//DriverManager.setLogStream(System.out); //JDBC 1.x driver
DriverManager.setLogWriter(new PrintWriter(System.out) );
// Connect to database. DriverManager loads each registered driver
// in turn until one can handle the database URL format
//Connection con = DriverManager.getConnection(
// "jdbc:oracle:thin:@host.domain.com:1521:db_name"
// ,"scott","tiger");
Connection con = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/civil2","","");
// Check for warnings generated during connect
areWarnings(con.getWarnings() );
// Get the DatabaseMetaData object to display database info
DatabaseMetaData dmd = con.getMetaData();
// Display overall database info
System.out.println( "\nConnected to " + dmd.getURL()
+ " using driver = " + dmd.getDriverName() + ", version = "
+ dmd.getDriverVersion() );
System.out.println(
"\nVendor product name is " + dmd.getDatabaseProductName()
+ ".\n\tDatabase software version is "
+ dmd.getDatabaseProductVersion()
+ ".\n\tUser name is " + dmd.getUserName()
+ ".\n\tCatalog is called " + dmd.getCatalogTerm()
+ ".\n\tSchema is called " + dmd.getSchemaTerm()
+ ".\n\tProcedure is called " + dmd.getProcedureTerm()
+ "." );
System.out.println(
"\nNumeric functions are:\n" + dmd.getNumericFunctions()
+ "\nString functions are:\n" + dmd.getStringFunctions()
+ "\nDate and Time functions are:\n" + dmd.getTimeDateFunctions()
+ "\nSystem functions are:\n" + dmd.getSystemFunctions()
+ "\n" );
System.out.println(
"Use the escape string \"" + dmd.getSearchStringEscape()
+ "\" to escape wildcard characters." );
System.out.println(
"Is the database in read only mode? Answer: " + dmd.isReadOnly()
+ "" );
// Create a Statement object for submitting SQL commands to driver
Statement stmt = con.createStatement();
String sql;
//DROP TABLE statement
sql = "DROP TABLE users";
try
{
stmt.executeUpdate(sql); //throws SQLExecption if fails
System.out.println("Dropped table \"users\"!");
}
catch(SQLException ex)
{
System.out.println("Could not drop table \"users\"!");
printException(ex);
}
areWarnings(stmt.getWarnings() );
//CREATE TABLE statement
sql = "CREATE TABLE users ("
+ "login VARCHAR(30) PRIMARY KEY NOT NULL,"
+ "password VARCHAR(100),"
+ "first VARCHAR(50),"
+ "middle VARCHAR(50),"
+ "last VARCHAR(50),"
+ "nickname VARCHAR(30),"
+ "email VARCHAR(100),"
+ "city VARCHAR(50),"
+ "state VARCHAR(50),"
+ "country VARCHAR(50),"
+ "zip VARCHAR(30)"
+ ")";
try
{
stmt.executeUpdate(sql); //throws SQLExecption if fails
System.out.println("Created table \"users\"!");
}
catch(SQLException ex)
{
printException(ex);
}
areWarnings(stmt.getWarnings() );
//
// More Database meta data
//
// What type of tables (tables, views etc.)?
rs = dmd.getTableTypes();
printResultSet(rs);
rs.close();
// Any catalogs?
rs = dmd.getCatalogs();
printResultSet(rs);
rs.close();
// What are the defined schemas?
rs = dmd.getSchemas();
printResultSet(rs);
rs.close();
// Good One: What are the defined tables?
// Last arg is an array of strings (table types to get)
//String[] tp = {"TABLE"};
//rs = dmd.getTables(null, null, "addr%", null);
rs = dmd.getTables(null, null, null, null);
printResultSet(rs);
rs.close();
// For a table, what are the defined indexes?
rs = dmd.getIndexInfo(null, null, "users", false, true);
printResultSet(rs);
rs.close();
// For a table, what columns nake up its primary key
rs = dmd.getPrimaryKeys(null, null, "users");
printResultSet(rs);
rs.close();
// Any stored procedures defined?
rs = dmd.getProcedures(null, null, null);
printResultSet(rs);
rs.close();
// The connected user has these table privileges
rs = dmd.getTablePrivileges(null, null, null);
printResultSet(rs);
rs.close();
// The connected user has these column privileges
rs = dmd.getColumnPrivileges(null, null, null, null);
printResultSet(rs);
rs.close();
// Get all the tables with their column definitions
rs = dmd.getColumns(null, null, null, null);
printResultSet(rs);
rs.close();
// INSERT statement (UPDATE is similar)
sql = "INSERT INTO users ("
+ "login, password, nickname, "
+ "last, first, middle, email,"
+ "city, state, country, zip"
+ ") VALUES ("
+ "'superman', 'foo has a meaning', 'S',"
+ "NULL, NULL, NULL, 'iam@your.place',"
+ "NULL, NULL, NULL, '56735-6453'"
+ ")";
stmt.executeUpdate(sql); //throws SQLExecption if fails
areWarnings(stmt.getWarnings() );
// Submit a query, driver hands back a ResultSet object
sql = "SELECT * FROM users WHERE login IS NOT NULL";
rs = stmt.executeQuery(sql); //throws SQLExecption if fails
areWarnings(stmt.getWarnings() );
// Process query results.
printResultSet(rs);
// Tell Java you are done and Java may release memory
rs.close();
// DELETE statement
sql = "DELETE FROM users WHERE login IS NOT NULL";
stmt.executeUpdate(sql); //throws SQLExecption if fails
areWarnings(stmt.getWarnings() );
// Good people close explicitly to release db resources
stmt.close();
con.close();
}
catch(SQLException ex){printException(ex); }
}
//
// Work with ResultSetMetaData
//
private static void printResultSet(ResultSet rs) throws SQLException
{
ResultSetMetaData rsmd = rs.getMetaData();
int numCols = rsmd.getColumnCount();
// Display column titles
System.out.println("-----------------------------------------");
for(int i=1; i<=numCols; i++)
{
if(i > 1) System.out.print(",");
System.out.print(rsmd.getColumnLabel(i));
}
System.out.println("");
System.out.println("-----------------------------------------");
// Display data, fetching until end of the result set
// Calling next moves to first or next row and returns true if success
while(rs.next() )
{
// Each rs after next() contains next rows data
for(int i=1; i<=numCols; i++)
{
if(i > 1) System.out.print(",");
// Almost all SQL types can be cast to a string by JDBC
System.out.print(rs.getString(i));
areWarnings(rs.getWarnings() );
}
System.out.println("");
}
}
//
// Check for warnings
//
private static boolean areWarnings(SQLWarning warn) throws SQLException
{
boolean rc = false;
// Multiple warning smay have been chained to the passed SQLWarning object
// Or, null may have been passed if there were no warnings
if(warn != null)
{
System.out.println("\n *** Warning ***\n");
rc = true;
while(warn != null)
{
System.out.println("SQLState: " + warn.getSQLState() );
System.out.println("Message: " + warn.getMessage() );
System.out.println("Vendor: " + warn.getErrorCode ());
System.out.println ("");
warn = warn.getNextWarning ();
}
}
return rc;
}
//
// Print all chained exceptions
//
public static void printException(SQLException ex)
{
// Multiple error objects may be chained together
System.out.println("\n*** SQLException caught ***\n");
while(ex != null)
{
System.out.println("SQLState: " + ex.getSQLState() );
System.out.println("Message: " + ex.getMessage() );
System.out.println("Vendor: " + ex.getErrorCode ());
ex.printStackTrace(System.out);
System.out.println ("");
// Get next error object in chain. null if none.
ex = ex.getNextException();
}
}
}
Driver, DriverManager, Connection, DatabaseMetaData, Statement/PreparedStatement/PreparedCall, ResultSet, ResultsetMetadata JDBC classes to access databases.
Class.forName("Vendor-driver's class name here");
Connection con = DriverManager.getConnection("jdbc:dbVendorHere:dbNameHere");
Statement stm =con.createStatement();PreparedStatement stm = con.prepareStatement("some sql command here");CallableStatement stm = con.prepareCall("some vendor-specific sql here");ResultSet rs = stm.executeQuery(...); Then work with the "ResultSet" object to retrieve data using:while rs.next()
{
String blah = rs.getString("column_name"|column_position);
int cu = rs.getInt(...);
}int returnVal = stm.executeUpdate(...); Returned integer contains number of rows affected.getWarnings() on "con", "stm" and "rs" objects.
rs.close(); stm.close(); con.close();
DriverManager.getConnection("database url", ...) methods to connect to a database. When the "DriverManager" class is called, it looks at Java's "jdbc.drivers" system property and tries to load the classes specified there.
All JDBC driver classes are coded in a special way such that they all have a static initialization code block (static { ... }). In Java, this code is always executed ONCE when the class is loaded. In this code block, the driver programmer instantiates an object of its "Driver" class and calls the staticDriverManager.registerDriver(driver)method to register this driver with the DriverManager.
Then, the "DriverManager" calls a method on each JDBC driver registered with it to see if they recognize the format of the database URL string. The first driver that does gets the job of connecting to the underlying database.
There are two ways to do it.
System.setProperty("jdbc.drivers", "oracle.jdbc.driver.OracleDriver");. To load multiple drivers, separate their class names with colons.
You may run into problems when distributing your application to different computers. Their security policy may not allow messing with the system properties.
Class.forName("any_class_name_with_pkg_path") method. It is kind of less apparent at first but is THE STANDARD WAY to load a JDBC driver class.
This method looks for the specified class everywhere in the classpath. If it finds the class, it loads the class AND runs its static initialization code block (just what we want).
This methodology uses one of the many very useful methods of the versatile "Class" class. This class has several other USEFUL (but non-static) methods such as
getName(), getPackage(), getResource(), gerResourceAsStream(), isArray(), getSuperClass(), isInstance(), newInstance(). Use someobject.getClass() to first get the "Class" object associated with your object. Then, run these methods on that "Class" object.
As we know now, a driver's initialization code instantiates an object of itself and registers it with the "DriverManager" class by calling its static "registerDriver()" method.
get|setLogWriter() will let you look at logs of JDBC calls. Default is "null" which means no logging info is shown. Use println() to write your own text to the log stream. The methods get|setLoginTimeout() will let you specify how long to wait to connect to a database before timing out and throwing an exception.
Specify the database URL string as "jdbc:subprotocol:subname". You may need to specify "user" and "password" properties or arguments to connect to a controlled database. If you are accessing a database over the internet, the format may be jdbc:subprotocol://wombat:356/fred but check the JDBC driver's documentation.
Connection con =
DriverManager.getConnection("jdbc:odbc:my_database_name");
Connection con = DriverManager.getConnection(
"jdbc:odbc:my_database_name", "scott", "tiger");
Properties p = new Properties();
p.setProperty("user", "scott");
p.setProperty("password", "tiger");
p.setProperty("server", "DEMO");
p.setProperty("database", "mydb");
Connection con = DriverManager.getConnection(
"jdbc:cloudscape:E:\\student\\SimpleDB", p);
Statement stm =con.createStatement();
PreparedStatement stm = con.prepareStatement("some sql command here");
Statement stm = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
CallableStatement stm = con.prepareCall("some vendor-specific sql here");
getWarnings(), clearWarnings() - Always check!
getMetaData() - Returns "DatabaseMetaData" object
close(), isClosed() - Don't forget to close the connection at the end.
setReadOnly(boolean readOnly), isReadOnly()
get|setCatalog()
con.get|setTransactionIsolation() - one of TRANSACTION_READ_COMMITTED, TRANSACTION_READ_UNCOMMITTED, TRANSACTION_REPEATABLE_READ, TRANSACTION_SERIALIZABLE (First check if transactions are supported using "DatabaseMetaData" object's "supportsTransactions()" method)
get|setAutoCommit(), commit(), rollback() - Transactions (First check if transactions are supported using "DatabaseMetaData" object's "supportsTransactions()" method)
getURL(), getDriverName(), getDriverVersion(), getDatabaseProductName(), getDatabaseProductVersion(), isReadOnly()
getUserName() - To check assigned user name
getSchemas(), getCatalogs(), getTables(), getColumns(), getTableTypes(), getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern), getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern), getPrimaryKeys(), getTypesInfo()
getNumericFunctions(), getStringFunctions(), getTimeDateFunctions(), getSystemFunctions(), supportsStoredProcedures()
getMaxBinaryLiteralLength(), getMaxCharLiteralLength(), getMaxConnections(), getMaxRowSize(), doesMaxRowSizeIncludeBlobs(), getMaxStatementLength()
supportsTransactions(), getDefaultTransactionIsolation(), supportsTransactionIsolationLevel(int level)
getCatalogTerm(), getSchemaTerm(), getProcedureTerm() - Vendor's term
DatabaseMetaData dbmd = con.getMetaData();
String[] tp = {"TABLE"};
// "catalog", schemaPattern", tableNamePattern", table types array of strings
// "tables" contains TABLE_CAT, TABLE_SCHEM, TABLE_NAME,
// TABLE_TYPE, REMARKS columns
ResultSet tables = dbmd.getTables(null, null, null, tp);
// "catalog", schemaPattern", tableNamePattern", "columnNamePattern"
// "cols" contains at least TABLE_CAT, TABLE_SCHEM, TABLE_NAME,
// COLUMN_NAME, DATA_TYPE, COLUMN_SIZE (among others)
ResultSet cols = dbmd.getColumns(null, null, "%TABLE%", null);
Driver dr = DriverManager.getDriver("jdbc:odbc:my_databse_name"); Then call dr.getMajorVersion(), dr.getMinorVersion() to get its version.
PreparedStatement ps
= con.prepareStatement("UPDATE test SET value = ? WHERE id = ?");
//ps.clearParameters(); //start fresh
ps.setString(1, "Hi");
for (int i = 0; i < 10; i++)
{
pstmt.setInt(2, i);
int rowCount = ps.executeUpdate();
}
java.sql.Types when using SQL INSERT, UPDATE, SELECT and DELETE.
PreparedStatement.setBytes() for handling BINARY, VARBINARY and LONGVARBINARY.
{fn concat("Hot", "Java")} SQL escape sequence. Similarly, use this to call other popular conversion functions in a DBMS-independent manner.
{d 'yyyy-mm-dd'}, {t 'hh:mm:ss'}, and {ts 'yyyy-mm-dd hh:mm:ss.fffffffff'} in your SQL statement string to specify dates and times in a DBMS-independent manner.
String sql = "INSERT INTO test VALUES ({d '1998-09-14'})";
java.sql.Date dt = java.sql.Date.valueOf("1998-12-25") to get a "Date" object from a string.
java.sql.Time tm = java.sql.Time.valueOf("22:34:59") to get a "Time" object from a string.
java.sql.Timestamp stmp = java.sql.Timestamp.valueOf("1998-12-25 22:34:59.234567876") to get a "Time" object from a string. Fractional seconds can be omitted.
//To insert a file as a table cell java.io.File file = new java.io.File("/tmp/data"); int fileLength = file.length(); java.io.InputStream fin = new java.io.FileInputStream(file); java.sql.PreparedStatement pstmt = con.prepareStatement( "UPDATE Table5 SET stuff = ? WHERE index = 4"); pstmt.setBinaryStream (1, fin, fileLength); pstmt.executeUpdate(); //ps.setBlob(1, img); // "img" is a Java Blob object // To retrieve large character objects Statement st = con.createStatement(); ResultSet rs = st.executeQuery("SELECT id,value FROM test"); BufferedReader br; String input; while(rs.next() ) { br = new BufferedReader(new InputStreamReader(rs.getAsciiStream(2) )); while( (input=br.readLine() ) != null ) System.out.println(input); }
java.io.File file = new java.io.File("/tmp/data");
int fileLength = file.length();
java.io.InputStream fin = new java.io.FileInputStream(file);
java.sql.PreparedStatement pstmt = con.prepareStatement(
"UPDATE Table5 SET stuff = ? WHERE index = 4");
pstmt.setBinaryStream (1, fin, fileLength);
pstmt.executeUpdate();
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("SELECT image FROM album WHERE id = " +
request.getParameter("id"));
BufferedInputStream bis;
while(rs.next() )
{
bis = new BufferedInputStream(rs.getBinaryStream("image") );
byte[] buf = new byte[4 * 1024]; //4K buffer
int len;
while( (len = bis.read(buf, 0, buf.length) ) != -1 )
{
out.write(buf, 0, len );
}
}
CallableStatement call = con.prepareCall("{call procedure_name}"); ResultSet rs = call.executeQuery(); to call stored procedures. CallableStatement is a must only if the stored procedure has OUT and IN OUT parameters. For only IN parameters, you can use PreparedStatement or Statement (and still retrieve any result set, just not OUTPUT values).
CallableStatement call = con.prepareCall("{? = call procedure_name(?, ?)}");
call.registerOutParameter(1, Types.INTEGER);
call.registerOutParameter(3, Types.INTEGER); //Both IN and OUT parameter
call.setInt(2, 3);
call.setInt(3, 1567); //Both IN and OUT parameter
ResultSet rs = call.executeQuery();
int inout = rs.getInt(3);
CREATE OR REPLACE PROCEDURE sp_interest (id IN INTEGER bal IN OUT FLOAT) IS BEGIN SELECT balance INTO bal FROM accounts WHERE account_id = id; bal := bal + bal * 0.03; UPDATE accounts SET balance = bal WHERE account_id = id; END;
stm.execute(...) returns true if there is a result ("ResultSet" or int). Then call stm.getResultSet() or getUpdateCount() to retrieve the actual result. Rarely necessary to use.
stm.addBatch(), stm.executeBatch(), stm.clearBatch() methods. To access multiple resultsets, first call stm.getResultSet() to access the first "ResultSet" object. Work with its contents. Then, call stm.getMoreResults() to see if there are more result sets waiting. If true, next call to stm.getResultSet() will actually return the next "ResultSet" object.
(!getMoreResults() && (getUpdateCount() == -1)
getUpdateCount() for non-resultset SQL statements such as INSERT, UPDATE, DELETE. (Returns -1 if you call it on a resultset-returning statement or if there are no more results).
get|setMaxFieldSize() in bytes - Maximum bytes to retrieve from the database, rest are silently discarded. Applies to BINARY, VARBINARY, LONGVARBINARY, CHAR, VARCHAR, and LONGVARCHAR columns. Use at least 256. 0 means unlimited.
get|setMaxRows() - Max rows to return from a SQL call, rest are silently discarded (SQL COUNT() may help if expecting larger number of rows). 0 means unlimited.
get|setQueryTimeout() in seconds - 0 means unlimited.
getWarnings(), clearWarnings() for database-issued warnings which are not errors.
| SQL TYPE | Java Class | ResultSet "getXXX" Method | Remarks |
|---|---|---|---|
| CHAR | String | rs.getString() | Text (Fixed length storage upto 254 characters) |
| VARCHAR | String | rs.getString() | Text (Variable length storage upto 254 characters) |
| SMALLINT | short | rs.getShort() | -32767 to +32767. Don't use TINYINT or BIT. |
| INTEGER or INT | int | rs.getInt() | -2147483647 to +2147483647 |
| BIGINT | long | rs.getLong() | Use only if already in database |
| REAL | float | rs.getFloat() | Upto 7 decimal places |
| FLOAT, DOUBLE PRECISION or DOUBLE | double | rs.getDouble() | Upto 15 decimal places |
| NUMERIC, DECIMAL | java.math.BigDecimal | rs.getBigDecimal() | e.g. 92375.456 (Precision = 8; Scale = 3). NUMERIC always has fixed scale, DECIMAL has variable scale beyond specified |
| DATE | java.sql.Date | rs.getDate() | yyyy-mm-dd, support varies |
| TIME | java.sql.Time | rs.getTime() | hh:mm:ss, support varies |
| TIMESTAMP | java.sql.Timestamp | rs.getTimestamp() | Allows nano-seconds. Maps to DATE in Oracle, DATETIME in SQL Server and Informix, TIMESTAMP in DB2 and Sybase |
| BOOLEAN, BIT | boolean | rs.getBoolean() | True or False |
| BINARY, VARBINARY | byte[] | getBytes() | Raw binary data upto 254 bytes |
| BLOB, LONGVARBINARY | Blob, byte[] | getBinaryStream(), getBlob() | Raw binary data upto 2GB (images, serialized objects) |
| CLOB, LONGVARCHAR | Clob, String | rs.AsciiStream(), getCharacterStream(), getClob() | Text up to 2GB. getUnicodeStream() is deprecated. |

getString(...) method. The getObject(...) method can retrive ALL types.
wasNull(), getMetaData(), next(), previous(), first(), last(), beforeFirst(), afterLast(), isFirst(), isLast(), getRow()
rs.wasNull() to check if it was SQL NULL.
rs.getMetaData returns a "ResultSetMetaData" object. Sample usage:
ResultSetMetaData rsmd = rs.getMetaData();
System.out.println(rsmd.getCatalogName(1) );
System.out.println(rsmd.getTableName(1) );
int n = rsmd.getColumnCount();
for (int i = 1; i <= n; i++)
{
// if (rsmd.getColumnType(i) == java.sql.Types.CHAR)
// {
System.out.println(rsmd.getColumnName(i) );
System.out.println(rsmd.getColumnLabel(i) ); //The text after SQL AS
System.out.println(rsmd.getColumnTypeName(i) ); //db-specific SQL type
System.out.println(rsmd.getColumnDisplaySize(i) );
System.out.println(rsmd.getColumnClassname(i) ); //Java equiv.
// }
}
getPrecision(), getScale(), isSigned(), isCurrency(), isNullable(), isWritable(), isAutoIncrement(), isCaseSensitive()
If inserts are to be performed on the result set, an SQL query should satisfy conditions one through three plus the following three additional conditions:
moveToInsertRow(), then any number of updateXXX() methods to set column values, then insertRow() to write the row to the underlying database. All columns must be given a value, even if it is SQL NULL using updateNull().
updateXXX() methods to update the column values within the resultset. Then call updateRow() to write to the underlying database.
deleteRow()
rowDeleted(), rowUpdated(), rowInserted() immediately after deleting, updating or inserting a row.
getMessage(), getSQLState(), getErrorCode(). Always check for chained SQL exceptions using getNextException() (returns "null" if no more). Tack on your own SQL exception using setNextException().
rs.getWarnings() which returns "null" if no warnings, otherwise the first warning in possible chain of warnings. Use sql_warning.getNextWarning() to get the next warning in chain or "null" if none.
Properties type3p = new Properties();
// Specify the URL of the Weblogic server to connect to, including port
type3p.setProperty("weblogic.t3.serverURL", "t3://localhost:7001");
type3p.setProperty("weblogic.t3.connectionPoolID", "phoneBook");
Class.forName("weblogic.jdbc.t3.Driver");
Connection con = DriverManager.getConnection("jdbc:weblogic:t3", t3props);
Statement stm = con.createStatement();
//Issue SQL commands as usual
# Create "phoneBook" connection pool. Only required parameters are shown here.
weblogic.jdbc.connectionPool.phoneBook=\
url=jdbc20:weblogic:oracle,\
driver=weblogic.jdbc20.oci.Driver,\
maxCapacity=10,\
capacityIncrement=1,\
props=user=SCOTT;password=tiger;server=DEMO
# Must also add an Access Control List for the connection pool
weblogic.allow.reserve.weblogic.jdbc.connectionPool.phoneBook=everyone
Note that the application server connects to the underlying database using a Type 2 or 4 driver, generally.
This may be helpful in switching quickly to a backup database after the main database crash, for example.
try
{
con.setAutoCommit(false);
Statement stm = con.createStatement();
stm.executeUpdate("UPDATE ...");
stm.executeUpdate("UPDATE ...");
stm.executeUpdate("UPDATE ...");
...
con.commit();
}
catch(Exception e)
{
con.rollback();
}
con.get|setTransactionIsolation(). It can be one of TRANSACTION_READ_COMMITTED, TRANSACTION_READ_UNCOMMITTED, TRANSACTION_REPEATABLE_READ, TRANSACTION_SERIALIZABLE
jdbc:weblogic:t3 driver in a client-side class file. Never use this driver in a server-side class file. It always makes calls over the TCP/IP.
Here "t3" is the name of Type 3 driver that connects to the Weblogic server (no relations to Weblogic's "t3" communications protocol).
jdbc.weblogic.oracle or Oracle-provided JDBC driver) or Weblogic's "POOL" driver in a server-side class file. All of these drivers support connection pooling.
java utils.dbping ORACLE bill secret DEMODATABASE
java utils.t3dbping http://localhost:7001 scott tiger
DEMODATABASE weblogic.jdbc.oci.Driver jdbc:weblogic:oracle
weblogic.jdbc.connectionPool.phoneBook=\
url=jdbc20:weblogic:oracle,\
driver=weblogic.jdbc20.oci.Driver,\
maxCapacity=10,\
capacityIncrement=1,\
props=user=SCOTT;password=tiger;server=garbage
#Must also add an ACL for the connection pool
weblogic.allow.reserve.weblogic.jdbc.connectionPool.phoneBook=everyone
weblogic.jdbc.DataSource.gold=phoneBook # Or, to support transactions (JTS) #weblogic.jdbc.TXDataSource.gold=phoneBook
javax.sql.DataSource which knows about the "phoneBook" connection pool. The server will then place the "DataSource" object in Weblogic's JNDI dirctory under the name "gold".
javax.sql.DataSource class (This works with any JDBC 2.0 compliant driver):
Properties env = new Properties();
env.setProperty("java.naming.factory.initial",
"weblogic.jndi.WLInitialContextFactory");
env.setProperty("java.naming.provider.url", "http://localhost:7001");
Context ic = new InitialContext(env);
javax.sql.DataSource ds = (javax.sql.DataSource) ic.lookup("gold");
Connection con = ds.getConnection();
// Use "con" as usualCREATE TABLE test ( id INTEGER NOT NULL PRIMARY KEY, value CHAR(25) DEFAULT 'N/A' , remarks VARCHAR(250) UNIQUE UNIQUE(id, value) ); CREATE TABLE test2 ( id INTEGER NOT NULL, value CHAR(25) NOT NULL, remarks VARCHAR(250) PRIMARY KEY (id, value) ); ALTER TABLE test2 ADD last_mod DATE, ADD user CHAR(8) MODIFY value VARCHAR(35); DROP TABLE test2; DROP INDEX ix_t; DROP VIEW v_test; CREATE VIEW v_test AS SELECT id, DISTINCT value FROM test; CREATE UNIQUE INDEX id_test ON test (id); CREATE INDEX i_test ON test (id, value);
INSERT INTO test (id, value) VALUES (23, 'Good Luck'); INSERT INTO test VALUES (2, NULL); INSERT INTO test2 (key, val) SELECT id, val FROM test; INSERT INTO test (last_mod) VALUES (CURRENT_TIMESTAMP);
SELECT * FROM test; SELECT id, DISTINCT value FROM v_test; SELECT id AS Identification, value AS 'Value' FROM test WHERE value = '3pix'; SELECT * FROM test WHERE value LIKE 'href=\'_%' {escape '\'}; SELECT id AS Identification, value AS 'Value' FROM test WHERE value = '3pix' ORDER BY value DESC, id DESC; SELECT id, value FROM test GROUP BY value HAVING id > 3; SELECT id AS Identification, value AS 'Value' FROM test WHERE id = 4 AND value IS NOT NULL; SELECT one.id AS Identification, two.value AS 'Value' FROM test one, junk two WHERE one.id = two.id; SELECT * FROM test WHERE id IN (3, 9, 13); SELECT * FROM test WHERE id IN SELECT id FROM test2; SELECT * FROM test WHERE id BETWEEN 4 AND 100; SELECT COUNT(*) FROM test; SELECT AVG(id) FROM test; SELECT MAX(value) FROM test; SELECT MIN(value) FROM test; SELECT SUM(id) FROM test; SELECT * FROM test WHERE last_mod = CURRENT_DATE; SELECT TRIM(BOTH ' ' FROM value) FROM test; SELECT SUBSTRING(value FROM 3 FOR 2) FROM test;
You can also use NOT LIKE, IS NOT NULL, NOT IN, BETWEEN, NOT BETWEEN, CURRENT_TIME, LOWER(...), TRIM(LEADING|TRAILING|BOTH '-' FROM value).
UPDATE test SET value = 'Tickle' WHERE id = 3;
UPDATE test SET value = UPPER(value);
DELETE FROM test WHERE id = 45;
| Function | Purpose |
|---|---|
| Date and Time Functions | |
CURDATE |
Returns the current date |
CURTIME |
Returns the current time |
CURRENT_DATE |
Returns the current date |
CURRENT_TIME(time_precision) |
Returns the current time |
CURRENT_TIMESTAMP(timestamp-precision) |
Returns the local date and local time as a timestamp |
DAYNAME(date) |
Returns a string with the day of the week |
DAYOFMONTH(date) |
Returns the day of the month, between 1 and 31 |
DAYOFWEEK(date) |
Returns the day of the week as an integer between 1 and 7 |
DAYOFYEAR(date) |
Returns the day of the year between 1 and 366 |
EXTRACT(extract-field FROM extract-source) |
Returns YEAR, MONTH, DAY, HOUR, MINUTE, or SECOND field of an extract-source (datetime or interval expression) |
HOUR(time_exp) |
Returns the hour as an integer between 0 and 23 |
MINUTE(time_exp) |
Returns the minute as an integer between 0 and 59 |
MONTH(date) |
Returns the month as an integer between 1 and 12 |
MONTHNAME(date) |
Returns the month name as a string |
NOW |
Returns the current date and time as a timestamp |
QUARTER(date) |
Returns the quarter as an integer between 1 and 4 |
SECOND(time_exp) |
Returns the second as an integer between 0 and 59 |
TIMESTAMPADD (interval,integer_exp,timestamp_exp) |
Calculates a timestamp by adding integer_exp intervals of type interval to timestamp_exp. |
TIMESTAMPDIFF (interval,timestamp_exp1,timestamp_exp2) |
Returns the integer number of intervals by which timestamp_exp2 is greater than timestamp_exp1. |
WEEK(date) |
Returns the week of the year as an integer between 1 and 53 |
YEAR(date) |
Returns the year as an integer in a data source-dependent range |
| String Functions (str = string expression) | |
ASCII(str) |
Returns the integer equivalent of string str |
CHAR(code) |
Returns the character equivalent of code |
BIT_LENGTH(str) |
Returns the length in bits of a string |
CHAR_LENGTH(str) |
Returns the length of a string expression |
CHARACTER_LENGTH(str) |
Returns the length of a string expression |
CONCAT(str1,str2) |
Concatenates string 2 to string 1 |
DIFFERENCE(str1,str2) |
Returns the SOUNDEX difference between strings |
INSERT(str1,start,length,str2) |
Merges strings by deleting length characters from str1 and inserting str2 |
LCASE(str) |
Converts string str to lowercase |
LEFT(str,count) |
Returns leftmost count characters of string str |
LENGTH(str) |
Returns the number of characters in str |
LOCATE(str1,str2[,start]) |
Returns starting position of str1 within str2 |
LTRIM(str) |
Removes the leading spaces of str |
OCTET_LENGTH(str) |
Returns smallest integer byte length not less than the bit length divided by 8 |
POSITION(char_exp IN char_exp) |
Returns the position of the first character expression in the second |
REPEAT(str,count) |
Returns characters of str repeated count times |
REPLACE(str1,str2,str3) |
Replaces occurences of str2 in str1 with str3 |
RIGHT(str,count) |
Replaces the rightmost count characters of string str |
RTRIM(str) |
Removes trailing spaces in str |
SOUNDEX(str) |
Returns phonetic equivalent of str |
SPACE(count) |
Returns a string str of count spaces |
SUBSTRING(str,start,length) |
Derives substring from str beginning at start |
UCASE(str) |
Converts str to upper case |
| Number Functions | |
ABS(numeric) |
Returns the absolute value of numeric |
ACOS(float) |
Returns the arccosine of float as an angle expressed in radians. |
ASIN(float) |
Returns the arcsine of float |
ATAN(float) |
Returns the arctangent of float |
ATAN2(float1, float2) |
Returns the arctangent of float1 and float2 as an angle expressed in radians |
CEILING (numeric) |
Returns the smallest integer greater than or equal to numeric |
COS(float) |
Returns the cosine of float |
COT(float) |
Returns the cotangent of float |
DEGREES(numeric) |
Converts numeric radians to degrees |
EXP(float) |
Returns the exponential value of float |
FLOOR(numeric) |
Returns the largest integer less than or equal to numeric |
LOG(float) |
Returns the natural logarithm of float |
LOG10(float) |
Returns the base 10 log of float |
MOD(integer1,integer2) |
Returns the modulus of integer1 divided by integer2 |
PI |
Returns pi as a floating point number |
POWER(numeric,integer) |
Returns the value of numeric raised to the power of integer |
RADIANS(numeric) |
Returns the number of radians converted from numeric |
RAND(integer) |
Returns a random floating number using integer as the optional seed value |
ROUND(numeric,integer) |
Returns numeric rounded to integer |
SIGN(numeric) |
Returns the sign of numeric |
SIN(float) |
Returns the sine of float |
SQRT(float) |
Returns the square root of float |
TAN(float) |
Returns the tangent of float |
TRUNCATE(numeric,integer) |
Returns numeric truncated to integer |
Keywords to express valid TIMESTAMPADD interval or TIMESTAMPDIFF interval values; fractional seconds are expressed in billionths of a second.
SQL_TSI_FRAC_SECOND SQL_TSI_SECOND SQL_TSI_MINUTE SQL_TSI_HOUR SQL_TSI_DAY SQL_TSI_WEEK SQL_TSI_MONTH SQL_TSI_QUARTER SQL_TSI_YEAR
//This is the cache implemented as an in-memory hashtable
private java.util.Hashtable s2c;
private ResultSetMetaData md;
public String getString(String columnName) throws SQLException
{
return (getString(findColumn(columnName)));
}
public synchronized int findColumn(String columnName) throws SQLException
{
// Make a mapping cache if we don't already have one.
if (md == null)
{
md = getMetaData();
s2c = new java.util.Hashtable();
}
// Look for the mapping in our cache.
Integer x = (Integer)s2c.get(columnName);
if (x != null)
{
return (x.intValue());
}
// OK, we'll have to use metadata.
for (int i = 1; i < md.getColumnCount(); i++)
{
if (md.getColumnName(i).equalsIgnoreCase(columnName))
{
// Success! Add an entry to the cache.
s2c.put(columnName, new Integer(i));
return (i);
}
}
// If we reach here w/o returning, then column name was not found
throw new SQLException("Column name not found", "S0022");
}
The material in this document is my notes on using JDBC. It is not meant to be a tutorial, introduction or cover-all. It is intended to provide some boiler-plate code-snippets or refresh my memory on some concepts.