// Source File Name: Spclient.java %
//
// Licensed Materials -- Property of IBM
//
// (c) Copyright International Business Machines Corporation, 1998, 2000.
// All Rights Reserved.
//
// US Government Users Restricted Rights -
// Use, duplication or disclosure restricted by
// GSA ADP Schedule Contract with IBM Corp.
// Sample Program Spclient - Client Application for Stored Procedure
// To run this sample, perform the following steps:
// (1) create and populate the SAMPLE database (db2sampl)
// (2) compile Spserver (javac Spserver.java)
// (3) copy Spserver.class to the sqllib/function directory
// (4) register the stored procedures using the Spcreate.db2 CLP script:
// (i) db2 connect to sample
// (ii) db2 -td@ -vf Spcreate.db2
// (3) compile Spclient (javac Spclient.java)
// (4) run Spclient (java Spclient)
// NOTES: (1) The jdk11_path database manager configuration parameter must
// be set on the server
// (2) The CLASSPATH and shared library path environment variables
// must be set, as for any JDBC application
// (3) Visit http://www.software.ibm.com/data/db2/java
// for current DB2 Java information
// For more information about this sample, refer to the README file.
// For more information on Programming in Java, refer to the
// "Programming in Java" section of the Application Development Guide.
// For more information on creating stored procedures, refer to the
// "Writing Stored Procedures" section of the Application Development Guide.
// For more information on building and running Java programs for DB2,
// refer to the "Building Java Applets and Applications" section of the
// Application Building Guide.
// For more information on the SQL language, refer to the SQL Reference.
// Spclient calls twelve methods that call stored procedures:
// (1) callOutLanguage: returns language of the stored procedure library
// Parameter types used: OUT CHAR(8)
// (2) callOutParameter: return median salary of EMPLOYEE table
// Parameter types used: OUT DOUBLE
// OUT INTEGER
// OUT CHAR(32)
// (3) callInParameters: accept 3 values and update salaries in EMPLOYEE table
// accordingly
// Parameter types used: IN DOUBLE
// IN CHAR(3)
// OUT INTEGER
// OUT CHAR(32)
// (4) callIncallOutParameter: accept an input value and return the median
// salary of the EMPLOYEE table for employees who make more
// than the input value. Demonstrates how to use null indicators
// in a client application.
// Parameter style (C): GENERAL WITH NULLS
// Parameter style (Java): JAVA
// Parameter style (SQL): SQL
// Parameter types used: INOUT DOUBLE
// OUT INTEGER
// OUT CHAR(32)
// (5) callOneResultSet: return a result set to the client application
// Parameter types used: IN DOUBLE
// OUT INTEGER
// (6) callTwoResultSets: return two result sets to the client application
// Parameter types used: IN DOUBLE
// OUT INTEGER
// (7) callClobExtract: return a sub-section of a CLOB data type
// Parameter types used: IN CHAR(6)
// OUT VARCHAR(1000)
// OUT INTEGER
// (8) callDecimalType: pass and receive a DECIMAL data type from a
// stored procedure
// Parameter types used: INOUT DECIMAL
// (9) callAllDataTypes: use all of the common data types in a stored procedure
// Parameter types used: INOUT SMALLINT
// INOUT INTEGER
// INOUT BIGINT
// INOUT REAL
// INOUT DOUBLE
// OUT CHAR(1)
// OUT CHAR(15)
// OUT VARCHAR(12)
// OUT DATE
// OUT TIME
// (10) callDB2SQL: calls a DB2SQL parameter style stored procedure
// Parameter style: DB2SQL
// Parameter types used: IN CHAR(8)
// OUT DOUBLE
// (11) callDBINFO: calls a stored procedure that receives a DBINFO
// structure and returns elements of the structure to the client
// Parameter types used: IN CHAR(8)
// OUT DOUBLE
// OUT CHAR(128)
// OUT CHAR(8)
// OUT INTEGER
// (12) callProgramTypeMain: calls a stored procedure implemented with
// PROGRAM TYPE MAIN parameter passing style
// Parameter types used: IN CHAR(8)
// OUT DOUBLE
import java.sql.*; // JDBC classes /* :rk.1:erk. */
import java.math.BigDecimal; // BigDecimal support for packed decimal type
class Spclient
{
static double outMedian = 0;
static
{
try
{
System.out.println();
System.out.println("Java Stored Procedure Sample");
Class.forName("COM.ibm.db2.jdbc.app.DB2Driver").newInstance();
}
catch (Exception e)
{
System.out.println("\nError loading DB2 Driver...\n");
e.printStackTrace();
}
}
public static void main(String argv[])
{
Connection con = null;
// URL is jdbc:db2:dbname
String url = "jdbc:db2:sample";
String language = "";
try
{
if (argv.length == 0) {
// connect to sample database
// connect with default id/password
con = DriverManager.getConnection(url); /* :rk.2:erk. */
}
else if (argv.length == 2) {
// connect to sample database
// connect with user-provided username and password
String userid = argv[0];
String passwd = argv[1];
con = DriverManager.getConnection(url, userid, passwd);
}
else if (argv.length == 3) {
// connect to user-provided database
url = "jdbc:db2:" + argv[2];
String userid = argv[0];
String passwd = argv[1];
// connect with user-provided username and password
con = DriverManager.getConnection(url, userid, passwd);
}
else {
System.out.println("\nUsage: java Spclient "
+ "[username password [database]]\n");
System.exit(0);
}
// turn off autocommit
con.setAutoCommit(false); /* :rk.3:erk. */
language = callOutLanguage(con);
callOutParameter(con);
callInParameters(con);
callInoutParameter(con, outMedian);
callInoutParameter(con, 99999.99);
callOneResultSet(con);
callTwoResultSets(con);
// SQL procedures cannot handle LOB data types
if (language.trim().equals("SQL"))
{
System.out.println("\nStored procedures are implemented in SQL,\n" +
"which cannot handle LOB datatypes.\n" +
"Skipping the call to CLOB_EXTRACT.\n");
}
else if (language.trim().equals("C"))
{
System.out.println(
"\n\n If the CLOB EXTRACT stored procedure is implemented\n" +
" using CLI, you must increase the value of the UDF_MEM_SZ\n" +
" database manager configuration variable to at least two\n" +
" pages larger than the size of the input arguments and\n" +
" the result of the stored procedure. To do this, issue\n" +
" the following command from the CLP:\n" +
" db2 UPDATE DBM CFG USING UDF_MEM_SZ 2048\n" +
" For the change to take effect, you must then stop and\n" +
" restart the DB2 server by issuing the following\n" +
" commands from the CLP:\n" +
" db2stop\n" +
" db2start");
callClobExtract("000140", con);
}
else if (language.trim().equals("JAVA"))
{
callClobExtract("000140", con);
}
// Java and SQL procedures can handle DECIMAL data types
if (language.trim().equals("SQL") || language.trim().equals("JAVA"))
{
callDecimalType(con);
}
else if (language.trim().equals("C"))
{
// C does not provide a native data type for decimal
// values, so neither a C client application nor a
// C stored procedure can pass DECIMAL SQL data types.
//
// Do not call the DECIMAL_TYPE stored procedure,
// because the stored procedure is written in C.
}
callAllDataTypes(con);
// the following stored procedures can only be implemented in C/C++
if (language.trim().equals("C"))
{
callDB2SQL("CLERK", con);
callDBINFO("MANAGER", con);
callProgramTypeMain("DESIGNER", con);
}
// roll back any changes to the database
con.rollback(); /* :rk.8:erk. */
con.close();
}
catch (Exception e)
{
try
{
con.rollback();
con.close();
}
catch (Exception x)
{ }
e.printStackTrace ();
}
} // end main
public static String callOutLanguage(Connection con)
{
String outLang = "";
try {
// prepare the CALL statement for OUT_LANGUAGE
String procName = "OUT_LANGUAGE";
String sql = "CALL " + procName + "(?)";
CallableStatement callStmt = con.prepareCall(sql);
// register the output parameter
callStmt.registerOutParameter (1, Types.CHAR);
// call the stored procedure
System.out.println ("\nCall stored procedure named " + procName);
callStmt.execute();
// retrieve output parameters
outLang = callStmt.getString(1);
System.out.println ("Stored procedures are implemented in language "
+ outLang);
}
catch (SQLException e)
{
System.out.println(e);
}
return(outLang);
}
public static void callOutParameter(Connection con)
{
try
{
// prepare the CALL statement for OUT_PARAM
String procName = "OUT_PARAM";
String sql = "CALL " + procName + "(?, ?, ?)";
CallableStatement callStmt = con.prepareCall(sql);
// register the output parameter /* :rk.4:erk. */
callStmt.registerOutParameter (1, Types.DOUBLE);
callStmt.registerOutParameter (2, Types.INTEGER);
callStmt.registerOutParameter (3, Types.CHAR);
// call the stored procedure /* :rk.5:erk. */
System.out.println ("\nCall stored procedure named " + procName);
callStmt.execute();
// retrieve output parameters /* :rk.6:erk. */
outMedian = callStmt.getDouble(1);
int outErrorCode = callStmt.getInt(2);
String outErrorLabel = callStmt.getString(3);
if (outErrorCode == 0) /* :rk.7:erk. */
{
System.out.println(procName + " completed successfully");
System.out.println ("Median salary returned from " + procName + " = "
+ outMedian);
}
else
{ // stored procedure failed
System.out.println(procName + " failed with SQLCODE "
+ outErrorCode);
System.out.println(procName + " failed at " + outErrorLabel);
}
}
catch (SQLException e)
{
System.out.println(e);
}
}
public static void callInParameters(Connection con) throws SQLException
{
try
{
// prepare the CALL statement for IN_PARAMS
String procName = "IN_PARAMS";
String sql = "CALL " + procName + "(?, ?, ?, ?, ?, ?)";
CallableStatement callStmt = con.prepareCall(sql);
// Display total salary before calling IN_PARAMS
String query = "SELECT SUM(salary) FROM employee WHERE workdept = ?";
PreparedStatement queryStmt = con.prepareStatement(query);
queryStmt.setString(1, "E11");
ResultSet queryRS = queryStmt.executeQuery();
queryRS.next();
double sumSalary = queryRS.getDouble(1);
queryRS.close();
System.out.println("\nSum of salaries for dept. E11 = "
+ sumSalary + " before " + procName);
// register the output parameters
callStmt.registerOutParameter (5, Types.INTEGER);
callStmt.registerOutParameter (6, Types.CHAR);
// set input parameters
callStmt.setDouble (1, 15000);
callStmt.setDouble (2, 20000);
callStmt.setDouble (3, 25000);
callStmt.setString (4, "E11");
// initialize output parameters
callStmt.setInt (5, 0);
callStmt.setString (6, "");
// call the stored procedure
System.out.println ("\nCall stored procedure named " + procName);
callStmt.execute();
// retrieve output parameters
int outErrorCode = callStmt.getInt(5);
String outErrorLabel = callStmt.getString(6);
if (outErrorCode == 0) {
System.out.println(procName + " completed successfully");
// Display total salary after calling IN_PARAMS
queryRS = queryStmt.executeQuery();
queryRS.next();
sumSalary = queryRS.getDouble(1);
queryRS.close();
System.out.println("Sum of salaries for dept. E11 = "
+ sumSalary + " after " + procName);
queryStmt.close();
}
else { // stored procedure failed
System.out.println(procName + " failed with SQLCODE " + outErrorCode);
System.out.println(procName + " failed at " + outErrorLabel.trim());
}
}
catch (SQLException e)
{
/* Roll back any UPDATE statements issued before the SQLException */
con.rollback();
System.out.println(e);
}
}
public static void callInoutParameter(Connection con, double median)
{
try
{
// prepare the CALL statement for INOUT_PARAM
String procName = "INOUT_PARAM";
String sql = "CALL " + procName + "(?, ?, ?)";
CallableStatement callStmt = con.prepareCall(sql);
// set input parameter to median value passed back by OUT_PARAM
callStmt.setDouble (1, median);
// register the output parameters
callStmt.registerOutParameter (1, Types.DOUBLE);
callStmt.registerOutParameter (2, Types.INTEGER);
callStmt.registerOutParameter (3, Types.CHAR);
// call the stored procedure
System.out.println ("\nCall stored procedure named " + procName);
if (median == 99999.99)
{
System.out.println("with an input value that causes a NOT FOUND error");
}
callStmt.execute();
// retrieve output parameters
double inoutMedian = callStmt.getDouble(1);
int outErrorCode = callStmt.getInt(2);
String outErrorLabel = callStmt.getString(3);
if (outErrorCode == 0) {
System.out.println(procName + " completed successfully");
System.out.println("Median salary returned from " + procName + " = "
+ inoutMedian);
}
else { // stored procedure failed
System.out.println(procName + " failed with SQLCODE " + outErrorCode);
System.out.println(procName + " failed at " + outErrorLabel.trim());
}
}
catch (SQLException e)
{
System.out.println(e);
}
}
public static void callOneResultSet(Connection con)
{
try
{
// prepare the CALL statement for ONE_RESULT_SET
String procName = "ONE_RESULT_SET";
String sql = "CALL " + procName + "(?, ?)";
CallableStatement callStmt = con.prepareCall(sql);
// set input parameter to median value passed back by OUT_PARAM
callStmt.setDouble (1, outMedian);
// register the output parameter
callStmt.registerOutParameter (2, Types.INTEGER);
// call the stored procedure
System.out.println ("\nCall stored procedure named " + procName);
callStmt.execute();
// retrieve output parameter
int outErrorCode = callStmt.getInt(2);
if (outErrorCode == 0) {
System.out.println(procName + " completed successfully");
ResultSet rs = callStmt.getResultSet();
while (rs.next()) {
fetchAll(rs);
}
// close ResultSet
rs.close();
}
else { // stored procedure failed
System.out.println(procName + " failed with SQLCODE " + outErrorCode);
}
}
catch (SQLException e)
{
System.out.println(e);
}
}
public static void callTwoResultSets(Connection con)
{
try
{
// prepare the CALL statement for TWO_RESULT_SETS
String procName = "TWO_RESULT_SETS";
String sql = "CALL " + procName + "(?, ?)";
CallableStatement callStmt = con.prepareCall(sql);
// set input parameter to median value passed back by OUT_PARAM
callStmt.setDouble (1, outMedian);
// register the output parameter
callStmt.registerOutParameter (2, Types.INTEGER);
// call the stored procedure
System.out.println ("\nCall stored procedure named " + procName);
callStmt.execute();
// retrieve output parameter
int outErrorCode = callStmt.getInt(2);
if (outErrorCode == 0) {
System.out.println(procName + " completed successfully");
System.out.println("Result set 1: Employees who make more than " + outMedian);
// get first result set
ResultSet rs = callStmt.getResultSet();
while (rs.next()) {
fetchAll(rs);
}
System.out.println("\nResult set 2: Employees who make less than " + outMedian);
// get second result set
callStmt.getMoreResults();
rs = callStmt.getResultSet();
while (rs.next()) {
fetchAll(rs);
}
// close ResultSet
rs.close();
}
else { // stored procedure failed
System.out.println(procName + " failed with SQLCODE " + outErrorCode);
}
}
catch (SQLException e)
{
System.out.println(e);
}
}
public static void callClobExtract(String empNo, Connection con)
{
String outInterests;
try
{
// prepare the CALL statement for CLOB_EXTRACT
String procName = "CLOB_EXTRACT";
String sql = "CALL " + procName + "(?, ?, ?)";
CallableStatement callStmt = con.prepareCall(sql);
// set input parameter to median value passed back by OUT_PARAM
callStmt.setString (1, empNo);
// register the output parameters
callStmt.registerOutParameter (2, Types.VARCHAR);
callStmt.registerOutParameter (3, Types.INTEGER);
// call the stored procedure
System.out.println ("\nCall stored procedure named " + procName);
callStmt.execute();
// retrieve output parameters
outInterests = callStmt.getString(2);
int outErrorCode = callStmt.getInt(3);
if (outErrorCode == 0)
{
System.out.println(procName + " completed successfully");
System.out.println ("Resume section returned for employee "
+ empNo + "=\n" + outInterests);
}
else
{ // stored procedure failed
System.out.println(procName + " failed with SQLCODE "
+ outErrorCode);
System.out.println("from procedure section labelled "
+ outInterests);
}
}
catch (SQLException e)
{
System.out.println(e);
}
}
public static void callDecimalType(Connection con)
{
try
{
// prepare the CALL statement for ALL_DATA_TYPES
String procName = "DECIMAL_TYPE";
String sql = "CALL " + procName + "(?, ?, ?)";
CallableStatement callStmt = con.prepareCall(sql);
// declare and initialize input variable
BigDecimal inoutDecimal = new BigDecimal("400000.00");
// set input parameter
callStmt.setBigDecimal (1, inoutDecimal);
// register the output parameters
callStmt.registerOutParameter (1, Types.DECIMAL, 2);
callStmt.registerOutParameter (2, Types.INTEGER);
callStmt.registerOutParameter (3, Types.CHAR);
// call the stored procedure
System.out.println ("\nCall stored procedure named " + procName);
callStmt.execute();
// retrieve SQLCODE output parameter
int outErrorCode = callStmt.getInt(2);
if (outErrorCode == 0) {
System.out.println(procName + " completed successfully");
// retrieve output parameters
inoutDecimal = callStmt.getBigDecimal(1,2);
System.out.println("Value of DECIMAL = " + inoutDecimal);
}
else { // stored procedure failed
String outErrorLabel = callStmt.getString(3);
System.out.println(procName + " failed with SQLCODE " + outErrorCode);
System.out.println(" from procedure section labelled " + outErrorLabel);
}
callStmt.close ();
}
catch (SQLException e)
{
System.out.println(e);
}
}
public static void callAllDataTypes(Connection con)
{
try
{
// prepare the CALL statement for ALL_DATA_TYPES
String procName = "ALL_DATA_TYPES";
String sql = "CALL " + procName + "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
CallableStatement callStmt = con.prepareCall(sql);
// declare and initialize input variables
short inoutSmallint = 32000;
int inoutInteger = 2147483000;
long inoutBigint = 2147483000;
float inoutReal = 100000;
double inoutDouble = 2500000;
// declare output variables
String outChar, outChars, outVarchar;
Date outDate;
Time outTime;
// set input parameters
callStmt.setShort (1, inoutSmallint);
callStmt.setInt (2, inoutInteger);
callStmt.setLong (3, inoutBigint);
callStmt.setFloat (4, inoutReal);
callStmt.setDouble (5, inoutDouble);
// register the output parameters
callStmt.registerOutParameter (1, Types.SMALLINT);
callStmt.registerOutParameter (2, Types.INTEGER);
callStmt.registerOutParameter (3, Types.BIGINT);
callStmt.registerOutParameter (4, Types.REAL);
callStmt.registerOutParameter (5, Types.DOUBLE);
callStmt.registerOutParameter (6, Types.CHAR);
callStmt.registerOutParameter (7, Types.CHAR);
callStmt.registerOutParameter (8, Types.VARCHAR);
callStmt.registerOutParameter (9, Types.DATE);
callStmt.registerOutParameter (10, Types.TIME);
callStmt.registerOutParameter (11, Types.INTEGER);
callStmt.registerOutParameter (12, Types.CHAR);
// call the stored procedure
System.out.println ("\nCall stored procedure named " + procName);
callStmt.execute();
// retrieve SQLCODE output parameter
int outErrorCode = callStmt.getInt(11);
if (outErrorCode == 0) {
System.out.println(procName + " completed successfully");
// retrieve output parameters
inoutSmallint = callStmt.getShort(1);
inoutInteger = callStmt.getInt(2);
inoutBigint = callStmt.getLong(3);
inoutReal = callStmt.getFloat(4);
inoutDouble = callStmt.getDouble(5);
outChar = callStmt.getString(6);
outChars = callStmt.getString(7);
outVarchar = callStmt.getString(8);
outDate = callStmt.getDate(9);
outTime = callStmt.getTime(10);
System.out.println("Value of SMALLINT = " + inoutSmallint);
System.out.println("Value of INTEGER = " + inoutInteger);
System.out.println("Value of BIGINT = " + inoutBigint);
System.out.println("Value of REAL = " + inoutReal);
System.out.println("Value of DOUBLE = " + inoutDouble);
System.out.println("Value of CHAR(1) = " + outChar);
System.out.println("Value of CHAR(15) = " + outChars.trim());
System.out.println("Value of VARCHAR(12) = " + outVarchar.trim());
System.out.println("Value of DATE = " + outDate);
System.out.println("Value of TIME = " + outTime);
}
else { // stored procedure failed
String outErrorLabel = callStmt.getString(12);
System.out.println(procName + " failed with SQLCODE " + outErrorCode);
System.out.println(" from procedure section labelled " + outErrorLabel);
}
callStmt.close ();
}
catch (SQLException e)
{
System.out.println(e);
}
}
public static void callDB2SQL(String job, Connection con)
{
try
{
// prepare the CALL statement for DB2SQL_EXAMPLE
String procName = "DB2SQL_EXAMPLE";
String sql = "CALL " + procName + "(?, ?)";
CallableStatement callStmt = con.prepareCall(sql);
// set the input parameter
callStmt.setString (1, job);
// register the output parameter
callStmt.registerOutParameter (2, Types.DOUBLE);
// call the stored procedure
System.out.println ("\nCall stored procedure named " + procName);
callStmt.execute();
// retrieve output parameters
outMedian = callStmt.getDouble(2);
System.out.println(procName + " completed successfully");
System.out.println ("Median salary returned from " + procName + " = "
+ outMedian);
}
catch (SQLException e)
{
// Note that the JDBC specification only allows us to
// get the SQLSTATE as a method called on an instance of
// an SQLException. If you call DB2SQL_EXAMPLE with
// null input, so that the stored procedure returns the
// custom SQLSTATE ('38100') and message, the Java client
// considers it a successful call because the returned SQLCODE = 0
// and an SQLException is not raised.
System.out.println(e);
}
}
public static void callDBINFO(String job, Connection con)
{
try
{
String databaseName, databaseVersion;
// prepare the CALL statement for DBINFO_EXAMPLE
String procName = "DBINFO_EXAMPLE";
String sql = "CALL " + procName + "(?, ?, ?, ?, ?)";
CallableStatement callStmt = con.prepareCall(sql);
// set the input parameter
callStmt.setString (1, job);
// register the output parameters
callStmt.registerOutParameter (2, Types.DOUBLE);
callStmt.registerOutParameter (3, Types.CHAR);
callStmt.registerOutParameter (4, Types.CHAR);
callStmt.registerOutParameter (5, Types.INTEGER);
// call the stored procedure
System.out.println ("\nCall stored procedure named " + procName);
callStmt.execute();
// retrieve output parameters
outMedian = callStmt.getDouble(2);
databaseName = callStmt.getString(3);
databaseVersion = callStmt.getString(4);
int outErrorCode = callStmt.getInt(5);
if (outErrorCode == 0) {
System.out.println(procName + " completed successfully");
System.out.println ("Average salary for job " + job + " = "
+ outMedian);
System.out.println("Database name from DBINFO structure = "
+ databaseName.trim());
System.out.println("Database version from DBINFO structure = "
+ databaseVersion.trim());
}
else { // stored procedure failed
System.out.println(procName + " failed with SQLCODE "
+ outErrorCode);
}
}
catch (SQLException e)
{
System.out.println(e);
}
}
public static void callProgramTypeMain(String job, Connection con)
{
try
{
// prepare the CALL statement for MAIN_EXAMPLE
String procName = "MAIN_EXAMPLE";
String sql = "CALL " + procName + "(?, ?, ?)";
CallableStatement callStmt = con.prepareCall(sql);
// set the input parameter
callStmt.setString (1, job);
// register the output parameter
callStmt.registerOutParameter (2, Types.DOUBLE);
callStmt.registerOutParameter (3, Types.INTEGER);
// call the stored procedure
System.out.println ("\nCall stored procedure named " + procName);
callStmt.execute();
// retrieve output parameters
outMedian = callStmt.getDouble(2);
int outErrorCode = callStmt.getInt(3);
if (outErrorCode == 0) {
System.out.println(procName + " completed successfully");
System.out.println ("Average salary for job " + job + " = "
+ outMedian);
}
else { // stored procedure failed
System.out.println(procName + " failed with SQLCODE "
+ outErrorCode);
}
}
catch (SQLException e)
{
System.out.println(e);
}
}
// ======================================================
// Method: fetchAll -- returns all rows from a result set
// ======================================================
public static void fetchAll( ResultSet rs )
{ try
{ System.out.println("=================================================================");
ResultSetMetaData stmtInfo = rs.getMetaData();
int numOfColumns = stmtInfo.getColumnCount();
int r = 0;
while( rs.next() )
{ r++;
System.out.print("Row: " + r + ": ");
for( int i=1; i <= numOfColumns; i++ )
{ System.out.print(rs.getString(i));
if( i != numOfColumns ) System.out.print(" , ");
}
System.out.println("");
}
}
catch (SQLException e)
{ System.out.println("Error: fetchALL: exception");
System.out.println (e);
}
}
}