The CREATE FUNCTION (External Table) statement is used to register a user-defined external table function at the current server.
A table function can be used in the FROM clause of a SELECT, and returns a table to the SELECT by returning one row at a time.
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 only if DYNAMICRULES run behavior is in effect for the package (SQLSTATE 42509).
Group privileges are not considered for any table or view specified in the CREATE FUNCTION statement.
To create a fenced function, no additional authorities or privileges are required.
To replace an existing function, the authorization ID of the statement must be the owner of the existing function (SQLSTATE 42501).
If the SECURED option is specified, the authorization ID of the statement must include SECADM or CREATE_SECURE_OBJECT authority (SQLSTATE 42501).
>>-CREATE--+------------+--FUNCTION--function-name--------------> '-OR REPLACE-' >--(--+-------------------------------+--)--●-------------------> | .-,-------------------------. | | V | | '---| parameter-declaration |-+-' .-,-------------------------------------------. V | >--RETURNS--+-TABLE--(----column-name--| data-type2 |--+------------+-+--)-+--> | '-AS LOCATOR-' | '-GENERIC TABLE------------------------------------------------' >--| option-list |--------------------------------------------->< parameter-declaration |--+----------------+--| data-type1 |--+--------------------+--+------------+--| '-parameter-name-' '-| default-clause |-' '-AS LOCATOR-' data-type1, data-type2 |--+-| built-in-type |----+-------------------------------------| +-distinct-type-name---+ +-structured-type-name-+ '-REF--(--type-name--)-' built-in-type |--+-+-SMALLINT----+----------------------------------------------------------------------+--| | +-+-INTEGER-+-+ | | | '-INT-----' | | | '-BIGINT------' | | .-(5,0)-------------------. | +-+-+-DECIMAL-+-+--+-------------------------+-----------------------------------------+ | | '-DEC-----' | | .-,0-------. | | | '-+-NUMERIC-+-' '-(integer-+----------+-)-' | | '-NUM-----' '-,integer-' | | .-(53)------. | +-+-FLOAT--+-----------+--+------------------------------------------------------------+ | | '-(integer)-' | | | +-REAL------------------+ | | | .-PRECISION-. | | | '-DOUBLE--+-----------+-' | | .-(34)-. | +-DECFLOAT--+------+-------------------------------------------------------------------+ | '-(16)-' | | .-(1)------------------------. | +-+-+-+-CHARACTER-+--+----------------------------+----------+--+------------------+-+-+ | | | '-CHAR------' '-(integer-+-------------+-)-' | | (1) | | | | | | +-OCTETS------+ | '-FOR BIT DATA-----' | | | | | '-CODEUNITS32-' | | | | | '-+-VARCHAR----------------+--(integer-+-------------+-)-' | | | | '-+-CHARACTER-+--VARYING-' +-OCTETS------+ | | | | '-CHAR------' '-CODEUNITS32-' | | | | .-(1M)-----------------------------. | | | '-+-CLOB------------------------+--+----------------------------------+------------' | | '-+-CHARACTER-+--LARGE OBJECT-' '-(integer-+---+-+-------------+-)-' | | '-CHAR------' +-K-+ +-OCTETS------+ | | +-M-+ '-CODEUNITS32-' | | '-G-' | | .-(1)------------------------. | +-+-GRAPHIC--+----------------------------+------+-------------------------------------+ | | '-(integer-+-------------+-)-' | | | | +-CODEUNITS16-+ | | | | '-CODEUNITS32-' | | | +-VARGRAPHIC--(integer-+-------------+-)-------+ | | | +-CODEUNITS16-+ | | | | '-CODEUNITS32-' | | | | .-(1M)-----------------------------. | | | '-DBCLOB--+----------------------------------+-' | | '-(integer-+---+-+-------------+-)-' | | +-K-+ +-CODEUNITS16-+ | | +-M-+ '-CODEUNITS32-' | | '-G-' | | .-(1)-------. | +-+-+-+-NCHAR-------------------+--+-----------+------+-------+------------------------+ | | | '-NATIONAL--+-CHAR------+-' '-(integer)-' | | | | | | '-CHARACTER-' | | | | | '-+-NVARCHAR-------------------------+--(integer)-' | | | | +-NCHAR VARYING--------------------+ | | | | '-NATIONAL--+-CHAR------+--VARYING-' | | | | '-CHARACTER-' | | | | .-(1M)-------------. | | | '-+-NCLOB---------------------------+--+------------------+-' | | +-NCHAR LARGE OBJECT--------------+ '-(integer-+---+-)-' | | '-NATIONAL CHARACTER LARGE OBJECT-' +-K-+ | | +-M-+ | | '-G-' | | .-(1M)-------------. | +-+-BLOB----------------+--+------------------+----------------------------------------+ | '-BINARY LARGE OBJECT-' '-(integer-+---+-)-' | | +-K-+ | | +-M-+ | | '-G-' | +-+-DATE-------------------------+-----------------------------------------------------+ | +-TIME-------------------------+ | | | .-(--6--)-------. | | | '-TIMESTAMP--+---------------+-' | | '-(--integer--)-' | +-XML----------------------------------------------------------------------------------+ | .-SYSPROC.-. (2) (3) | '-+----------+--DB2SECURITYLABEL-------------------------------------------------------' default-clause |--DEFAULT--+-NULL-------------+--------------------------------| +-constant---------+ +-special-register-+ +-global-variable--+ '-(--expression--)-' option-list (4) |--●--LANGUAGE--+-C----+------●--+-------------------------+----> +-JAVA-+ '-SPECIFIC--specific-name-' +-CLR--+ '-OLE--' >--●--EXTERNAL--+----------------------+--●---------------------> '-NAME--+-'string'---+-' '-identifier-' >--PARAMETER STYLE--+-DB2GENERAL-+--●---------------------------> '-SQL--------' .-NOT DETERMINISTIC-. >--+------------------------------+--●--+-------------------+---> '-PARAMETER CCSID--+-ASCII---+-' '-DETERMINISTIC-----' '-UNICODE-' .-FENCED------------------------. >--●--+-------------------------------+--●----------------------> +-FENCED--●--+-THREADSAFE-----+-+ | '-NOT THREADSAFE-' | | .-THREADSAFE-. | '-NOT FENCED--●--+------------+-' .-RETURNS NULL ON NULL INPUT-. .-READS SQL DATA-. >--+----------------------------+--●--+----------------+--●-----> '-CALLED ON NULL INPUT-------' +-NO SQL---------+ '-CONTAINS SQL---' .-STATIC DISPATCH-. .-EXTERNAL ACTION----. >--+-----------------+--●--+--------------------+--●------------> '-NO EXTERNAL ACTION-' .-NO SCRATCHPAD----------. .-NO FINAL CALL-. >--+------------------------+--●--+---------------+--●----------> | .-100----. | '-FINAL CALL----' '-SCRATCHPAD--+--------+-' '-length-' >--+-DISALLOW PARALLEL------------------------------------------------------------------+--> | .-DATABASE PARTITIONS-. | '-ALLOW PARALLEL--EXECUTE ON--ALL--+---------------------+--RESULT TABLE DISTRIBUTED-' .-NO DBINFO-. >--●--+-----------+--●--+----------------------+--●-------------> '-DBINFO----' '-CARDINALITY--integer-' >--+-----------------------------+--●---------------------------> '-TRANSFORM GROUP--group-name-' .-INHERIT SPECIAL REGISTERS-. .-NOT SECURED-. >--+---------------------------+--●--+-------------+------------| '-SECURED-----'
If the function is referenced in the definition of a row permission or a column mask, the function cannot be replaced (SQLSTATE 42893).
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' (SQLSTATE 42939).
A number of names used as keywords in predicates are reserved for system use, and cannot be used as a function-name (SQLSTATE 42939). The names are SOME, ANY, ALL, NOT, AND, OR, BETWEEN, NULL, LIKE, EXISTS, IN, UNIQUE, OVERLAPS, SIMILAR, MATCH, and the comparison operators.
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 table function should not be given the same name as a built-in function.
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). A weakly typed distinct type specified for a parameter is considered to be the same data type as the source type of the distinct type. For a Unicode database, CHAR(13) and GRAPHIC(8) are considered to be the same type. 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 returns an error (SQLSTATE 42723).
For a user-defined structured type, the appropriate transform functions must exist in the associated transform group.
For a reference type, the parameter can be specified as REF(type-name) if the parameter is unscoped.
The expression can be any expression of the type described in "Expressions". If a default value is not specified, the parameter has no default and the corresponding argument cannot be omitted on invocation of the procedure. The maximum size of the expression is 64K bytes.
The default expression must not modify SQL data (SQLSTATE 428FL or SQLSTATE 429BL). The expression must be assignment compatible to the parameter data type (SQLSTATE 42821).
A default cannot be specified for a parameter of type ARRAY, ROW, or CURSOR (SQLSTATE 429BB).
The AS LOCATOR clause has no effect on determining whether data types can be promoted, nor does it affect the function signature, which is used in function resolution.
If the function is FENCED and has the NO SQL option, the AS LOCATOR clause cannot be specified (SQLSTATE 42613).
The valid types for use with this clause are discussed in the "CREATE FUNCTION (external scalar)" statement topic.
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, SQLyymmddhhmmssxxx.
If NAME clause is not specified "NAME function-name" is assumed.
The 'string' option is a string constant with a maximum of 254 bytes. The format used for the string is dependent on the LANGUAGE specified.
The string specified is the library name and function within the 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 executed. 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.
>>-'--+-library_id-------+--+------------+--'------------------>< '-absolute_path_id-' '-!--func_id-'
Extraneous blanks are not permitted within the single quotation marks.
Operating system | Library name location |
---|---|
Linux AIX® Solaris HP-UX |
If myfunc was given as the library_id, and the database manager is being run from /u/production, the database manager will look for the function in library /u/production/sqllib/function/myfunc |
Windows | The database manager will look for the function in a directory path that is specified by the LIBPATH or PATH environment variable |
Operating system | Full path name example |
---|---|
Linux AIX Solaris HP-UX |
A value of '/u/jchui/mylib/myfunc' would cause the database manager to look in /u/jchui/mylib for the myfunc shared library. |
Windows | A value of 'd:\mylib\myfunc.dll' would cause the database manager to load the dynamic link library, myfunc.dll, from the d:\mylib directory. If an absolute path ID is being used to identify the routine body, be sure to append the .dll extension. |
Operating system | Entry point name of the function |
---|---|
Linux AIX Solaris HP-UX |
A value of '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. |
Windows | A value of 'mymod!func8' would direct the database manager to load the mymod.dll file and to call the func8() function in the dynamic link library (DLL). |
If the string is not properly formed, an error is returned (SQLSTATE 42878).
In any case, the body of every external function should be in a directory that is available on every database partition.
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 executed. 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.
>>-'--+----------+--class_id--+-.-+--method_id--'-------------->< '-jar_id :-' '-!-'
Extraneous blanks are not permitted within the single quotation marks.
Operating system | Directory the Java virtual machine will look in for the classes |
---|---|
Linux AIX Solaris HP-UX |
'.../myPacks/UserFuncs/' |
Windows | '...\myPacks\UserFuncs\' |
The string specified represents the .NET assembly (library or executable), the class within that assembly, and the method within the class that the database manager invokes to execute the function being created. The module, class, and method do not need to exist when the CREATE FUNCTION statement is executed. However, when the function is used in an SQL statement, the module, class, and method must exist and be accessible from the database server machine; otherwise, an error is returned (SQLSTATE 42724).
C++ routines that are compiled with the '/clr' compiler option to indicate that they include managed code extensions must be cataloged as 'LANGUAGE CLR' and not 'LANGUAGE C'. The database server needs to know that the .NET infrastructure is being utilized in a user-defined function in order to make necessary runtime decisions. All user-defined functions using the .NET infrastructure must be cataloged as 'LANGUAGE CLR'.
>>-'--assembly--:--class_id--!--method_id--'-------------------><
The name must be enclosed by single quotation marks. Extraneous blanks are not permitted.
For example, c:\sqllib\function.
If the file resides in a subdirectory of the install function directory, the subdirectory can be given before the file name rather than specifying the full path.
For example, if your install directory is c:\sqllib and your assembly file is c:\sqllib\function\myprocs\mydotnet.dll, it is only necessary to specify 'myprocs\mydotnet.dll' for the assembly.
The case sensitivity of this parameter is the same as the case sensitivity of the file system.
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 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 is returned (SQLSTATE 42724).
>>-'--+-progid-+--!--method_id--'------------------------------>< '-clsid--'
Extraneous blanks are not permitted within the single quotation marks.
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).
{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.
LANGUAGE OLE is supported for user-defined functions for this database product only in Windows 32-bit operating systems.
For information about creating LANGUAGE OLE DB external table functions, see "CREATE FUNCTION (OLE DB External Table)".
If the database is not a Unicode database, and a function with PARAMETER CCSID UNICODE is created, the function cannot have any graphic types or user-defined types (SQLSTATE 560C1).
If the database is not a Unicode database, and the alternate collating sequence has been specified in the database configuration, functions can be created with either PARAMETER CCSID ASCII or PARAMETER CCSID UNICODE. All string data passed into and out of the function will be converted to the appropriate code page.
This clause cannot be specified with LANGUAGE OLE, LANGUAGE JAVA, or LANGUAGE CLR (SQLSTATE 42613).
If a function is registered as FENCED, the database manager protects its internal resources (for example, 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.
Only FENCED can be specified for a function with LANGUAGE OLE or NOT THREADSAFE (SQLSTATE 42613).
If the function is FENCED and has the NO SQL option, the AS LOCATOR clause cannot be specified (SQLSTATE 42613).
Either SYSADM authority, DBADM authority, or a special authority (CREATE_NOT_FENCED_ROUTINE) is required to register a user-defined function as NOT FENCED.
LANGUAGE CLR user-defined functions cannot be created when specifying the NOT FENCED clause (SQLSTATE 42601).
For FENCED functions, THREADSAFE is the default if the LANGUAGE is JAVA or CLR. For all other languages, NOT THREADSAFE is the default. If the function is defined with LANGUAGE OLE, THREADSAFE may not be specified (SQLSTATE 42613).
For NOT FENCED functions, THREADSAFE is the default. NOT THREADSAFE cannot be specified (SQLSTATE 42613).
If RETURNS NULL ON NULL INPUT is specified, and if, at table function OPEN time, any of the function's arguments are null, then the user-defined function is not called. The result of the attempted table function scan is the empty table (a table with no rows).
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 compatibility. Similarly, NOT NULL CALL may be used as a synonym for RETURNS NULL ON NULL INPUT.
For the classification of each statement, see SQL statements that can be executed in routines and triggers.
The default is READS SQL DATA.
A function with external actions might return incorrect results if the function is executed by parallel tasks. For example, if the function sends a note for each initial call to it, one note is sent for each parallel task instead of once for the function. Specify the DISALLOW PARALLEL clause for functions that do not work correctly with parallelism.
SELECT A.C1, B.C2
FROM TABLE (UDFX(:hv1)) AS A,
TABLE (UDFX(:hv1)) AS B
WHERE ...
If NO FINAL CALL is specified or defaulted, then the external table function should clean up any such resources on the CLOSE call, as the database server will re-initialize the scratchpad on each OPEN call. This determination of FINAL CALL or NO FINAL CALL and the associated behavior of the scratchpad could be an important consideration, particularly if the table function will be used in a subquery or join, since that is when multiple OPEN calls can occur during the execution of a statement.
(As previously outlined, the FINAL CALL/NO FINAL CALL keyword is used to control the re-initialization of the scratchpad, and also dictates when the external table function should release resources anchored in the scratchpad.)
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.
For external table functions, the call-type argument is ALWAYS present, regardless of which option is chosen.
If the final call is being made because of an interrupt or end-of-transaction, the UDF may not issue any SQL statements except for CLOSE cursor (SQLSTATE 38505). A special value is passed in the "call type" argument for these special final call situations.
If the CARDINALITY clause is not specified for a table function, assume a finite value is assumed as a default; the same value assumed for tables for which the RUNSTATS utility has not gathered statistics.
Warning: If a function does, in fact, have infinite cardinality - that is, it returns a row every time it is called to do so, and never returns the "end-of-table" condition - then queries that require the end-of-table condition to correctly function will be infinite, and will have to be interrupted. Examples of such queries are those that contain a GROUP BY or an ORDER BY clause. Writing such UDFs is not recommended.
No changes to the special registers are passed back to the invoker of the function.
Non-updatable special registers, such as the datetime special registers, reflect a property of the statement currently executing, and are therefore set to their default values.
The SECURED attribute is considered to be an assertion that declares the user has established a change control audit procedure for all changes to the user-defined function. The database manager assumes that such a control audit procedure is in place for all subsequent ALTER FUNCTION statements or changes to external packages.
Within the context of a single session, the UDF will always return the same table, and therefore it is defined as DETERMINISTIC. Note the RETURNS clause which defines the output from DOCMATCH. FINAL CALL must be specified for each table function. In addition, the DISALLOW PARALLEL keyword is added as table functions cannot operate in parallel. Although the size of the output for DOCMATCH is highly variable, CARDINALITY 20 is a representative value, and is specified to help the database optimizer.
CREATE FUNCTION DOCMATCH (VARCHAR(30), VARCHAR(255))
RETURNS TABLE (DOC_ID CHAR(16))
EXTERNAL NAME '/common/docfuncs/rajiv/udfmatch'
LANGUAGE C
PARAMETER STYLE SQL
NO SQL
DETERMINISTIC
NO EXTERNAL ACTION
NOT FENCED
SCRATCHPAD
FINAL CALL
DISALLOW PARALLEL
CARDINALITY 20
CREATE FUNCTION MAIL()
RETURNS TABLE (TIMERECEIVED DATE,
SUBJECT VARCHAR(15),
SIZE INTEGER,
TEXT VARCHAR(30))
EXTERNAL NAME 'tfmail.header!list'
LANGUAGE OLE
PARAMETER STYLE SQL
NOT DETERMINISTIC
FENCED
CALLED ON NULL INPUT
SCRATCHPAD
FINAL CALL
NO SQL
EXTERNAL ACTION
DISALLOW PARALLEL