IBM Books

SQL Reference

CREATE FUNCTION (External Scalar)

This statement is used to register a user-defined external scalar function with an application server. A scalar function returns a single value each time it is invoked, and is in general valid wherever an SQL expression is valid

Invocation

This statement can be embedded in an application program or issued through the use of dynamic SQL statements. It is an executable statement that can be dynamically prepared. However, if the bind option DYNAMICRULES BIND applies, the statement cannot be dynamically prepared (SQLSTATE 42509).

Authorization

The privileges held by the authorization ID of the statement must include at least one of the following:

To create a not-fenced function, the privileges held by the authorization ID of the statement must also include at least one of the following:

To create a fenced function, no additional authorities or privileges are required.

If the authorization ID has insufficient authority to perform the operation, an error (SQLSTATE 42502) is raised.

Syntax

>>-CREATE FUNCTION--function-name------------------------------->
 
>----(--+------------------------------------+---)---*---------->
        |  .-,----------------------------.  |
        |  V                              |  |
        '----data-type1--+-------------+--+--'
                         '-AS LOCATOR--'
 
>----RETURNS--+-data-type2--+-------------+------------------------+>
              |             '-AS LOCATOR--'                        |
              '-data-type3--CAST FROM--data-type4--+-------------+-'
                                                   '-AS LOCATOR--'
 
>----*----+--------------------------+--*----------------------->
          '-SPECIFIC--specific-name--'
 
>-----EXTERNAL--+----------------------+---*-------------------->
                '-NAME--+-'string'---+-'
                        '-identifier-'
 
>----LANGUAGE--+-C----+--*---PARAMETER STYLE--+-DB2SQL-----+---->
               +-JAVA-+                       +-DB2GENERAL-+
               '-OLE--'                       '-JAVA-------'
 
          .-NOT DETERMINISTIC--.       .-FENCED-----.
>----*----+--------------------+--*----+------------+----------->
          |               (1)  |       '-NOT FENCED-'
          '-DETERMINISTIC------'
 
      .-RETURNS NULL ON NULL INPUT--.  (2)
>-----+-----------------------------+---------*---NO SQL--*----->
      '-CALLED ON NULL INPUT--------'
 
      .-EXTERNAL ACTION----.       .-NO SCRATCHPAD--.
>-----+--------------------+--*----+----------------+--*-------->
      '-NO EXTERNAL ACTION-'       '-SCRATCHPAD-----'
 
      .-NO FINAL CALL--.       .-ALLOW PARALLEL----.
>-----+----------------+--*----+-------------------+--*--------->
      '-FINAL CALL-----'       '-DISALLOW PARALLEL-'
 
      .-NO DBINFO--.
>-----+------------+--*----------------------------------------><
      '-DBINFO-----'
 

Notes:

  1. NOT VARIANT may be specified in place of DETERMINISTIC and VARIANT may be specified in place of NOT DETERMINISTIC.

  2. NULL CALL may be specified in place of CALLED ON NULL INPUT and NOT NULL CALL may be specified in place of RETURNS NULL ON NULL INPUT.

Description

function-name
Names the function being defined. It is a qualified or unqualified name that designates a function. The unqualified form of function-name is an SQL identifier (with a maximum length of 18). In dynamic SQL statements, the CURRENT SCHEMA special register is used as a qualifier for an unqualified object name. In static SQL statements the QUALIFIER precompile/bind option implicitly specifies the qualifier for unqualified object names. The qualified form is a schema-name followed by a period and an SQL identifier.

The name, including the implicit or explicit qualifiers, together with the number of parameters and the data type of each parameter (without regard for any length, precision or scale attributes of the data type) must not identify a function described in the catalog (SQLSTATE 42723). The unqualified name, together with the number and data types of the parameters, while of course unique within its schema, need not be unique across schemas.

If a two-part name is specified, the schema-name cannot begin with "SYS". Otherwise, an error (SQLSTATE 42939) is raised.

A number of names used as keywords in predicates are reserved for system use, and may not be used as a function-name. The names are SOME, ANY, ALL, NOT, AND, OR, BETWEEN, NULL, LIKE, EXISTS, IN, UNIQUE, OVERLAPS, SIMILAR, MATCH and the comparison operators as described in Basic Predicate. Failure to observe this rule will lead to an error (SQLSTATE 42939).

In general, the same name can be used for more than one function if there is some difference in the signature of the functions.

Although there is no prohibition against it, an external user-defined function should not be given the same name as a built-in function, unless it is an intentional override. To give a function having a different meaning the same name (for example, LENGTH, VALUE, MAX), with consistent arguments, as a built-in scalar or column function, is to invite trouble for dynamic SQL statements, or when static SQL applications are rebound; the application may fail, or perhaps worse, may appear to run successfully while providing a different result.

(data-type1,...)
Identifies the number of input parameters of the function, and specifies the data type of each parameter. One entry in the list must be specified for each parameter that the function will expect to receive. No more than 90 parameters are allowed. If this limit is exceeded, an error (SQLSTATE 54023) is raised.

It is possible to register a function that has no parameters. In this case, the parentheses must still be coded, with no intervening data types. For example,

  CREATE FUNCTION WOOFER() ...

No two identically-named functions within a schema are permitted to have exactly the same type for all corresponding parameters. Lengths, precisions and scales are not considered in this type comparison. Therefore CHAR(8) and CHAR(35) are considered to be the same type, as are DECIMAL(11,2) and DECIMAL (4,3). There is some further bundling of types that causes them to be treated as the same type for this purpose, such as DECIMAL and NUMERIC. A duplicate signature raises an SQL error (SQLSTATE 42723).

For example, given the statements:

  CREATE FUNCTION PART (INT, CHAR(15)) ...
  CREATE FUNCTION PART (INTEGER, CHAR(40)) ...
 
  CREATE FUNCTION ANGLE (DECIMAL(12,2)) ...
  CREATE FUNCTION ANGLE (DEC(10,7)) ...

the second and fourth statements would fail because they are considered to be duplicate functions.

data-type1
Specifies the data type of the parameter.

  • SQL data type specifications and abbreviations which may be specified in the data-type1 definition of a CREATE TABLE statement and have a correspondence in the language that is being used to write the function may be specified. See the language-specific sections of the Application Development Guide for details on the mapping between the SQL data types and host language data types with respect to user-defined functions.

  • DECIMAL (and NUMERIC) are invalid with LANGUAGE C and OLE (SQLSTATE 42815). For alternatives to using DECIMAL refer to Application Development Guide.

  • REF(type-name) cannot be specified as the data type of a parameter (SQLSTATE 42997).

AS LOCATOR
For the LOB types or distinct types which are based on a LOB type, the AS LOCATOR clause can be added. This indicates that a LOB locator is to be passed to the UDF instead of the actual value. This saves greatly in the number of bytes passed to the UDF, and may save as well in performance, particularly in the case where only a few bytes of the value are actually of interest to the UDF. Use of LOB locators in UDFs are described in Application Development Guide.

Here is an example which illustrates the use of the AS LOCATOR clause in parameter definitions:

   CREATE FUNCTION foo (CLOB(10M) AS LOCATOR, IMAGE AS LOCATOR)
                   ...

which assumes that IMAGE is a distinct type based on one of the LOB types.

Note also that for argument promotion purposes, the AS LOCATOR clause has no effect. In the example the types are considered to be CLOB and IMAGE respectively, which would mean that a CHAR or VARCHAR argument could be passed to the function as the first argument. Likewise, the AS LOCATOR has no effect on the function signature, which is used in matching the function (a) when referenced in DML, by a process called "function resolution", and (b) when referenced in a DDL statement such as COMMENT ON or DROP. In fact the clause may or may not be used in COMMENT ON or DROP with no significance.

An error (SQLSTATE 42601) is raised if AS LOCATOR is specified for a type other than a LOB or a distinct type based on a LOB.

If the function is FENCED, the AS LOCATOR clause cannot be specified (SQLSTATE 42613).

RETURNS
This mandatory clause identifies the output of the function.

data-type2
Specifies the data type of the output.

In this case, exactly the same considerations apply as for the parameters of external functions described above under data-type1 for function parameters.

AS LOCATOR
For LOB types or distinct types which are based on LOB types, the AS LOCATOR clause can be added. This indicates that a LOB locator is to be passed from the UDF instead of the actual value.

data-type3 CAST FROM data-type4
Specifies the data type of the output.

This form of the RETURNS clause is used to return a different data type to the invoking statement from the data type that was returned by the function code. For example, in

   CREATE FUNCTION GET_HIRE_DATE(CHAR(6))
           RETURNS DATE CAST FROM CHAR(10)
                   ...

the function code returns a CHAR(10) value to the database manager, which, in turn, converts it to a DATE and passes that value to the invoking statement. The data-type4 must be castable to the data-type3 parameter. If it is not castable, an error (SQLSTATE 42880) is raised (for the definition of castable, see Casting Between Data Types).

Since the length, precision or scale for data-type3 can be inferred from data-type4, it not necessary (but still permitted) to specify the length, precision, or scale for paramaterized types specified for data-type3. Instead empty parentheses may be used (for example VARCHAR() may be used). FLOAT() cannot be used (SQLSTATE 42601) since parameter value indicates different data types (REAL or DOUBLE).

A distinct type is not valid as the type specified in data-type4 (SQLSTATE 42815).

The cast operation is also subject to run-time checks that might result in conversion errors being raised.

AS LOCATOR
For data-type4 specifications that are LOB types or distinct types which are based on LOB types, the AS LOCATOR clause can be added. This indicates that a LOB locator is to be passed back from the UDF instead of the actual value. Use of LOB locators in UDFs are described in Application Development Guide.

SPECIFIC specific-name
Provides a unique name for the instance of the function that is being defined. This specific name can be used when sourcing on this function, dropping the function, or commenting on the function. It can never be used to invoke the function. The unqualified form of specific-name is an SQL identifier (with a maximum length of 18). The qualified form is a schema-name followed by a period and an SQL identifier. The name, including the implicit or explicit qualifier, must not identify another function instance that exists at the application server; otherwise an error (SQLSTATE 42710) is raised.

The specific-name may be the same as an existing function-name.

If no qualifier is specified, the qualifier that was used for function-name is used. If a qualifier is specified, it must be the same as the explicit or implicit qualifier of function-name or an error (SQLSTATE 42882) is raised.

If specific-name is not specified, a unique name is generated by the database manager. The unique name is SQL followed by a character timestamp, SQLyymmddhhmmsshhn.

EXTERNAL
This clause indicates that the CREATE FUNCTION statement is being used to register a new function based on code written in an external programming language and adhering to the documented linkage conventions and interface.

If NAME clause is not specified "NAME function-name" is assumed.

NAME 'string'
This clause identifies the name of the user-written code which implements the function being defined.

The 'string' option is a string constant with a maximum of 254 characters. The format used for the string is dependent on the LANGUAGE specified.

  • For LANGUAGE C:

    The string specified is the library name and function within library, which the database manager invokes to execute the user-defined function being CREATEd. The library (and the function within the library) do not need to exist when the CREATE FUNCTION statement is performed. However, when the function is used in an SQL statement, the library and function within the library must exist and be accessible from the database server machine, otherwise an error (SQLSTATE 42724) is raised.

    >>-'--+-library_id-------+---+-------------+---'---------------><
          '-absolute_path_id-'   '-!--func_id--'
     
    

    Extraneous blanks are not permitted within the single quotes.

    library_id
    Identifies the library name containing the function. The database manager will look for the library in the .../sqllib/function directory (UNIX-based systems), or ...\instance_name\function directory (OS/2, Windows 95 and Windows NT as specified by the DB2INSTPROF registry variable), where the database manager will locate the controlling sqllib directory which is being used to run the database manager. For example, the controlling sqllib directory in UNIX-based systems is /u/$DB2INSTANCE/sqllib.

    'myfunc' were the library_id in a UNIX-based system it would cause the database manager to look for the function in library /u/production/sqllib/function/myfunc, provided the database manager is being run from /u/production.

    For OS/2, Windows 95 and Windows NT, the database manager will look in the LIBPATH or PATH if the library_id is not located in the function directory.

    In OS/2 the library_id should not contain more than 8 characters.

    absolute_path_id
    Identifies the full path name of the file containing the function.

    In a UNIX-based system, for example, '/u/jchui/mylib/myfunc' would cause the database manager to look in /u/jchui/mylib for the myfunc shared library.

    In OS/2, Windows 95 and Windows NT, 'd:\mylib\myfunc' would cause the database manager to load dynamic link library, myfunc.dll file, from the d:\mylib directory.

    In OS/2 the last part of this specification (i.e. the name of the dll), should not contain more than 8 characters.

    ! func_id
    Identifies the entry point name of the function to be invoked. The ! serves as a delimiter between the library id and the function id. If ! func_id is omitted, the database manager will use the default entry point established when the library was linked.

    In a UNIX-based system, for example, 'mymod!func8' would direct the database manager to look for the library $inst_home_dir/sqllib/function/mymod and to use entry point func8 within that library.

    In OS/2, Windows 95 and Windows NT, 'mymod!func8' would direct the database manager to load the mymod.dll file and call the func8() function in the dynamic link library (DLL).

    If the string is not properly formed, an error (SQLSTATE 42878) is raised.

    The body of every external function should be in a directory which is mounted and available on every partition of the database.

  • For LANGUAGE JAVA:

    The string specified contains the optional jar file identifier, class identifier and method identifier, which the database manager invokes to execute the user-defined function being CREATEd. The class identifier and method identifier do not need to exist when the CREATE FUNCTION statement is performed. If a jar_id is specified, it must exist when the CREATE FUNCTION statement is executed. However, when the function is used in an SQL statement, the method identifier must exist and be accessible from the database server machine, otherwise an error (SQLSTATE 42724) is raised.

    >>-'----+----------+--class_id----+-.-+--method_id--'----------><
            '-jar_id :-'              '-!-'
     
    

    Extraneous blanks are not permitted within the single quotes.

    jar_id
    Identifies the jar identifier given to the jar collection when it was installed in the database. It can be either a simple identifier, or a schema qualified identifier. Examples are 'myJar' and 'mySchema.myJar'.

    class_id
    Identifies the class identifier of the Java object. If the class is part of a package, the class identifier part must include the complete package prefix, for example, 'myPacks.UserFuncs'. The Java virtual machine will look in directory '.../myPacks/UserFuncs/' for the classes. In OS/2 and Windows 95 and Windows NT, the Java virtual machine will look in directory '...\myPacks\UserFuncs\'.

    method_id
    Identifies the method name of the Java object to be invoked.

  • For LANGUAGE OLE:

    The string specified is the OLE programmatic identifier (progid) or class identifier (clsid), and method identifier, which the database manager invokes to execute the user-defined function being CREATEd. The programmatic identifier or class identifier, and method identifier do not need to exist when the CREATE FUNCTION statement is performed. However, when the function is used in an SQL statement, the method identifier must exist and be accessible from the database server machine, otherwise an error (SQLSTATE 42724) is raised.

    >>-'--+-progid-+---!--method_id--'-----------------------------><
          '-clsid--'
     
    

    Extraneous blanks are not permitted within the single quotes.

    progid
    Identifies the programmatic identifier of the OLE object.

    progid is not interpreted by the database manager but only forwarded to the OLE APIs at run time. The specified OLE object must be creatable and support late binding (also called IDispatch-based binding).

    clsid
    Identifies the class identifier of the OLE object to create. It can be used as an alternative for specifying a progid in the case that an OLE object is not registered with a progid. The clsid has the form:

    {nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn}

    where 'n' is an alphanumeric character. clsid is not interpreted by the database manager but only forwarded to the OLE APIs at run time.

    method_id
    Identifies the method name of the OLE object to be invoked.

NAME identifier
This identifier specified is an SQL identifier. The SQL identifier is used as the library-id in the string. Unless it is a delimited identifier, the identifier is folded to upper case. If the identifier is qualified with a schema name, the schema name portion is ignored. This form of NAME can only be used with LANGUAGE C.

LANGUAGE
This mandatory clause is used to specify the language interface convention to which the user-defined function body is written.

C
This means the database manager will call the user-defined function as if it were a C function. The user-defined function must conform to the C language calling and linkage convention as defined by the standard ANSI C prototype.

JAVA
This means the database manager will call the user-defined function as a method in a Java class.

OLE
This means the database manager will call the user-defined function as if it were a method exposed by an OLE automation object. The user-defined function must conform with the OLE automation data types and invocation mechanism as described in the OLE Automation Programmer's Reference.

LANGUAGE OLE is only supported for user-defined functions stored in DB2 for Windows 95 and Windows NT.

PARAMETER STYLE
This clause is used to specify the conventions used for passing parameters to and returning the value from functions.

DB2SQL
Used to specify the conventions for passing parameters to and returning the value from external functions that conform to C language calling and linkage conventions or methods exposed by OLE automation objects. This must be specified when LANGUAGE C or LANGUAGE OLE is used.

DB2GENERAL
Used to specify the conventions for passing parameters to and returning the value from external functions that are defined as a method in a Java class. This can only specified when LANGUAGE JAVA is used.

The value DB2GENRL may be used as a synonym for DB2GENERAL.

JAVA
This means that the function will use a parameter passing convention that conforms to the Java language and SQLJ Routines specification. This can only be specified when LANGUAGE JAVA is used. PARAMETER STYLE JAVA functions do not support the FINAL CALL, SCRATCHPAD or DBINFO clauses.

Refer to Application Development Guide for details on passing parameters.

DETERMINISTIC  or  NOT DETERMINISTIC
This optional clause specifies whether the function always returns the same results for given argument values (DETERMINISTIC) or whether the function depends on some state values that affect the results (NOT DETERMINISTIC). That is, a DETERMINISTIC function must always return the same result from successive invocations with identical inputs. Optimizations taking advantage of the fact that identical inputs always produce the same results are prevented by specifying NOT DETERMINISTIC. An example of a NOT DETERMINISTIC function would be a random-number generator. An example of a DETERMINISTIC function would be a function that determines the square root of the input.

FENCED  or  NOT FENCED
This clause specifies whether or not the function is considered "safe" to run in the database manager operating environment's process or address space (NOT FENCED), or not (FENCED).

If a function is registered as FENCED, the database manager insulates its internal resources (e.g. data buffers) from access by the function. Most functions will have the option of running as FENCED or NOT FENCED. In general, a function running as FENCED will not perform as well as a similar one running as NOT FENCED.
Warning:Use of NOT FENCED for functions not adequately checked out can compromise the integrity of DB2. DB2 takes some precautions against many of the common types of inadvertent failures that might occur, but cannot guarantee complete integrity when NOT FENCED user defined functions are used.

Most user-defined functions should be able to run either as FENCED or NOT FENCED. Only FENCED can be specified for a function with LANGUAGE OLE (SQLSTATE 42613).

If the function is FENCED, the AS LOCATOR clause cannot be specified (SQLSTATE 42613).

To change from FENCED to NOT FENCED, the function must be re-registered (by first dropping it and then re-creating it). Either SYSADM authority, DBADM authority or a special authority (CREATE_NOT_FENCED) is required to register a user-defined function as NOT FENCED.

RETURNS NULL ON NULL INPUT or CALLED ON NULL INPUT
This optional clause may be used to avoid a call to the external function if any of the arguments is null. If the user-defined function is defined to have no parameters, then of course this null argument condition cannot arise, and it does not matter how this specification is coded.

If RETURNS NULL ON NULL INPUT is specified and if at execution time any one of the function's arguments is null, the user-defined function is not called and the result is the null value.

If CALLED ON NULL INPUT is specified, then regardless of whether any arguments are null, the user-defined function is called. It can return a null value or a normal (non-null) value. But responsibility for testing for null argument values lies with the UDF.

The value NULL CALL may be used as a synonym for CALLED ON NULL INPUT for backwards and family compatability. Similarly, NOT NULL CALL may be used as a synonym for RETURNS NULL ON NULL INPUT.

NO SQL
This mandatory clauses indicates that the function cannot issue any SQL statements. If it does, an error (SQLSTATE 38502) is raised at run time.

NO EXTERNAL ACTION  or  EXTERNAL ACTION
This optional clause specifies whether or not the function takes some action that changes the state of an object not managed by the database manager. Optimizations that assume functions have no external impacts are prevented by specifying EXTERNAL ACTION. For example: sending a message, ringing a bell, or writing a record to a file.

NO SCRATCHPAD  or  SCRATCHPAD
This optional clause may be used to specify whether a scratchpad is to be provided for an external function. (It is strongly recommended that user-defined functions be re-entrant, so a scratchpad provides a means for the function to "save state" from one call to the next.)

If SCRATCHPAD is specified, then at first invocation of the user-defined function, memory is allocated for a scratchpad to be used by the external function. This scratchpad has the following characteristics:

If SCRATCHPAD is specified, then on each invocation of the user-defined function an additional argument is passed to the external function which addresses the scratchpad.

If NO SCRATCHPAD is specified then no scratchpad is allocated or passed to the external function.

SCRATCHPAD is not supported for PARAMETER STYLE JAVA functions.

NO FINAL CALL  or  FINAL CALL
This optional clause specifies whether a final call is to be made to an external function. The purpose of such a final call is to enable the external function to free any system resources it has acquired. It can be useful in conjunction with the SCRATCHPAD keyword in situations where the external function acquires system resources such as memory and anchors them in the scratchpad. If FINAL CALL is specified, then at execution time:
An additional argument is passed to the external function which specifies the type of call. The types of calls are:

  • Normal call: SQL arguments are passed and a result is expected to be returned.

  • First call: the first call to the external function for this reference to the user-defined function in this SQL statement. The first call is a normal call.

  • Final call: a final call to the external function to enable the function to free up resources. The final call is not a normal call. This final call occurs at the following times:

    • End-of-statement: This case occurs when the cursor is closed for cursor-oriented statements, or when the statement is through executing otherwise.

    • End-of-transaction: This case occurs when the normal end-of-statement does not occur. For example, the logic of an application may for some reason bypass the close of the cursor.

    If a commit operation occurs while a cursor defined as WITH HOLD is open, a final call is made at the subsequent close of the cursor or at the end of the application.

If NO FINAL CALL is specified then no "call type" argument is passed to the external function, and no final call is made.

A description of the scalar UDF processing of these calls when errors occur is included in the Application Development Guide.

FINAL CALL is not supported for PARAMETER STYLE JAVA functions.

ALLOW PARALLEL  or  DISALLOW PARALLEL
This optional clause specifies whether, for a single reference to the function, the invocation of the function can be parallelized. In general, the invocations of most scalar functions should be parallelizable, but there may be functions (such as those depending on a single copy of a scratchpad) that cannot. If either ALLOW PARALLEL or DISALLOW PARALLEL are specified for a scalar function, then DB2 will accept this specification. The following questions should be considered in determining which keyword is appropriate for the function.

In any case, the body of every external function should be in a directory that is mounted and available on every partition of the database.

The syntax diagram indicates that the default value is ALLOW PARALLEL. However, the default is DISALLOW PARALLEL if one or more of the following options is specified in the statement:

NO DBINFO  or  DBINFO
This optional clause specifies whether certain specific information known by DB2 will be passed to the UDF as an additional invocation-time argument (DBINFO) or not (NO DBINFO). NO DBINFO is the default. DBINFO is not supported for LANGUAGE OLE (SQLSTATE 42613) or PARAMETER STYLE JAVA.

If DBINFO is specified, then a structure is passed to the UDF which contains the following information:

Please see the Application Development Guide for detailed information on the structure and how it is passed to the user-defined function.

Notes

Examples

Example 1:  Pellow is registering the CENTRE function in his PELLOW schema. Let those keywords that will default default, and let the system provide a function specific name:

  CREATE FUNCTION CENTRE (INT,FLOAT)
      RETURNS FLOAT
      EXTERNAL NAME 'mod!middle'
      LANGUAGE C
      PARAMETER STYLE DB2SQL
      DETERMINISTIC
      NO SQL
      NO EXTERNAL ACTION

Example 2:  Now, McBride (who has DBADM authority) is registering another CENTRE function in the PELLOW schema, giving it an explicit specific name for subsequent data definition language use, and explicitly providing all keyword values. Note also that this function uses a scratchpad and presumably is accumulating data there that affects subsequent results. Since DISALLOW PARALLEL is specified, any reference to the function is not parallelized and therefore a single scratchpad is used to perform some one-time only initialization and save the results.

  CREATE FUNCTION PELLOW.CENTRE (FLOAT, FLOAT, FLOAT)
      RETURNS DECIMAL(8,4) CAST FROM FLOAT
      SPECIFIC FOCUS92
      EXTERNAL NAME 'effects!focalpt'
      LANGUAGE C   PARAMETER STYLE DB2SQL
      DETERMINISTIC   FENCED   NOT NULL CALL   NO SQL   NO EXTERNAL ACTION
      SCRATCHPAD   NO FINAL CALL 
      DISALLOW PARALLEL

Example 3:  The following is the C language user-defined function program written to implement the rule:

    output = 2 * input - 4

returning NULL if and only if the input is null. It could be written even more simply (that is, without the null checking), if the CREATE FUNCTION statement had used NOT NULL CALL. Further examples of user-defined function programs can be found in the Application Development Guide. The CREATE FUNCTION statement:

    CREATE FUNCTION ntest1 (SMALLINT)
       RETURNS SMALLINT
       EXTERNAL NAME 'ntest1!nudft1'
       LANGUAGE C    PARAMETER STYLE DB2SQL
       DETERMINISTIC   NOT FENCED   NULL CALL
       NO SQL   NO EXTERNAL ACTION

The program code:

 
#include "sqlsystm.h"
/* NUDFT1 IS A USER_DEFINED SCALAR FUNCTION */
/* udft1 accepts smallint input
   and produces smallint output
   implementing the rule:
     if (input is null)
        set output = null;
     else
        set output = 2 * input - 4;
*/
void SQL_API_FN nudft1
     (short *input,      /* ptr to input arg */
      short *output,     /* ptr to where result goes */
      short *input_ind,  /* ptr to input indicator var */
      short *output_ind, /* ptr to output indicator var */
      char sqlstate[6],  /* sqlstate, allows for null-term */
      char fname[28],    /* fully qual func name, nul-term */
      char finst[19],    /* func specific name,  null-term */
      char msgtext[71])  /* msg text buffer,     null-term */
{
   /* first test for null input */
   if (*input_ind == -1)
   {
      /* input is null, likewise output */
      *output_ind = -1;
   }
   else
   {
      /* input is not null.  set output to 2*input-4 */
      *output = 2 * (*input) - 4;
      /* and set out null indicator to zero */
      *output_ind = 0;
   }
 
   /* signal successful completion by leaving sqlstate as is */
   /* and exit */
   return;
}
/* end of UDF: NUDFT1 */

Example 4:  The following registers a Java UDF which returns the position of the first vowel in a string. The UDF is written in Java, is to be run fenced, and is the findvwl method of class javaUDFs.

  CREATE FUNCTION findv ( CLOB(100K) )
       RETURNS INTEGER
       FENCED 
       LANGUAGE JAVA 
       PARAMETER STYLE JAVA 
       EXTERNAL NAME 'javaUDFs.findvwl' 
       NO EXTERNAL ACTION 
       CALLED ON NULL INPUT  
       DETERMINISTIC 
       NO SQL


[ Top of Page | Previous Page | Next Page | Table of Contents | Index ]

[ DB2 List of Books | Search the DB2 Books ]