A Java™ scalar function returns one value from a Java program to the database. For example, a scalar function could be created that returns the sum of two numbers.
Like Java stored procedures, Java scalar functions use one of two parameter styles, Java and DB2GENERAL. When coding a Java user-defined function (UDF), you must be aware of restrictions placed on creating Java scalar functions.
The Java parameter style is the style specified by the SQLJ Part 1: SQL Routines standard. When coding a Java UDF, use the following conventions.
For example, given a UDF called sample!test3 that returns INTEGER and takes arguments of type CHAR(5), BLOB(10K), and DATE, DB2® expects the Java implementation of the UDF to have the following signature:
import com.ibm.db2.app.*; public class sample { public static int test3(String arg1, Blob arg2, Date arg3) { ... } }
The parameters of a Java method must be SQL compatible types. For example, if a UDF is declared as taking arguments of SQL types t1, t2, and t3, and returning type t4, it is called as a Java method with the expected Java signature:
public static T4 name (T1 a, T2 b, T3 c) { .....}
where:
The correlation between SQL types and Java types is found in Parameter passing conventions for stored procedures and UDFs.
SQL NULL values are represented by Java variables that are not initialized. These variables have a Java null value if they are object types. If an SQL NULL is passed to a Java scalar data type, such as int, then an exception condition is raised.
To return a result from a Java UDF when using the JAVA parameter style, simply return the result from the method.
{ .... return value; }
Like C modules used in UDFs and stored procedures, you cannot use the Java standard I/O streams (System.in, System.out, and System.err) in Java UDFs.
Parameter style DB2GENERAL is used by Java UDFs. In this parameter style, the return value is passed as the last parameter of the function and must be set using a set method of the com.ibm.db2.app.UDF class.
When coding a Java UDF, the following conventions must be followed:
A class that includes a Java UDF must extend the Java class, com.ibm.db2.app.UDF. A Java UDF that uses the DB2GENERAL parameter style must be a void instance method of the Java class. For example, for a UDF called sample!test3 that returns INTEGER and takes arguments of type CHAR(5), BLOB(10K), and DATE, DB2 expects the Java implementation of the UDF to have the following signature:
import com.ibm.db2.app.*; public class sample extends UDF { public void test3(String arg1, Blob arg2, String arg3, int result) { ... } }
The parameters of a Java method must be SQL types. For example, if a UDF is declared as taking arguments of SQL types t1, t2, and t3, returning type t4, it is called as a Java method with the expected Java signature:
public void name (T1 a, T2 b, T3 c, T4 d) { .....}
where:
The correlation between SQL types and Java types is given in the section, Parameter passing conventions for stored procedures and UDFs.
SQL NULL values are represented by Java variables that are not initialized. These variables have a value of zero if they are primitive types, and Java null if they are object types, in accordance with Java rules. To tell an SQL NULL apart from an ordinary zero, the isNull method can be called for any input argument:
{ .... if (isNull(1)) { /* argument #1 was a SQL NULL */ } else { /* not NULL */ } }
In the previous example, the argument numbers start at one. The isNull() function, like the other functions that follow, are inherited from the com.ibm.db2.app.UDF class. To return a result from a Java UDF when using the DB2GENERAL parameter style, use the set() method in the UDF, as follows:
{ .... set(2, value); }
Where 2 is the index of an output argument, and value is a literal or variable of a compatible type. The argument number is the index in the argument list of the selected output. In the first example in this section, the int result variable has an index of 4. An output argument that is not set before the UDF returns has a NULL value.
Like C modules used in UDFs and stored procedures, you cannot use the Java standard I/O streams (System.in, System.out, and System.err) in Java UDFs.
Typically, DB2 calls a UDF many times, once for each row of an input or result set in a query. If SCRATCHPAD is specified in the CREATE FUNCTION statement of the UDF, DB2 recognizes that some "continuity" is needed between successive invocations of the UDF, and therefore, for DB2GENERAL parameter style functions, the implementing Java class is not instantiated for each call, but generally speaking once per UDF reference per statement. If, however, NO SCRATCHPAD is specified for a UDF, then a clean instance is instantiated for each call to the UDF, by means of a call to the class constructor.
A scratchpad may be useful for saving information across calls to a UDF. Java UDFs can either use instance variables or set the scratchpad to achieve continuity between calls. Java UDFs access the scratchpad with the getScratchPad and setScratchPad methods available in com.ibm.db2.app.UDF. At the end of a query, if you specify the FINAL CALL option on the CREATE FUNCTION statement, the object's public void close() method is called (for DB2GENERAL parameter style functions). If you do not define this method, a stub function takes over and the event is ignored. The com.ibm.db2.app.UDF class contains useful variables and methods that you can use within a DB2GENERAL parameter style UDF. These variables and methods are explained in the following table.
Variables and Methods | Description |
---|---|
|
For scalar UDFs, these are constants to determine if the call is a first call or a normal call. For table UDFs, these are constants to determine if the call is a first call, open call, fetch call, close call, or final call. |
public Connection getConnection(); | The method obtains the JDBC connection handle for this stored procedure call and returns a JDBC object that represents the calling application's connection to the database. It is analogous to the result of a null SQLConnect() call in a C stored procedure. |
public void close(); | This method is called by the database at the end of a UDF evaluation, if the UDF was created with the FINAL CALL option. It is analogous to the final call for a C UDF. If a Java UDF class does not implement this method, this event is ignored. |
public boolean isNull(int i) | This method tests whether an input argument with the given index is an SQL NULL. |
|
These methods set an output argument to the given value. An exception
is thrown if anything goes wrong, including the following:
|
public void setSQLstate(String string); | This method may be called from a UDF to set the SQLSTATE to be returned
from this call. If the string is not acceptable as an SQLSTATE, an exception
is thrown. The user may set the SQLSTATE in the external program to return
an error or warning from the function. In this case, the SQLSTATE must contain
one of the following:
|
public void setSQLmessage(String string); | This method is similar to the setSQLstate method. It sets the SQL message result. If the string is not acceptable (for example, longer than 70 characters), an exception is thrown. |
public String getFunctionName(); | This method returns the name of the processing UDF. |
public String getSpecificName(); | This method returns the specific name of the processing UDF. |
public byte[] getDBinfo(); | This method returns a raw, unprocessed DBINFO structure for the processing UDF, as a byte array. The UDF must have been registered (using CREATE FUNCTION) with the DBINFO option. |
|
These methods return the value of the appropriate field from the DBINFO structure of the processing UDF. The UDF must have been registered (using CREATE FUNCTION) with the DBINFO option. The getDBtbschema(), getDBtbname(), and getDBcolname() methods only return meaningful information if a user-defined function is specified on the right side of a SET™ clause in an UPDATE statement. |
public int getCCSID(); | This method returns the CCSID of the job. |
public byte[] getScratchpad(); | This method returns a copy of the scratchpad of the currently processing UDF. You must first declare the UDF with the SCRATCHPAD option. |
public void setScratchpad(byte ab[]); | This method overwrites the scratchpad of the currently processing UDF with the contents of the given byte array. You must first declare the UDF with the SCRATCHPAD option. The byte array must have the same size as getScratchpad() returns. |
public int getCallType(); | This method returns the type of call that is currently being made.
These values correspond to the C values defined in sqludf.h. Possible return
values include the following:
|