BEA Logo BEA WebLogic Server Release 5.0

  Corporate Info  |  News  |  Solutions  |  Products  |  Partners  |  Services  |  Events  |  Download  |  How To Buy

Using the jdbcKona Type 2 JDBC drivers

I. Overview of jdbcKona
jdbcKona support
jdbcKona shared libraries and dynamic link libraries
JavaSoft JDBC classes and jdbcKona drivers
What you will need to connect to a DBMS with jdbcKona
How to connect to a DBMS with jdbcKona
Codeset support in jdbcKona drivers
Using a jdbcKona driver with Symantec Cafe
Closing Statements and other data objects
Working with ResultSets
Support for JDBC Extended SQL (2.5)

II. The JDBC API, with WebLogic extensions

III. Implementing with the jdbcKona drivers
Importing packages
Setting properties for connecting
Connecting to the DBMS
Making a simple SQL query
Inserting, updating, and deleting records
Creating and using stored procedures and functions
Disconnecting and closing objects
Code example

IV. Change history

Other related documents
Installing WebLogic (non-Windows)
Installing WebLogic (Windows)
Developers Guides
API Reference Manual
Performance tuning your JDBC application
Troubleshooting JDBC hangs and SEGVs
Choosing a Java Database Connectivity driver
Using jdbcKona/Oracle
Using jdbcKona/Sybase and jdbcKona/MSSQLServer
Using jdbcKona/MSSQLServer4
Using jdbcKona/Informix4
Using WebLogic JDBC
Using the jdbcKona Type 2 JDBC drivers
Using dbKona
Glossary
Code examples
jdbcKona examples
Examples for jdbcKona/Oracle

I. Overview of jdbcKona

This document covers general guidelines for using the WebLogic jdbcKona JDBC drivers and some vendor-specific notes on each driver. We have also included a brief implementation guide with examples of simple jdbcKona applications to help you get started.

WebLogic jdbcKona drivers include both Type 2 and Type 4 JDBC drivers. The Type 2 drivers (for Oracle, Sybase, and Microsoft SQL Server) employ client libraries supplied by the database vendors. The Type 4 drivers (for Informix and Microsoft SQL Server) are 100% pure Java; they connect to the database server at the wire level without vendor-supplied client libraries.

You can use the Type 2 and Type 4 JDBC drivers with WebLogic JDBC, WebLogic's multitier JDBC implementation. Refer to the Developers Guide, Using WebLogic JDBC, for more information.

Top of this section

jdbcKona support

For details on the platforms, operating systems, JVMs, DBMS versions, and client libraries supported by jdbcKona see Platform support for jdbcKona JDBC drivers.

Top of this section

jdbcKona Type 2 shared libraries and dynamic link libraries

jdbcKona Type 2 drivers call native libraries that are supplied with the JDBC driver. The UNIX libraries (shared object files) are in the WebLogic distribution kit in the directory weblogic/lib. The Windows .dlls are included in the distribution kit in the directory weblogic\bin.

The following table lists the names of the driver files included with WebLogic release 4.5.

JDBC driver Windows NT/95 Windows NT/95
(using Microsoft SDK for Java)
UNIX
jdbcKona/
Oracle
weblogicoci34.dll
weblogicoci34_g.dll
weblogicmsoci34.dll
weblogicmsoci34_g.dll
libweblogicoci34.so
jdbcKona/
Sybase
weblogicsyb26.dll
weblogicsyb26_g.dll
weblogicmssyb26.dll
weblogicmssyb26_g.dll
libweblogicsyb26.so
jdbcKona/
MSSQLServer
weblogicsql26.dll
weblogicsql26_g.dll
weblogicmssql26.dll
weblogicmssql26_g.dll
 

The Windows .dll files ending with "_g" are linked with javai_g.dll for compatibility with debuggers such as the Visual Cafe debugger. The HP-UX shared library files have an .sl extension.

Top of this section

JavaSoft JDBC classes and jdbcKona drivers

The jdbcKona products implement the most recent JavaSoft JDBC API specification, which is a set of interfaces. The distribution that you downloaded contains the latest version of the JDBC API class files. Please make sure you do not have any earlier versions of JDBC in your CLASSPATH.

We do not generate classdocs (API reference pages) for WebLogic implementations of the JDBC spec; however, we do provide copies of JavaSoft's classdocs online with our other API reference materials so that you have access to all the documentation in a single place. JavaSoft's classdocs and other materials are also freely available by download at JavaSoft.

Top of this section

What you will need to connect to a DBMS with jdbcKona

  • A database server (Oracle, Sybase, Informix, or Microsoft SQL Server)
  • The jdbcKona JDBC driver for your database
  • A Java JDK

For Type 2 drivers, you will also need the vendor-supplied libraries for the database.

See jdbcKona support for a table that lists the supported versions of each of these components.

Top of this section

How to connect to a DBMS with jdbcKona

In general, connecting happens in two steps:

  1. Load the proper JDBC driver.

    The most efficient way to load the JDBC driver is to call Class.forName().newInstance() with the name of the driver class. This loads and registers the JDBC driver, as in this example for jdbcKona/Oracle:

      Class.forName("weblogic.jdbc.oci.Driver").newInstance();
  2. Obtain a JDBC connection.

    You request a JDBC connection by calling the DriverManager.getConnection() method, which takes as its parameters the URL of the driver and other information about the connection, such as the location of the database and login information.

Note that both steps describe the JDBC driver, but in different formats. The full pathname for the driver is period-separated while the URL is colon-separated. The following table lists the class paths and URLs for the WebLogic jdbcKona drivers.

jdbcKona
driver
Driver type Class pathname Class URL
jdbcKona/
Oracle
Type 2 weblogic.jdbc.oci.Driver jdbc:weblogic:oci
jdbcKona/
Sybase
Type 2 weblogic.jdbc.dblib.Driver jdbc:weblogic:sybase
jdbcKona/
MSSQL
Server
Type 2 weblogic.jdbc.dblib.Driver jdbc:weblogic:mssqlserver
jdbcKona/
MSSQL
Server4
Type 4 weblogic.jdbc.mssqlserver4.Driver jdbc:weblogic:mssqlserver4
jdbcKona/
Informix4
Type 4 weblogic.jdbc.informix4.Driver jdbc:weblogic:informix4

Additional information required to form a database connection varies by DBMS vendor and whether the jdbcKona driver is of Type 2 or Type 4. There are also a variety of methods for specifying this information in your program. Several variations on the two-step connection pattern are described here. For full details on the Type 2 jdbcKona drivers, check out the Developers Guides Using jdbcKona/Sybase and jdbcKona/MSSQLServer, and Using jdbcKona/Oracle. For information on using the Type 4 drivers, see Using jdbcKona/MSSQLServer4 and Using jdbcKona/Informix4. For a complete code example, check the beginning sections in the Overview and implementation guide.

Method 1

The simplest connection method is to include the name of database in the URL of the driver, and pass the database user name and password as additional arguments to the DriverManager.getConnection() method, as in this jdbcKona/Oracle example:
  Class.forName
      ("weblogic.jdbc.oci.Driver").newInstance();
  Connection conn =
    DriverManager.getConnection
      ("jdbc:weblogic:oracle:DEMO",
        "scott", "tiger");
where DEMO is the V2 alias of an Oracle database. Note that calling Class.forName().newInstance() properly loads and registers the JDBC driver.

The Type 4 drivers for Informix and Microsoft SQL Server do not have access to the logical names defined for database servers. For these drivers, you specify the computer running the DBMS and the TCP/IP port the server is listening on. This jdbcKona/Informix4 example shows how to put this information into the URL:

  Class.forName
      ("weblogic.jdbc.informix4.Driver".newInstance();
  Connection conn = 
    DriverManager.getConnection
        ("jdbc:weblogic:informix4:bigbox:1439", "scott",
	"tiger");
where bigbox is the name of the computer running the Informix server, and 1439 is its TCP/IP port number.

Method 2

You can pass a java.util.Properties object with connection parameters as the second argument to the DriverManager.getConnection() method. This example shows how to connect to a Sybase database ("mydb") on the server host "mach2":
  Properties props = new Properties();
  props.put("user",         "sa");
  props.put("password",     "");
  props.put("server",       "mach2");
  props.put("db",           "mydb");

  Class.forName
     ("weblogic.jdbc.dblib.Driver").newInstance();
  Connection conn =
    DriverManager.getConnection("jdbc:weblogic:sybase",
                                props);
Here is a similar example that shows how to connect to a Microsoft SQL Server database using the Type 2 driver, jdbcKona/MSSQLServer. The only difference is the URL for the driver; for Microsoft SQL Server, it is "jdbc:weblogic:mssqlserver".
  Properties props = new Properties();
  props.put("user",         "sa");
  props.put("password",     "");
  props.put("server",       "mach2");
  props.put("db",           "mydb");

  Class.forName
     ("weblogic.jdbc.dblib.Driver").newInstance();
  Connection conn = DriverManager.getConnection
        ("jdbc:weblogic:mssqlserver",props);

If you do not supply a server name ("mach2" in the example above), the Type 2 drivers look for an environment variable (DSQUERY in the case of Sybase and Microsoft, ORACLE_SID in the case of Oracle). You may also choose to add the database and server name to the URL, using this format:

  "jdbc:weblogic:sybase:mydb@mach2"

Method 3

If you prefer, you can load the JDBC driver from the command line with the command:

 $ java -Djdbc.drivers=weblogic.jdbc.dblib.Driver classname

where classname is the name of the application you want to run; and then use a Properties object to set parameters necessary for connecting to the DBMS. In this case, you will not need to call the Class.forName().newInstance() method, as shown here in this jdbcKona/MSSQLServer example:

  Properties props = new Properties();
  props.put("user",         "sa");
  props.put("password",     "");
  props.put("server",       "mach2");
  props.put("db",           "mydb");

  Connection conn = DriverManager.getConnection
   ("jdbc:weblogic:mssqlserver", props);

General notes

Always call the Connection.close() method to close the Connection when you have finished working with it. Closing objects releases resources on the remote DBMS and within your application.

Other jdbcKona objects that you should close after final use:

  • Statement (PreparedStatement, CallableStatement)
  • ResultSet

If you are using WebLogic JDBC in a multitier environment with a two-tier jdbcKona driver, you will set connection properties in a slightly different way. See the Developers Guide Using WebLogic JDBC for more details.

Top of this section

Codeset support in jdbcKona Drivers

jdbcKona/Oracle

Codeset support was introduced in the jdbcKona/Oracle drivers in version 2.5.0. Earlier versions of the drivers support only ASCII data.

In versions 2.5 through 3.1, the jdbcKona/Oracle codeset support relies on the Oracle server codeset conversion mechanism. The drivers always interact with Oracle in either 8859-1 or UTF-8. The Oracle server converts from the driver's codeset to the codeset of the database. For more information about codeset support in jdbcKona/Oracle, see Internationalization support (AL24UTFFSS/UTF-8) in Using jdbcKona/Oracle.

jdbcKona/Sybase and jdbcKona/MSSQLServer

Codeset support was introduced in the jdbcKona/Sybase driver and jdbcKona/MSSQLServer in version 3.1. Earlier versions of the drivers support only ASCII data. Choose the codeset by setting the connection property "weblogic.codeset" to the appropriate JDK codeset for your database. For more information, see Using codesets in Using jdbcKona/Sybase and jdbcKona/MSSQLServer.

jdbcKona/MSSQLServer4

The jdbcKona/MSSQLServer4 Type 4 JDBC driver detects the codeset of the database and operates in that codeset by default. You can explicitly set the codeset in the "weblogic.codeset" connection property, overriding the default behavior.

jdbcKona/Informix4

The jdbcKona/Informix4 Type 4 JDBC driver handles character strings as Unicode strings. To exchange character strings with a database that may operate with a different codeset, you must set the the weblogic.codeset connection property to the proper JDK codeset. If there is no direct mapping between the codeset of your database and the character sets provided with the JDK, you can set the weblogic.codeset connection property to the most appropriate Java character set.

Top of this section

Using a jdbcKona Type 2 driver with Symantec Cafe

If you are developing JDBC applications with Symantec Visual Cafe, copy the jdbcKona .dll files with "_g" in the file names into your cafe\bin and cafe\java\bin directories. These .dll files are linked with javai_g.dll to include debugging support.

Top of this section

Closing Statements and other data objects

You should close Statements, ResultSets, etc. with their close() methods after you have finished using them. When you use one object to construct another, close the objects in the reverse order in which they were created. For example:
  Statement stmt = conn.createStatement();
  ResultSet rs = stmt.executeQuery("select * from empno");

       (process the ResultSet)
  
  rs.close();
  stmt.close();

Always close the java.sql.Connection, as well, usually as one of the last steps in your program. Every Connection should be closed, even if a login fails. An Oracle Connection will cause a SEGV when the finalized thread attempts to close a Connection the programmer has inadvertently left open. If you do not close Connections to log out of the database you may also exceed the maximum number of database logins. Once a Connection is closed, all of the objects created in its context become unusable.

Top of the page

Working with ResultSets from stored procedures

Executing stored procedures may return multiple ResultSets. When you process ResultSets returned by a stored procedure, using Statement.execute() and Statement.getResultSet() methods, you must process all ResultSets returned before any of the OUT parameters or the return status codes are available. Here is a jdbcKona/Sybase example that shows how to retrieve multiple ResultSets from a stored procedure, get all the results, and finally print out the return code of the stored procedure:
  boolean hasResultSet = stmt.execute();
  while (true)
  {
    ResultSet rs = stmt.getResultSet();
    int updateCount = stmt.getUpdateCount();

    // no more results
    if (rs == null && updateCount == -1)
      break; 

    // we have a ResultSet
    if (rs != null)                     
    {
      while (rs.next()) {
        System.out.println
	  ("Get first col by id:" + rs.getString(1));
      }
    }
    else

    // we have an update count
    {
      System.out.println
          ("Update count = " + stmt.getUpdateCount());
    }
    stmt.getMoreResults();
  }

  int retstat = stmt.getInt(1);
  String msg = stmt.getString(3);

  System.out.println("sp_getmessage: status = " + retstat +
                     " msg = " + msg);
  stmt.close();

Top of the page

Support for JDBC Extended SQL

The JavaSoft JDBC specification includes SQL Extensions, also called SQL Escape Syntax. All WebLogic jdbcKona drivers support Extended SQL. Extended SQL provides access to common SQL extensions in a way that is portable between DBMSs.

For example, the function to extract the day name from a date is not defined by the SQL standards. For Oracle, the SQL is:

  select to_char(date_column, 'DAY') from table_with_dates

The equivalent function for Sybase and Microsoft SQL Server is:

  select datename(dw, date_column) from table_with_dates

Using Extended SQL, you can retrieve the day name for both DBMSs as follows:

  select {fn dayname(date_column)} from table_with_dates

Here is an example that demonstrates several features of Extended SQL:

 String query =
  "-- This SQL includes comments and " +
      "JDBC extended SQL syntax.\n" +
  "select into date_table values( \n" +
  "      {fn now()},        -- current time \n" +
  "      {d '1997-05-24'},  -- a date       \n" +
  "      {t '10:30:29' },   -- a time       \n" +
  "      {ts '1997-05-24 10:30:29.123'},  -- a timestamp\n" +
  "     '{string data with { or } will not be altered}'\n" +
  "-- Also note that you can safely include" +
     " { and } in comments or\n" +
  "-- string data.";
  Statement stmt = conn.createStatement();
  stmt.executeUpdate(query);

Extended SQL is delimited with curly braces ("{}") to differentiate it from common SQL. Comments are preceded by two hyphens, and are ended by a newline ("\n"). The entire Extended SQL sequence, including comments, SQL, and Extended SQL, is placed within double quotes and passed to the execute() method of a Statement object. Here is Extended SQL used as part of a CallableStatement:

  CallableStatement cstmt = 
    conn.prepareCall("{ ? = call func_squareInt(?)}");

This example shows that you can nest extended SQL expressions:

  select {fn dayname({fn now()})}

You can retrieve lists of supported Extended SQL functions from a DatabaseMetaData object. This example shows how to list all the functions a JDBC driver supports:

  DatabaseMetaData md = conn.getMetaData();
  System.out.println("Numeric functions:     " +
      md.getNumericFunctions());
  System.out.println("\nString functions:    " + 
      md.getStringFunctions());
  System.out.println("\nTime/date functions: " + 
      md.getTimeDateFunctions());
  System.out.println("\nSystem functions:    " + 
      md.getSystemFunctions());
  conn.close();

Refer to chapter 11 of the JDBC 1.2 specification at JavaSoft for a description of Extended SQL.

Top of the page

II. The JDBC API, with WebLogic extensions

Package java.sql
Package java.math
Class java.lang.Object
   Interface java.sql.CallableStatement
    (extends java.sql.PreparedStatement)
   Interface java.sql.Connection
   Interface java.sql.DatabaseMetaData
   Class java.util.Date
      Class java.sql.Date
      Class java.sql.Time
      Class java.sql.Timestamp
   Class java.util.Dictionary
      Class java.util.Hashtable
       (implements java.lang.Cloneable)
          Class java.util.Properties
   Interface java.sql.Driver
   Class java.sql.DriverManager
   Class java.sql.DriverPropertyInfo
   Class java.lang.Math
   Class java.lang.Number
      Class java.math.BigDecimal
      Class java.math.BigInteger
   Interface java.sql.PreparedStatement
    (extends java.sql.Statement)
   Interface java.sql.ResultSet
   Interface java.sql.ResultSetMetaData
   Interface java.sql.Statement
   Class java.lang.Throwable
      Class java.lang.Exception
         Class java.sql.SQLException
            Class java.sql.SQLWarning
                Class java.sql.DataTruncation
   Class java.sql.Types
   Class weblogic.jdbc.oci.Connection
    (implements java.sql.Connection)
   Class weblogic.jdbc.dblib.Statement
    (implements java.sql.Statement)
       Class weblogic.jdbc.dblib.PreparedStatement
          Class weblogic.jdbc.dblib.CallableStatement
           (implements java.sql.CallableStatement)
   Class weblogic.jdbc.oci.Statement
    (implements java.sql.Statement)
       Class weblogic.jdbc.oci.PreparedStatement
          Class weblogic.jdbc.oci.CallableStatement
           (implements java.sql.CallableStatement)
   

WebLogic provides extensions to JDBC for certain database-specific enhancements. The jdbcKona drivers have the following extended classes:

Check the Oracle, Sybase, and Informix Developers Guides for more information on these extensions.

Top of the page

III. Implementing with the jdbcKona drivers

This example follows a simple jdbcKona application through the basic steps: You will want to refer to each driver's Developers Guide for more database-specific details.

Importing packages

The classes that you import into your jdbcKona application should include:
import java.sql.*;
import java.util.Properties;
import weblogic.common.*;  // Type 2 drivers only

The jdbcKona drivers implement the java.sql interface. You write your application using the java.sql classes; the java.sql.DriverManager maps the jdbcKona implementation to the java.sql classes.

You do not import the JDBC driver class; instead, you load the driver inside the application. This allows you to select an appropriate driver at runtime. You can even decide what DBMS to connect to after the program is compiled.

Each WebLogic distribution contains the latest version of the JDBC API class files. Make sure you do not have any earlier versions of the java.sql classes in your CLASSPATH.

You only have to import java.util.Properties class if you use a Properties object to set parameters for connecting to the DBMS.

Top of this section

Setting properties for connecting

In this example, we use a java.util.Properties object to set parameters for connecting to the DBMS. There are other ways of passing these parameters to the DBMS that do not require a Properties object (more information).
  Properties props = new Properties();
  props.put("user",          "scott");
  props.put("password",      "tiger");
  props.put("server",        "DEMO");
The value for the server property may be vendor specific; in this example, it is the V2 alias of an Oracle database running over TCP. You may also add the server name to the URL (see the next step) instead of setting it with the Properties object.

Top of this section

Connecting to the DBMS

The connection to the DBMS is handled by the JDBC driver. You use both the class name of the driver (in dot-notation) and the URL of the driver (with colons as separators). Class names are case-sensitive.

The Class.forName().newInstance method loads the driver and registers it with DriverManager.

Note: The JavaSoft JDBC API reference for java.sql.Driver recommends simply calling Class.forName("driver-class") to load the driver. However, this is not sufficient with the strictest implementations of the Java VM, such as those of IBM and Microsoft.

Then the Connection is created with the DriverManager.getConnection() method, which takes as arguments the URL of the driver and a Properties object. The URL is not case-sensitive.

  Class.forName("weblogic.jdbc.oci.Driver").newInstance();
  Connection conn =
    DriverManager.getConnection("jdbc:weblogic:oracle",
                                props);
  conn.setAutoCommit(false);
The default transaction mode for JDBC assumes autocommit to be true. If you are using jdbcKona/Sybase or jdbcKona/MSSQLServer, be sure to read Autocommit before you change the autocommit setting. If you are using jdbcKona/Oracle, setting autocommit to false will improve performance.

The Connection object is an important part of the application. The Connection class has constructors for many fundamental database objects that you will use throughout the application, and in the examples that follow, you will see the Connection object conn used again and again.

Connecting to the database completes the initial portion of a jdbcKona application, which will be very much the same for any application.

You should call the close() method on the Connection object as soon as you finish working with it, usually at the end of a class.

Top of this section

Making a simple SQL query

The most fundamental task in database access is to retrieve data. With jdbcKona, this is a three-step process:
  1. Create a Statement to send a SQL query to the DBMS
  2. Execute the Statement
  3. Retrieve the results into a ResultSet
In this example, we execute a simple query on the Employee table (alias "emp") and display data from three of the columns. We also access and display metadata about the table from which the data was retrieved. Note that we close the Statement at the end.
Statement stmt = conn.createStatement();
stmt.execute("select * from emp");
ResultSet rs = stmt.getResultSet();

while (rs.next()) {
  System.out.println(rs.getString("empid") + " - " +
                     rs.getString("name")  + " - " +
                     rs.getString("dept"));
  }

ResultSetMetaData md = rs.getMetaData();

System.out.println("Number of columns: " + 
      md.getColumnCount());
for (int i = 1; i <= md.getColumnCount(); i++) {
    System.out.println("Column Name: "     + 
      md.getColumnName(i));
    System.out.println("Nullable: "        + 
      md.isNullable(i));
    System.out.println("Precision: "       + 
      md.getPrecision(i));
    System.out.println("Scale: "           + 
      md.getScale(i));
    System.out.println("Size: "            + 
      md.getColumnDisplaySize(i));
    System.out.println("Column Type: "     + 
      md.getColumnType(i));
    System.out.println("Column Type Name: "+ 
      md.getColumnTypeName(i));
    System.out.println("");
  }

stmt.close();
There are vendor-dependent details that affect how you use ResultSets. Check in particular Executing and canceling queries and Interleaving operations on a connection if you are using jdbcKona/Sybase or jdbcKona/MSSQLServer.

JDBC ResultsSets have a very basic functionality for dealing with data on the record level. You may find managing data easier with dbKona's higher level of abstraction. dbKona's objects, like TableDataSet, QueryDataSet, and Record, as well as other features like automatic SQL generation and client-side results management, sit on top of JDBC. Check the Developers Guide Using dbKona, the examples, and the dbKona examples for more information.

There are also notes on the implementation of the DatabaseMetaData methods for jdbcKona/Sybase and jdbcKona/MSSQLServer and jdbcKona/Oracle.

Top of this section

Inserting, updating, and deleting records

We illustrate three common database tasks in this step: inserting, updating, and deleting records from a database table. We use a JDBC PreparedStatement for these operations; we create the PreparedStatement, then execute it and close it.

A PreparedStatement (subclassed from JDBC Statement) allows you to execute the same SQL over and over again with different values. PreparedStatements use the JDBC "?" syntax.

  String inssql = 
     "insert into emp(empid, name, dept) values (?, ?, ?)";
  PreparedStatement pstmt = conn.prepareStatement(inssql);

  for (int i = 0; i < 100; i++) {
    pstmt.setInt(1, i);
    pstmt.setString(2, "Person " + i);
    pstmt.setInt(3, i);
    pstmt.execute():
  }
  pstmt.close();
We also use a PreparedStatement to update records. In this example, we add the value of the counter "i" to the current value of the "dept" field.
  String updsql = 
     "update emp set dept = dept + ? where empid = ?";
  PreparedStatement pstmt2 = conn.prepareStatement(updsql);

  for (int i = 0; i < 100; i++) {
    pstmt2.setInt(1, i);
    pstmt2.setInt(2, i);
    pstmt2.execute();
  } 
  pstmt2.close();
Finally, we use a PreparedStatement to delete the records that we added and then updated.
  String delsql = "delete from emp where empid = ?";
  PreparedStatement pstmt3 = conn.prepareStatement(delsql);

  for (int i = 0; i < 100; i++) {
    pstmt3.setInt(1, i);
    pstmt3.execute();
  }
  pstmt3.close();
Top of this section

Creating and using stored procedures and functions

You can use jdbcKona to create, use, and drop stored procedures and functions. First, we execute a series of Statements to drop a set of stored procedures and functions from the database.

  Statement stmt = conn.createStatement();
  try {stmt.execute("drop procedure proc_squareInt");}
  catch (SQLException e) {;}
  try {stmt.execute("drop procedure func_squareInt");}
  catch (SQLException e) {;}
  try {stmt.execute("drop procedure proc_getresults");}
  catch (SQLException e) {;}
  stmt.close();

We use a JDBC Statement to create a stored procedure or function, and then we use a JDBC CallableStatement (subclassed from Statement) with the JDBC "?" syntax to set IN and OUT parameters. If you are using jdbcKona/Sybase or jdbcKona/MSSQLServer, read Using stored procedures and Open Server RPCs in the Developers Guide for jdbcKona/Sybase and jdbcKona/MSSQLServer for more vendor-specific information. If you are using jdbcKona/Oracle, read Using stored procedures in the Developers Guide for jdbcKona/Oracle for details.

The first two examples use jdbcKona/Oracle. Note that Oracle does not natively support binding to "?" values in a SQL statement. Instead it uses ":1", ":2", etc. You can use either syntax in your SQL with jdbcKona/Oracle.

Stored procedure input parameters are mapped to JDBC IN parameters, using the CallableStatement.setXXX() methods, like setInt(), and the JDBC PreparedStatement "?" syntax. Stored procedure output parameters are mapped to JDBC OUT parameters, using the CallableStatement.registerOutParameter() methods and JDBC PreparedStatement "?" syntax. A parameter may be both IN and OUT, which requires both a setXXX() and a registerOutParameter() call to be done on the same parameter number.

In this example, we use a JDBC Statement to create an Oracle stored procedure; then we execute the stored procedure with a CallableStatement. We use the registerOutParameter() method to set an output parameter for the squared value.

  Statement stmt1 = conn.createStatement();
  stmt1.execute
    ("CREATE OR REPLACE PROCEDURE proc_squareInt " +
    "(field1 IN OUT INTEGER, field2 OUT INTEGER) IS " + 
    "BEGIN field2 := field1 * field1; field1 := " +
    "field1 * field1; END proc_squareInt;");
  stmt1.close();

  // Native Oracle SQL is commented out here
  // String sql = "BEGIN proc_squareInt(?, ?); END;";

  // This is the correct syntax as specified by JDBC
  String sql = "{call proc_squareInt(?, ?)}";
  CallableStatement cstmt1 = conn.prepareCall(sql);

  // Register out parameters
  cstmt1.registerOutParameter(2, java.sql.Types.INTEGER);
  for (int i = 0; i < 5; i++) {
    cstmt1.setInt(1, i);
    cstmt1.execute();
    System.out.println(i + " " + cstmt1.getInt(1) +
                       " " + cstmt1.getInt(2));
  }
  cstmt1.close();

In the next example, we use similar code to create and execute a stored function that squares an integer.

  Statement stmt2 = conn.createStatement();
  stmt2.execute("CREATE OR REPLACE FUNCTION func_squareInt " +
                "(field1 IN INTEGER) RETURN INTEGER IS " +
                "BEGIN return field1 * field1; " +
		"END func_squareInt;");
  stmt2.close();

  // Native Oracle SQL is commented out here
  // sql = "BEGIN ? := func_squareInt(?); END;";

  // This is the correct syntax specified by JDBC
  sql = "{ ? = call func_squareInt(?)}";
  CallableStatement cstmt2 = conn.prepareCall(sql);

  cstmt2.registerOutParameter(1, Types.INTEGER);
  for (int i = 0; i < 5; i++) {
    cstmt2.setInt(2, i);
    cstmt2.execute();
    System.out.println(i + " " + cstmt2.getInt(1) +
                       " " + cstmt2.getInt(2));
  }
  cstmt2.close();

In the last example, we show a Sybase stored procedure named sp_getmessages, which takes a message number as an input parameter and returns the message text in a ResultSet as an output parameter. Note that you must process all ResultSets returned by a stored procedure using the Statement.execute() and Statement.getResult() methods before OUT parameters and return status are available. (This example is also detailed in the notes on SQL Server earlier in this document.)

First, we set up the three parameters to the CallableStatement:

  1. Parameter 1 (output only) is the stored procedure return value
  2. Parameter 2 (input only) is the msgno argument to sp_getmessage
  3. Parameter 3 (output only) is the message text return for the message number
  String sql = "{ ? = call sp_getmessage(?, ?)}";
    CallableStatement stmt = conn.prepareCall(sql);

    stmt.registerOutParameter(1, java.sql.Types.INTEGER);
    stmt.setInt(2, 18000);           // msgno 18000
    stmt.registerOutParameter(3, java.sql.Types.VARCHAR);
We execute the stored procedure and check the return value to see if the ResultSet is empty. If it is not, we use a loop to retrieve and display its contents.
  boolean hasResultSet = stmt.execute();
  while (true)
  {
    ResultSet rs = stmt.getResultSet();
    int updateCount = stmt.getUpdateCount();
    if (rs == null && updateCount == -1) // no more results
      break;
    if (rs != null) {
      // Process the ResultSet until it is empty
      while (rs.next()) {
        System.out.println
        ("Get first col by id:" + rs.getString(1));
      }
    } else {
      // we have an update count
      System.out.println("Update count = " + 
       stmt.getUpdateCount());
    }
    stmt.getMoreResults();
  }
Once we have finished processing the ResultSet, the OUT parameters and return status are available.
  int retstat = stmt.getInt(1);
  String msg = stmt.getString(3);

  System.out.println("sp_getmessage: status = " +
                     retstat + " msg = " + msg);
  stmt.close();
Top of this section

Disconnecting and closing objects

There are occasions on which you will want to call the commit() method to commit changes you have made to the database before you close the connection.

When autocommit is set to true (the default JDBC transaction mode) each SQL statement is its own transaction. After we created the Connection for these examples, however, we set autocommit to false; in this mode, the Connection always has an implicit transaction associated with it, and any call to the rollback() or commit() methods will end the current transaction and start a new one. Calling commit() before close() ensures that all of the transactions are completed before closing the Connection.

Just as you close Statements, PreparedStatements, and CallableStatements when you have finished working with them, you should always call the close() method on the connection as final cleanup in your application, in a try {} block, and you should catch exceptions and deal with them appropriately. The final two lines of this example include a call to commit and then a call to close the connection.

  conn.commit();
  conn.close();
Top of this section

Code example

Here are selected portions of the code used in these examples to give you an overall idea of structure for a jdbcKona application. The code example shown here includes retrieving data, displaying metadata, inserting, deleting, and updating data, and stored procedures and functions. Note the explicit calls to close() for each JDBC-related object, and note also that we close the Connection itself in a finally {} block, with the call to close() wrapped in a try {} block.
package examples.jdbc.oracle;

import java.sql.*;
import java.util.Properties;
import weblogic.common.*;

public class test {
  static int i;
  Statement stmt = null;

  public static void main(String[] argv) {
    try {  
      Properties props = new Properties();
      props.put("user",              "scott");
      props.put("password",          "tiger");
      props.put("server",            "DEMO");

      Class.forName("weblogic.jdbc.oci.Driver").newInstance();
      Connection conn =
        DriverManager.getConnection("jdbc:weblogic:oracle",
                                    props);
    }
    catch (Exception e)
      e.printStackTrace();
    }

    try {
      // This will improve performance in Oracle
      // You will need an explicit commit() call later
      conn.setAutoCommit(false);

      stmt = conn.createStatement();
      stmt.execute("select * from emp");
      ResultSet rs = stmt.getResultSet();

      while (rs.next()) {
        System.out.println(rs.getString("empid") + " - " + 
                           rs.getString("name")  + " - " + 
                           rs.getString("dept"));
      }

      ResultSetMetaData md = rs.getMetaData();

      System.out.println("Number of Columns: " + 
         md.getColumnCount());
      for (i = 1; i <= md.getColumnCount(); i++) {
        System.out.println("Column Name: "     + 
          md.getColumnName(i));
        System.out.println("Nullable: "        + 
          md.isNullable(i));
        System.out.println("Precision: "       + 
          md.getPrecision(i));
        System.out.println("Scale: "           + 
          md.getScale(i));
        System.out.println("Size: "            + 
          md.getColumnDisplaySize(i));
        System.out.println("Column Type: "     + 
          md.getColumnType(i));
        System.out.println("Column Type Name: "+ 
          md.getColumnTypeName(i));
        System.out.println("");
      }
      rs.close();
      stmt.close();

      Statement stmtdrop = conn.createStatement();
      try {stmtdrop.execute("drop procedure proc_squareInt");}
      catch (SQLException e) {;}
      try {stmtdrop.execute("drop procedure func_squareInt"); }
      catch (SQLException e) {;}
      try {stmtdrop.execute("drop procedure proc_getresults"); }
      catch (SQLException e) {;}
      stmtdrop.close();

      // Create a stored procedure
      Statement stmt1 = conn.createStatement();
      stmt1.execute
       ("CREATE OR REPLACE PROCEDURE proc_squareInt " +
       "(field1 IN OUT INTEGER, " +
       "field2 OUT INTEGER) IS " + 
       "BEGIN field2 := field1 * field1; " +
       "field1 := field1 * field1; " +
       "END proc_squareInt;");
      stmt1.close();

      CallableStatement cstmt1 =
        conn.prepareCall("BEGIN proc_squareInt(?, ?); END;");
      cstmt1.registerOutParameter(2, Types.INTEGER);
      for (i = 0; i < 100; i++) {
        cstmt1.setInt(1, i);
        cstmt1.execute();
        System.out.println(i + " " + cstmt1.getInt(1) +
                           " " + cstmt1.getInt(2));
      }
      cstmt1.close();

      // Create a stored function
      Statement stmt2 = conn.createStatement();
      stmt2.execute
       ("CREATE OR REPLACE FUNCTION func_squareInt " +
       "(field1 IN INTEGER) RETURN INTEGER IS " +
       "BEGIN return field1 * field1; END func_squareInt;");
      stmt2.close();

      CallableStatement cstmt2 =
        conn.prepareCall("BEGIN ? := func_squareInt(?); END;");
      cstmt2.registerOutParameter(1, Types.INTEGER);
      for (i = 0; i < 100; i++) {
        cstmt2.setInt(2, i);
        cstmt2.execute();
        System.out.println(i + " " + cstmt2.getInt(1) +
                           " " + cstmt2.getInt(2));
      }
      cstmt2.close();

      // Insert 100 records
      System.out.println("Inserting 100 records...");
      String inssql = 
        "insert into emp(empid, name, dept) values (?, ?, ?)";
      PreparedStatement pstmt = conn.prepareStatement(inssql);

      for (i = 0; i < 100; i++) {
        pstmt.setInt(1, i);
        pstmt.setString(2, "Person " + i);
        pstmt.setInt(3, i);
        pstmt.execute();
      }
      pstmt.close();

      // Update 100 records
      System.out.println("Updating 100 records...");
      String updsql = 
       "update emp set dept = dept + ? where empid = ?";
      PreparedStatement pstmt2 = conn.prepareStatement(updsql);

      for (i = 0; i < 100; i++) {
        pstmt2.setInt(1, i);
        pstmt2.setInt(2, i);
        pstmt2.execute();
      }
      pstmt2.close();

      // Delete 100 records
      System.out.println("Deleting 100 records...");
      String delsql = "delete from emp where empid = ?";
      PreparedStatement pstmt3 = conn.prepareStatement(delsql);

      for (i = 0; i < 100; i++) {
        pstmt3.setInt(1, i);
        pstmt3.execute();
      }
      pstmt3.close();

      conn.commit();
    }
    catch (Exception e) {
      // Deal with failures appropriately
    }
    finally {
      try {conn.close();}
      catch (Exception e) {
        // Catch and deal with exception
      }
    }
  }
}

Top of the page

IV. Change history

Change history for the jdbcKona drivers is incorporated into the specific Developers Guide for each driver.

 

Copyright © 2000 BEA Systems, Inc. All rights reserved.
Required browser: Netscape 4.0 or higher, or Microsoft Internet Explorer 4.0 or higher.
Last updated 04/05/1999