BEA Logo BEA WebLogic Enterprise Release 5.1

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

 

   WebLogic Enterprise Doc Home   |   JDBC Topics   |   Previous Topic   |   Next Topic   |   Contents   |   Index

Using the jdbcKona Drivers

 

This chapter covers general guidelines for using the jdbcKona drivers and some vendor-specific notes on each driver. Included at the end of this chapter is a summary of the steps you take, including sample code, to use a JDBC driver in a WebLogic Enterprise Java application.

This topic includes the following sections:

 


API Support

The WebLogic Enterprise 5.1 software supports:

New methods that were added in the JDBC 2.0 API, which were not present in JDBC 1.22, are not supported in this release of WebLogic Enterprise. If a WebLogic Enterprise application calls a new JDBC 2.0 method that was not in JDBC 1.22, an SQLException will be thrown.

 


Platforms Supported by the jdbcKona Drivers

The jdbcKona/Oracle drivers are supported on the following platforms:

For information about any vendor patches required on each platform, and the specific required version of the Java 2 Software Development Kit (SDK), see the WebLogic Enterprise Platform Data Sheets in the WebLogic Enterprise Installation Guide.

 


Adding the JAR Files to Your CLASSPATH

Be sure to add the WebLogic Enterprise Java ARchive (JAR) files that include the jdbcKona driver classes to your environment.

Note: In %TUXDIR% (Windows 2000 or NT) or $TUXDIR (UNIX), the /udataobj/java/jdbc/jdbckona.jar file used in the WebLogic Enterprise 4.2 and prior WebLogic Enterprise Java releases no longer exists. On systems running the WebLogic Enterprise 5.1 software that will continue to use a jdbcKona driver, update your CLASSPATH to reference the JAR files shown in the next example.

Append the following to your CLASSPATH system environment variable, where TUXDIR is the directory in which you installed the WebLogic Enterprise software:

Windows 2000 or NT

%TUXDIR%\udataobj\java\jdk\M3.jar;%TUXDIR%\udataobj\java\jdk\weblogicaux.jar;

UNIX

$TUXDIR/udataobj/java/jdk/M3.jar;$TUXDIR/udataobj/java/jdk/weblogicaux.jar;

 


jdbcKona/Oracle Shared Libraries and Dynamic Link Libraries

The jdbcKona/Oracle (Type 2) driver calls native libraries that are supplied with the driver. The UNIX libraries (shared object files) are in the $TUXDIR/lib directory. The Windows DLL files are included in the WebLogic Enterprise Java software kit in the $TUXDIR\bin directory.

Table 3-1 lists the updated names of the jdbcKona/Oracle driver files included with the WebLogic Enterprise Java system.

Table 3-1 Updated jdbcKona/Oracle Driver Names

Windows 2000
and NT

Solaris, Compaq Tru64 UNIX, IBM AIX

HP-UX

weblogicoci734.dll

weblogicoci805.dll

weblogicoci815.dll

libweblogicoci734.so
(Solaris only)

libweblogicoci805.so

libweblogicoci815.so

libweblogicoci805.sl

libweblogicoci815.sl

The jdbcKona drivers used in WebLogic Enterprise 4.2 and prior Java releases are removed in the current release. The former driver names were:

However, accessing the non-XA jdbcKona drivers with the API used in version 4.2 and prior WebLogic Enterprise releases is still supported; that is, using the java.sql.DriverManager API. For example, JDBC applications from WebLogic Enterprise 4.2 should be able to use a WebLogic Enterprise 5.1 jdbcKona/Oracle driver, provided you change the driver class name for the Oracle driver.

The jdbcKona/Oracle driver class names are as follows:

For the jdbcKona/Oracle drivers, you also need the vendor-supplied libraries for the database.

 


Requirements for Making a Connection to a Database Management System (DBMS)

You need the following components to connect to a DBMS using a jdbcKona driver:

 


Support for JDBC Extended SQL

The Sun Microsystems, Inc. JDBC specification includes SQL Extensions, also called SQL Escape Syntax. All 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

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

select {fn dayname(date_column)} from table_with_dates

The following is an example that demonstrates several features of Extended SQL:

String insert=
"-- This SQL includes comments and JDBC extended SQL syntax. \n" +
"insert into date_table values( {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 character (\n). The entire Extended SQL sequence, including comments, SQL, and Extended SQL, is placed within double quotes and is passed to the execute method of a Statement object.

The following Extended SQL is used as part of a CallableStatement object:

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

The following 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. The following 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();

For a description of Extended SQL, refer to the Sun Microsystems, Inc. Web site, JDBC Specification 1.2, Chapter 11.

 


The JDBC API with WebLogic Extensions

For the complete set of JDBC API documentation, see the following Web site:

http://www.weblogic.com/docs/classdocs/packages.html#jdbc

The following packages, classes, interfaces, and WebLogic extensions compose the JDBC API.

Note: In the class paths, this section shows oci815. However, you would use oci805 or oci734, if you are using Oracle 8.0.5 or Oracle 7.3.4, respectively.

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.jdbc20.oci815.Connection
(implements java.sql.Connection)
Class weblogic.jdbc20.oci815.Statement
(implements java.sql.Statement)
Class weblogic.jdbc20.oci815.PreparedStatement
Class weblogic.jdbc20.oci815.CallableStatement
(implements java.sql.CallableStatement)

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

Class weblogic.jdbc20.oci815.CallableStatement 
Class weblogic.jdbc20.oci815.Connection
Class weblogic.jdbc20.oci815.Statement

For more information about these extensions, see jdbcKona Extensions to the JDBC 1.22 API.

 


Implementing a WebLogic Enterprise Java Application Using the jdbcKona Drivers

This section describes the following steps involved in implementing a simple WebLogic Enterprise Java application that uses a jdbcKona driver to connect to a DBMS:

Many of the steps described in this section include code snippets from a comprehensive code example that is provided at the end of this chapter.

For database-specific details on implementing WebLogic Enterprise Java applications using the jdbcKona drivers, see Using the jdbcKona/Oracle Drivers.

Importing Packages

The classes that you import into your WebLogic Enterprise JavaServer application that uses a jdbcKona driver should include:

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

The jdbcKona drivers implement the java.sql interface. You write your WebLogic Enterprise Java application using the java.sql classes; the java.sql.DriverManager maps the jdbcKona driver to the java.sql classes.

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

Included in the WebLogic Enterprise Java software is 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 need to import the java.util.Properties class only if you use a Properties object to set parameters for connecting to the DBMS.

Setting Properties for Connecting to the DBMS

In the following example, a java.util.Properties object sets the parameters for connecting to the DBMS. There are other ways of passing these parameters to the DBMS that do not require a Properties object, as in the following snippet:

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 version 2 alias of an Oracle database running over TCP. You may also add the server name to the URL (see the next section) instead of setting it with the java.util.Properties object.

Connecting to the DBMS

To connect to the DBMS, complete the following steps:

  1. Load the proper jdbcKona driver.

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

    Class.forName("weblogic.jdbc20.oci815.Driver").newInstance();

  2. Obtain a JDBC connection.

    You request a JDBC connection by invoking 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: See the section "Obtaining Connections from a WebLogic Enterprise Connection Pool" on page 2-15 for more information about an alternative way of connecting to the DBMS.

Note that both steps describe the jdbcKona 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 jdbcKona drivers:

JDBC Driver

Driver Type

Class Pathname

Class URL

jdbcKona/Oracle

Type 2

weblogic.jdbc20.oci734.Driver

weblogic.jdbc20.oci815.Driver

jdbc:weblogic:oci

Additional information required to form a database connection varies by DBMS vendor and by 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.

For full details about the jdbcKona drivers, refer to Using the jdbcKona/Oracle Drivers. For a complete code example, see "Implementing a WebLogic Enterprise Java Application Using the jdbcKona Drivers" on page 3-8.

The connection to the DBMS is handled by the jdbcKona 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 the driver with the DriverManager object.

Note: The Sun Microsystems, Inc. JDBC API Reference for the java.sql.Driver interface recommends simply invoking Class.forName("driver-class") to load the driver.

The connection is created with the DriverManager.getConnection method, which takes as arguments the URL of the driver and a Properties object, as in the following code fragment. The URL is not case sensitive.

Class.forName("weblogic.jdbc20.oci815.Driver").newInstance();
Connection conn =
DriverManager.getConnection("jdbc:weblogic:oracle",
props);
conn.setAutoCommit(false);

The default transaction mode for JDBC assumes autocommit to be true. Setting autocommit to false improves 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. In the examples that follow, you will see the Connection object conn used repeatedly.

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

Invoke the close method on the Connection object as soon as you finish working with the object, usually at the end of a class.

Making a Simple SQL Query

The most fundamental task in database access is to retrieve data. With a jdbcKona driver, retrieving data is a three-step process:

  1. Create a Statement object to send an SQL query to the DBMS.

  2. Execute the Statement.

  3. Retrieve the results into a ResultSet object.

In the following code snippet, 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();

Inserting, Updating, and Deleting Records

The following snippet shows three common database tasks: inserting, updating, and deleting records from a database table. We use a JDBC PreparedStatement object for these operations; we create the PreparedStatement object, then execute the object and close it.

A PreparedStatement object (subclassed from JDBC Statement) allows you to execute the same SQL over and over again with different values. PreparedStatement objects 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 object to update records. In the following code snippet, 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 object to delete the records that we added and then updated, as in the following snippet:

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();

Creating and Using Stored Procedures and Functions

You can use a jdbcKona driver to create, use, and drop stored procedures and functions. First, we execute a series of Statement objects to drop a set of stored procedures and functions from the database, as in the following code snippet:

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 object to create a stored procedure or function, and then use a JDBC CallableStatement object (subclassed from the Statement object) with the JDBC "?" syntax to set IN and OUT parameters. For information about doing this with the jdbcKona/Oracle driver, see Using the jdbcKona/Oracle Drivers.

The first two code snippets that follow use the jdbcKona/Oracle driver. Note that Oracle does not natively support binding to "?" values in an SQL statement. Instead, it uses ":1", ":2", and so forth. You can use either syntax in your SQL with the jdbcKona/Oracle driver.

Stored procedure input parameters are mapped to JDBC IN parameters, using the CallableStatement.setxxx methods, such as setInt(), and the "?" syntax of the JDBC PreparedStatement object. Stored procedure output parameters are mapped to JDBC OUT parameters, using the CallableStatement.registerOutParameter methods and the "?" syntax of the JDBC PreparedStatement object. A parameter may be both IN and OUT, which requires both a setxxx() and a registerOutParameter() invocation to be made on the same parameter number.

In the following code snippet, we use a JDBC Statement object to create an Oracle stored procedure; then we execute the stored procedure with a CallableStatement object. 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 following code snippet, 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();

Disconnecting and Closing Objects

Close Statement, ResultSet, Connection, and other such objects with their close methods after you have finished using them. Closing these objects releases resources on the remote DBMS and within your application. 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 system failure (such as a segment violation) when the finalizer thread attempts to close a connection that you have 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.

There are occasions in which you will want to invoke 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 object for these examples, however, we set autocommit to false; in this mode, the Connection object always has an implicit transaction associated with it, and any invocation to the rollback or commit methods will end the current transaction and start a new one. Invoking commit() before close() ensures that all of the transactions are completed before closing the connection.

Just as you close Statement, PreparedStatement, and CallableStatement objects when you have finished working with them, always invoke the close method on the connection as final cleanup in your application; enclose the close method invocation in a try {} block in order to catch exceptions and deal with them appropriately. The final two lines of the example include an invocation to commit() and then close() to close the connection, as in the following snippet:

conn.commit();
conn.close();

Code Example

The following is a sample implementation to give you an overall idea of the structure for a WebLogic Enterprise Java application that uses a jdbcKona driver to access a DBMS. The code example shown here includes retrieving data, displaying metadata, inserting, deleting, and updating data, and stored procedures and functions. Note the explicit invocations to close() for each JDBC-related object, and note also that we close the connection itself in a finally {} block, with the invocation to close() wrapped in a try {} block.

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.jdbc20.oci815.Driver").newInstance();
Connection conn =
DriverManager.getConnection("jdbc:weblogic:oracle",
props);
}
catch (Exception e)
e.printStackTrace();
}

try {
// This will improve performance in Oracle
// You'll 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
}
}
}
}