// Source File Name: DB2UdCli.java 1.4
//
// Licensed Materials -- Property of IBM
//
// (c) Copyright International Business Machines Corporation, 1996, 1997.
// All Rights Reserved.
//
// US Government Users Restricted Rights -
// Use, duplication or disclosure restricted by
// GSA ADP Schedule Contract with IBM Corp.
// Sample program - Client Side of Java User-defined Functions Sample
// Run these samples by the following steps:
// (1) you must have the "sample" database catalogued on the client
// (2) compile this Java file (javac DB2UdCli.java)
// (3) compile the UDF server program (javac DB2Udf.java) and copy
// it to the sqllib/function directory
// (4) run the sample (java DB2UdCli [username password])
// NOTES: (1) The CLASSPATH and shared library path environment variables
// must be set, as for any JDBC application.
// (2) Visit http://www.software.ibm.com/data/db2/java
// for current DB2 Java information
// Class DB2UdCli implements the sample client (configuration and
// execution using JDBC). Class DB2Udf implements the UDF
// method bodies.
// 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 and using user-defined functions,
// refer to the "Object-Relational Programming" 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.
import COM.ibm.db2.jdbc.app.*;
import java.sql.*;
import java.io.*;
public class DB2UdCli {
static boolean testDL = false;
public static void main (String argv[]) {
Connection con = null;
// URL is jdbc:db2:dbname
String url = "jdbc:db2:sample";
try {
System.out.println ("Java User-defined Function Sample");
// Load DB2 JDBC application driver
Class.forName ("COM.ibm.db2.jdbc.app.DB2Driver").newInstance ();
// Connect to database
if (argv.length == 0) {
// connect with default id/password
con = DriverManager.getConnection(url);
}
else if (argv.length == 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 DB2UdCli [username password]\n");
System.exit(0);
}
System.out.println ("Connected to the database");
// Execute DECLARE FUNCTION calls to register Java UDFs
System.out.println ("Declaring the Java UDFs");
declareUDFs (con, false); // use NOT FENCED mode
// Prepare table for UDF runs
System.out.println ("Preparing test tables for Java UDFs");
prepareTable (con);
// Call UDFs
System.out.println ("Calling UDFs in UNFENCED mode");
callUDFs (con);
// Clean-up table
System.out.println ("Cleaning up test tables");
deleteTable (con);
}
catch (Throwable x)
{
try { con.close (); } catch (Throwable y) {}
System.err.println ("Aborted due to exception.");
x.printStackTrace ();
}
}
// Run DECLARE FUNCTION to register JAVA UDFs
static void
declareUDFs (Connection con,
boolean fenced) throws Exception
{
declareUDF (con, "MATH.\"/\"", "int, int", "int",
fenced, false, "DB2Udf!divid");
declareUDF (con, "fold", "clob(100k), int", "clob(100k)",
fenced, false, "DB2Udf!fold");
declareUDF (con, "findv", "varchar(500)", "int",
fenced, false, "DB2Udf!findvwl");
declareUDF (con, "counter", "", "int",
fenced, true, "DB2Udf!ctr");
declareUDF (con, "get_blob", "varchar(200)", "blob(1K)",
fenced, false, "DB2Udf!getBlob");
declareUDF (con, "listDirectory", "varchar(250)",
"table(f_name varchar(250), f_type varchar(20)," +
"f_link varchar(250), f_len int)",
fenced, true, "DB2Udf!listDirectory");
}
// Build and run just one CREATE FUNCTION statement.
static void
declareUDF (Connection con,
String name,
String argumentTypes,
String returnType,
boolean fenced,
boolean scratchpad,
String externalName) throws Exception
{
Statement s = con.createStatement ();
String sqlClean = "drop function " + name;
try { s.executeUpdate (sqlClean); } catch (SQLException x) { }
String sql = "create function " + name +
" (" + argumentTypes + ") " +
" returns " + returnType +
(fenced ? " fenced" : " not fenced") +
(scratchpad ? " scratchpad" : "") +
" variant no sql no external action " +
" language java parameter style db2general " +
" final call disallow parallel dbinfo " +
" external name '" + externalName + "'";
s.executeUpdate (sql);
System.out.println ("Registered Java UDF " + name);
s.close ();
}
// Create sample tables for UDF runs - parallel C UDF examples
static void
prepareTable (Connection con) throws Exception
{
Statement s = con.createStatement ();
String sqlClean = "drop table udftest";
String sqlClean1 = "drop table datalink_udftest";
String sqlUrlIns1 = "insert into datalink_udftest values (16,dlvalue('";
String sqlUrlIns2 = "'))";
String sqlUrlIns;
byte[] dlUrl = new byte[400];
String dlUrlString;
try
{
s.executeUpdate (sqlClean);
s.executeUpdate (sqlClean1);
} catch (SQLException x) { }
s.executeUpdate ("create table udftest(int1 integer,int2 integer," +
"part char(5),descr clob(33K))");
// Create table for the DATALINK-UDF sample. "no link control"
// has been used just for simplicity. Powerful UDFs can be
// written with "file link control" along similiar lines.
s.executeUpdate ("create table datalink_udftest(int1 integer," +
"file_reference datalink linktype url no link control)");
s.executeUpdate ("insert into udftest values (16,1,'brain'," +
"'The only part of the body capable of forgetting.')");
s.executeUpdate ("insert into udftest values (8,2,'heart'," +
"'The seat of the emotions?')");
s.executeUpdate ("insert into udftest values (4,4,'elbow'," +
"'That bendy place in mid-arm')");
s.executeUpdate ("insert into udftest values (2,0,NULL,NULL)");
s.executeUpdate ("insert into udftest values (97,16,'xxxxx','Unknown.')");
System.out.print("\nTo call the DATALINK-UDF, type a URL\n" +
"(for example, http:// www.ibm.com) at the following prompt.\n" +
"WARNING: Ensure your DB2 server has Data Links support\n" +
"and that the URL is accessible from the database server.\n" +
"To skip the DATALINK-UDF sample, just press ENTER.\n" +
"URL>");
// Get from user the URL whose contents are to be materialized into BLOB
// When user just presses ENTER, the string is zero-length.
// The result BLOB from the UDF in this case will be NULL.
// This can be used to skip the DATALINK-UDF sample.
System.in.read(dlUrl);
// Construct a string from user input, trimming whitespaces at
// both ends
dlUrlString = (new String(dlUrl)).trim();
if (!dlUrlString.equals("")) {
// Use the input value to insert into a DATALINK column
sqlUrlIns = sqlUrlIns1 + dlUrlString + sqlUrlIns2;
s.executeUpdate (sqlUrlIns);
System.out.println ("Inserted DATALINK value into sample" +
" table datalink_udftest!");
testDL = true;
}
s.close ();
System.out.println ("Created UDF test tables.");
}
// Call the UDFs - parallel C UDF examples
static void
callUDFs (Connection con) throws Exception
{
runQuery (con, "select substr(descr,1,30)," +
"substr(fold(descr,6),1,30) from udftest");
System.out.println ();
// exception expected for this run
try
{
runQuery (con, "select part, findv(part) from udftest");
}
catch (SQLException x)
{
if (x.getSQLState ().equals ("38700"))
System.out.println ("Got expected exception: " + x.toString ());
else
throw x;
}
// System.out.println();
runQuery (con, "select substr(descr,1,25), " +
"findv(cast(descr as varchar(60))) from udftest");
System.out.println ();
runQuery (con, "select int1, counter(), int1/counter() from udftest");
System.out.println ();
// Run the datalink query if the user entered a URL at the prompt
if (testDL) {
runQuery (con, "select get_blob(dlurlcomplete(file_reference)) " +
"from datalink_udftest");
System.out.println ();
}
runQuery (con, "select * from table(listDirectory('/')) as files");
System.out.println ();
}
// Run a query and print out its results
static void
runQuery (Connection con, String sql) throws Exception
{
Statement s = con.createStatement ();
System.out.println ("Executing SQL query:");
System.out.println (sql);
ResultSet rs = s.executeQuery (sql);
int row = 1;
int numColumns = rs.getMetaData ().getColumnCount ();
while (rs.next ())
{
System.out.print ("Row " + row + ": ");
for (int column = 1; column <= numColumns; column++)
{
if (column > 1)
System.out.print (", ");
System.out.print (rs.getString (column));
}
System.out.println ();
row++;
}
rs.close ();
s.close ();
}
// Drop the UDF tables we built
static void
deleteTable (Connection con) throws Exception
{
Statement s = con.createStatement ();
s.executeUpdate ("drop table udftest");
s.executeUpdate ("drop table datalink_udftest");
s.close ();
System.out.println ("Dropped UDF test tables.");
}
}