< Day Day Up > |
Types of User -Defined FunctionsThere are two ways of creating a user-defined function: You can code your own function program from scratch, or you can edit an existing function. Two types of user-defined functions can be written from scratch: scalar functions and table functions . Recall from Chapter 3, "Using DB2 Functions," that scalar functions are applied to a column or expression and operate on a single value. Table functions are a different type of function that, when invoked, return an entire table. A table function is specified in the WHERE clause of a SELECT statement taking the place of a table, view, synonym, or alias. Scalar and table user-defined functions are referred to as external functions because they are written and developed outside of (or external to) DB2. External UDFs must be written in a host programming language. DB2 user-defined functions can be written in Assembler, C, C++, COBOL, Java, or PL/I. A third type of user-defined function can be created from another existing function. This is a sourced function. A sourced function is based on a function that already exists ”it can be based on a built-in function or another user-defined function that has already been created. A sourced function can be based on an existing scalar or column function. So, external functions are coded from scratch, whereas sourced functions are created based on a pre-existing function (see Figure 4.1). Figure 4.1. Sourced versus external UDFs.
User-defined functions are similar in functionality to application subroutines, but user-defined functions are different because they can be used inside SQL statements. In fact, the only way that user-defined functions can be executed is from within an SQL statement. This gives them great power. A user-defined function is not a substitute for an application subroutine, subprogram, or procedure. Instead, user-defined functions are used to extend the functionality of the SQL language. The SchemaUser-defined functions, user-defined distinct types, stored procedures, and triggers all are associated with a schema. By default, the schema name is the authid of the process that issues the CREATE FUNCTION , CREATE DISTINCT TYPE , CREATE PROCEDURE , or CREATE TRIGGER statement. A schema, therefore, is simply a logical grouping of procedural database objects (user-defined functions, user-defined distinct types, stored procedures, and triggers). You can specify a schema name when you create a user-defined function, type, or trigger. If the schema name is not the same as the SQL authorization ID, the issuer of the statement must have either SYSADM or SYSCTRL authority, or the authid of the issuing process must have the CREATEIN privilege on the schema. For example, the following statement creates a user-defined function named NEWFUNC in the schema named MYSCHEMA : CREATE FUNCTION MYSCHEMA.NEWFUNC ... If the MYSCHEMA component was not included in the CREATE statement, the schema would default to the authid of the person (or process) that executed the CREATE statement. In short, the schema is set to the owner of the function. If the CREATE statement was embedded in a program, the owner is the authid of the owner of the plan or package; if the statement is dynamically prepared, the owner is the authid in the CURRENT SQLID special register. Creating User-Defined FunctionsBefore using DDL to create a user-defined function, the function program should be coded and prepared. This requires the developer to write the program, precompile, compile, link-edit the program, BIND the DBRM for the program (if the function contains SQL statements), and then test the program to be sure it is free of bugs . Then, before the user-defined function can be used, it must be registered to DB2 using the CREATE FUNCTION DDL statement. For example, assume that you have written a user-defined function program. Further assume that the program returns the number of days in the month for a given date. The following is a simplified version of the CREATE FUNCTION statement that could be used to register the UDF to DB2: CREATE FUNCTION DAYSINMONTH(DATE) RETURNS INTEGER EXTERNAL NAME 'DAYMTH' LANGUAGE COBOL; This statement creates a UDF named DAYSINMONTH , with one parameter of DATE data type, that returns a single value of INTEGER data type. The external name for the function program is DAYMTH and it is coded in COBOL. NOTE Most of the parameters have been omitted from this simple CREATE FUNCTION example. The parameters available for the CREATE FUNCTION statement are discussed in depth later in this chapter. After the user-defined function has been created, and the appropriate authority has been GRANT ed, the UDF can be used in an SQL statement as follows : SELECT EMPNO, LASTNME, BIRTHDATE, DAYSINMONTH(BIRTHDATE) FROM DSN8810.EMP WHERE DAYSINMONTH(BIRTHDATE) < 31; The result of this statement would be a list of employees whose birth date falls in a month having fewer than 31 days (that is, February, April, June, September, and November). This assumes that the program for the user-defined function DAYSINMONTH is correctly coded to examine the date specified as input and return the actual number of days in the month. There are many different characteristics that need to be determined and specified when creating UDFs. Table 4.1 outlines the characteristics and whether each applies to external functions, sourced functions, or both. Table 4.1. Characteristics of DB2 User-Defined Functions
NOTE If the Validity column of Table 4.1 contains the value X, the characteristic applies to external functions only; S means it applies to sourced functions only; and B means it applies to both external and sourced functions. UDF Programming Language OptionsDB2 offers several application programming languages in which UDF programs can be written. The following languages are supported by DB2 for UDF creation:
DB2 also supports SQL scalar functions that are written using only SQL functionality. Keep in mind, too, that all UDF programs must be designed to run in IBM's Language Environment (LE/370). How Functions Are ExecutedUser-defined functions run in WLM-managed stored procedure address spaces. To execute a user-defined function, simply reference the function in an SQL statement. The SQL statement can be issued dynamically or statically, as part of an application program or via ad hoc SQL ” anywhere SQL can be run, the UDF can be coded. External UDFs require WLM running in GOAL mode. When a function is invoked in an SQL statement, DB2 must choose the correct function to run to satisfy the request. DB2 will check for candidate functions to satisfy the function request. The manner in which DB2 chooses which function to run is based on the following criteria:
NOTE For a function that passes a transition table, the data type, length, precision, and scale of each column in the transition table must match the data type, length, precision, and scale of each column of the table specified in the function definition. For unqualified UDFs, it is possible that two or more candidate functions will fit equally well. In this case, the user-defined function whose schema name is earliest in the SQL path will be chosen for execution. For example, suppose functions XSCHEMA.FUNC1 and YSCHEMA2.FUNC1 both fit the function resolution criteria equally well. Both have the same function name but different schema names . Both also fit the rest of the criteria regarding number of parameters, parameter data types, and requisite authority. If the SQL path is "ZSCHEMA"; "YSCHEMA"; "SYSPROC"; "SYSIBM"; "XSCHEMA"; DB2 will select function YSCHEMA.FUNC1 because YSCHEMA is before XSCHEMA in the SQL path. The SQL path is specified to DB2 in one of two ways. The SQL path is determined by the CURRENT PATH special register for dynamically prepared SQL statements. For dynamic SQL, the SQL path can be set by issuing the SET CURRENT PATH statement. The PATH parameter of the BIND and REBIND commands is used to specify the SQL path for SQL containing UDFs in plans and packages. DB2 supports function overloading. This means that multiple functions can have the same name and DB2 will decide which one to run based on the parameters. Consider an example where an application developer writes a UDF that overloads the addition operator + . The UDF is created to concatenate text strings together. The + function is overloaded because if it is acting on numbers it adds them together; if the function is acting on text it concatenates the text strings. Table 4.2. Data Type Promotability
The process of following these steps to determine which function to execute is called function resolution . NOTE When automatic rebind is invoked on a package or plan that contains UDFs, DB2 will not consider any UDF created after the original BIND or REBIND was issued. In other words, only those UDFs that existed at the time of the original BIND or REBIND are considered during function resolution for plans and packages bound as a result of automatic rebind. DSN_FUNCTION_TABLE and EXPLAINYou can use EXPLAIN to obtain information about DB2 function resolution. To use EXPLAIN to obtain function resolution information, you must create a special table called DSN_FUNCTION_TABLE . When EXPLAIN is executed and UDFs are used, DB2 will store function resolution details for each UDF in the statement, package, or plan, in DSN_FUNCTION_TABLE . Information will be populated in DSN_FUNCTION_TABLE when you execute an EXPLAIN on an SQL statement that contains one or more UDFs, or when you run a program whose plan is bound with EXPLAIN(YES) , and the program executes an SQL statement that contains one or more UDFs. NOTE EXPLAIN actually can be used to return a lot more information about SQL statements, including the actual access paths used by DB2 to run the SQL. Refer to Chapter 25, "Using EXPLAIN," for an in-depth exploration of using EXPLAIN and interpreting its results. Remember, you must create a table named DSN_FUNCTION_TABLE before you can use EXPLAIN to obtain function resolution details. A sample CREATE statement for this table follows: CREATE TABLE userid .DSN_FUNCTION_TABLE (QUERYNO INTEGER NOT NULL WITH DEFAULT, QBLOCKNO INTEGER NOT NULL WITH DEFAULT, APPLNAME CHAR(8) NOT NULL WITH DEFAULT, PROGNAME CHAR(8) NOT NULL WITH DEFAULT, COLLID CHAR(18) NOT NULL WITH DEFAULT, GROUP_MEMBER CHAR(8) NOT NULL WITH DEFAULT, EXPLAIN_TIME TIMESTAMP NOT NULL WITH DEFAULT, SCHEMA_NAME CHAR(8) NOT NULL WITH DEFAULT, FUNCTION_NAME CHAR(18) NOT NULL WITH DEFAULT, SPEC_FUNC_NAME CHAR(18) NOT NULL WITH DEFAULT, FUNCTION_TYPE CHAR(2) NOT NULL WITH DEFAULT, VIEW_CREATOR CHAR(8) NOT NULL WITH DEFAULT, VIEW_NAME CHAR(18) NOT NULL WITH DEFAULT, PATH VARCHAR(254) NOT NULL WITH DEFAULT, FUNCTION_TEXT VARCHAR(254) NOT NULL WITH DEFAULT ) IN database.tablespace ; After executing EXPLAIN for an SQL statement that uses a UDF, each of these columns will contain information about the UDF chosen during function resolution. The actual definition of the information contained in the columns of DSN_FUNCTION_TABLE is shown in Table 4.3. Table 4.3. DSN_FUNCTION_TABLE Columns
CAUTION For UDFs specified in infix notation, the FUNCTION_TEXT column of DSN_FUNCTION_TABLE will contain the function name only. For example, suppose that * is UDF in the following reference: COL1*COL6 In this case, the FUNCTION_TEXT column will contain only the value * and not the entire reference ( COL1*COL6 ). Table FunctionsTable functions are different in nature from scalar functions. A table function is designed to return multiple columns and rows. Its output is a table. An example using a table function follows: SELECT WINNER, WINNER_SCORE, LOSER, LOSER_SCORE FROM FOOTBALL_RESULTS(5) WHERE LOSER_SCORE = 0; In this case, the table function FOOTBALL_RESULTS() is used to return the win/loss statistics for football games . The table function can be used in SQL statements, just like a regular DB2 table. The function program is designed to fill the rows and columns of the "table." The input parameter is an INTEGER value corresponding to the week the game was played ; if is entered, all weeks are considered. The previous query would return all results where the losing team was shut out (had 0 points) during the fifth week of the season . The following or similar CREATE FUNCTION statement could be used to define the FOOTBALL_RESULTS() function: CREATE FUNCTION FOOTBALL_RESULTS(INTEGER) RETURNS TABLE (WEEK INTEGER, WINNER CHAR(20), WINNER_SCORE INTEGER, LOSER CHAR(20), LOSER_SCORE INTEGER) EXTERNAL NAME FOOTBALL LANGUAGE C PARAMETER STYLE DB2SQL NO SQL DETERMINISTIC NO EXTERNAL ACTION FENCED SCRATCHPAD FINAL CALL DISALLOW PARALLEL CARDINALITY 300; The key parameter is the RETURNS TABLE parameter, which is used to define the columns of the table function. The function program must create these rows itself or from another data source, such as a flat file. The value supplied for the CARDINALITY parameter is only an estimate. It is provided to help DB2 optimize statements using the table function. It is possible to return more or fewer rows than is specified in CARDINALITY . Sourced FunctionsSourced functions are created from already existing built-in (scalar and column) and user-defined (scalar) functions. The primary reason to create a sourced function is to enable functions for user-defined distinct data types. This is required because DB2 implements strong typing. More information on sourced functions and strong typing is provided later in this chapter in the section "User-Defined Data Types and Strong Typing." For now, though, the following is an example of creating a sourced UDF: CREATE FUNCTION FINDWORD (DOCUMENT, VARCHAR(50)) RETURNS INTEGER SPECIFIC FINDWORDDOC SOURCE SPECIFIC FINDWORDCLOB; In this example, a new function, FINDWORD , is created from an existing function, FINDWORDCLOB . The function finds the location of the supplied word ( expressed as a VARCHAR(50) value) in the supplied DOCUMENT . The function returns an INTEGER indicating the location of the word in the DOCUMENT . DOCUMENT is a user-defined type based on a CLOB data type. User-Defined Function GuidelinesThe following guidelines can be used to help you implement effective and efficient user-defined functions for your organization. Naming User-Defined FunctionsThe rules for naming user-defined functions are somewhat complex. The UDF name can be the same as another UDF, even if it is in the same schema. However, to give one function the same name as another function in the same schema, the number of parameters and the data type of the parameters must differ . DB2 will not allow a UDF to be created if the schema, UDF name, number of parameters, and data type of each parameter match another existing UDF. Furthermore, the name of the user-defined function cannot be any of the following system defined key words:
External UDF Program RestrictionsWhen you develop programs for external user-defined functions, DB2 places certain restrictions on the type of services and functions that can be used. Keep the following restrictions in mind as you code your external UDF programs:
NOTE The limitation on the number of parameters for the programming language to be used can impact table UDFs because table functions often require a large number of parameters (that is, at least one output parameter for every column of the table). Starting and Stopping UDFsStarting and stopping external UDFs can be an administrative burden . When UDFs fail, they will be stopped (unless you specify otherwise when the UDF is created). In order for any application to call the UDF again, it must first be started again. You should develop administrative procedures such that appropriate personnel have the authority to start and stop UDFs. To start a UDF, you must issue the following DB2 command: -START FUNCTION SPECIFIC This will cause the named UDF to be activated. You do not need to issue a START command for new UDFs; DB2 will automatically activate a new UDF the first time an SQL statement invokes the function. For example, the following command starts the function XFUNC in the schema XSCHEMA : -START FUNCTION SPECIFIC(XCHEMA.XFUNC) CAUTION The -START FUNCTION SPECIFIC command will not refresh the Language Environment in the WLM-established stored procedure address space. In order to refresh the Language Environment to establish a new load module for a UDF, you must issue the following WLM command: VARY WLM, APPLENV=applenv,REFRESH Similarly, you can issue the -STOP FUNCTION SPECIFIC command to stop a UDF. Stopping a UDF prevents DB2 from accepting SQL statements that invoke that function. Any SQL statements that have already been queued or scheduled by DB2 will continue to run. This command will not prevent these SQL statements from running. UDF administration is complicated by the fact that only users with one of the following authorities (or qualities) can execute the START and STOP FUNCTION SPECIFIC commands:
CAUTION Remember, these commands (both START FUNCTION SPECIFIC and STOP FUNCTION SPECIFIC ) apply to external UDFs only; built-in functions and sourced UDFs cannot be stopped and started using DB2 commands. Starting and Stopping All FunctionsIssuing either the -START FUNCTION SPECIFIC or the “STOP FUNCTION SPECIFIC command without any arguments starts, or stops, all UDFs known to the system. For example -START FUNCTION SPECIFIC starts all UDFs for the DB2 subsystem on which the command was issued. Exercise Control Over UDF StoppingIn Version 8, DB2 for z/OS gives you greater control over UDF execution and utilization. You can now specify for each stored procedure or UDF the maximum number of failures that are allowed before DB2 stops the routine. Previously, when a UDF failed, DB2 stopped it, resulting in administrative overhead ”particularly in a test environment. By specifying the most appropriate value for an individual routine, you can let some routines continue to be invoked for development and debugging and stop other routines for maintenance before they cause problems in a production environment. The available options that can be specified using CREATE or ALTER FUNCTION are
These options should only be specified on external UDFs, not on sourced UDFs. Keep It SimpleEach user-defined function program should be coded to perform one and only one task. The UDF program should be as simple as possible while still performing the desired task. Do not create overly complex UDF programs that perform multiple tasks based on the input. It is far better to have multiple UDFs, each performing one simple task, than to have a single, very complex UDF that performs multiple tasks . The UDF program will be easier to code, debug, understand, and maintain when it needs to be modified. Use DSN_FUNCTION_TABLETo be sure that the right UDF is being chosen during function resolution, use EXPLAIN to populate DSN_FUNCTION_TABLE . It is only by reading the contents of DSN_FUNCTION_TABLE that you can ascertain which UDF was chosen for execution by DB2 during function resolution. Promote UDF ReuseabilityUser-defined functions should be developed with reuseability in mind. After the UDF has been coded and registered to DB2, it can be shared by multiple applications. It is wise to code your UDFs such that they perform simple, useful tasks that can be used by many applications at your site. Reusing UDFs in multiple applications is better than creating multiple UDFs having the same (or similar) functionality for each application. You should promote reuseability while at the same time keeping the UDF code as simple as possible. Promote Consistent Enterprisewide SQLConsider replicating UDFs across subsystems in order to keep the SQL language consistent across the enterprise. This might add a few maintenance steps; however, the gain is a more mobile development staff. Handle UDF AbendsWhen an external UDF abends, the invoking statement in the calling program receives an error code, namely SQLCODE -430 . The unit of work containing the invoking statement must be rolled back. The calling program should check for the “430 SQLCODE and issue a ROLLBACK when it is received. Furthermore, the UDF might need to be restarted depending on the setting of the [STOP CONTINUE] AFTER FAILURE option for the UDF. Invoke UDFs Using Qualified NamesUse the qualified name of a function in the invoking SQL statement. By doing so, you simplify function resolution. DB2 will only search for functions in the specific schema you code. Therefore, DB2 is more likely to choose the function you intend, and the function resolution process will take less time to complete, because fewer functions will qualify as candidates. Consider Using SET CURRENT PACKAGE PATHThe new special register, CURRENT PACKAGE PATH , was added with DB2 Version 8. It is particularly useful for those organizations that use more than one collection for packages. In prior releases, applications that do not use plans must issue the SET CURRENT PACKAGE PATH statement each time a package from a different collection is used. With the CURRENT PACKAGE PATH special register, an application programmer can specify a list of package collections in one SET CURRENT PACKAGE PATH statement. Using SET CURRENT PACKAGE PATH can reduce network traffic, simplify application coding, and result in improved processing and elapsed time. CAST Parameters to the Right Data TypeUse the CAST function to cast the parameters of the invoked UDF to the data types specified in the user-defined function definition. This assists the function resolution process to choose the correct function for execution. For example, consider a sample UDF named TAXAMT . It requires one input parameter, which is defined as DECIMAL(9,2) . If you want to pass a column defined as INTEGER to the UDF, use the CAST function as follows to cast the value of the integer column to a DECIMAL(9,2) value: SELECT TAXAMT(CAST (INT_COL AS DECIMAL(9,2))) FROM TABLE; Define UDF Parameter Data Types EfficientlyAvoid defining UDF parameters using the following data types: CHAR , GRAPHIC , SMALLINT , and REAL . Instead, use VARCHAR , VARGRAPHIC , INTEGER , and DOUBLE , respectively. To clarify this guideline, consider a UDF named FUNCX that is defined with a parameter of data type SMALLINT . To invoke this UDF, the parameter must be of data type SMALLINT . Using a data type of INTEGER will not suffice. For example, the following statement will not resolve to FUNCX , because the constant 500 is of type INTEGER , not SMALLINT : SELECT FUNCX(500) FROM TABLE; The same line of thinking applies to CHAR , GRAPHIC , and REAL data types. Of course, you could use the CAST function as described previously to resolve this problem. But it is better to avoid the problem altogether by specifying VARCHAR , VARGRAPHIC , INTEGER , and DOUBLE as parameter data types instead. Choose Parameter Data Types for PortabilityIf you need to ensure that your UDFs are portable across platforms other than DB2 for z/OS, avoid defining UDFs with parameter data types of FLOAT or NUMERIC . Instead, use DOUBLE or REAL in place of FLOAT , and DECIMAL in place of NUMERIC . UDFs Do Not Require ParametersIt is possible to code user-defined functions that have no parameters. However, when creating and executing the UDF, you still need to specify the parentheses with no value supplied for a parameter. For example, to create a procedure named FLOWERS() that requires no parameters, you should code the following: CREATE FUNCTION FLOWERS(). . . Similarly, to execute the UDF, you would code it in an SQL statement with the parentheses, but without specifying any parameter values, as shown in the following: SELECT FLOWERS() FROM TABLE; Use the Sample User-Defined Functions As TemplatesIBM provides quite a few sample programs for user-defined functions. Examine these samples for examples of how to implement effective DB2 user-defined functions. There are sample function programs for
These functions can be used as samples to learn how to code function programs for your specific needs and requirements. SQL Usage Options Within External UDFsThere are four options for external functions regarding their usage of SQL:
Table 4.4 indicates which SQL statements are valid for each type of SQL usage just described. Table 4.4. Using SQL Within User-Defined Functions
CAUTION When a stored procedure is called from a user-defined function, it must allow for the same or more restrictive data access as the calling UDF. For example, a UDF defined as READS SQL DATA can call a procedure defined as READS SQL DATA or CONTAINS SQL . It cannot call a procedure defined as MODIFIES SQL DATA . The hierarchy of data access from least to most restrictive is MODIFIES SQL DATA READS SQL DATA CONTAINS SQL When to DISALLOW PARALLEL OperationsA table function cannot operate in parallel, so the DISABLE PARALLEL parameter should be specified when issuing a CREATE FUNCTION statement for a table UDF. Some functions that are NOT DETERMINISTIC can receive incorrect results if the function is executed by parallel tasks. Specify the DISALLOW PARALLEL option for these functions. Likewise, some functions that rely on a SCRATCHPAD to store data between UDF invocations might not function correctly in parallel. Specify the DISALLOW PARALLEL option for these functions, too. DETERMINISTIC Versus NOT DETERMINISTICBe sure to specify accurately whether the UDF will always return the same result for identical input arguments. If the UDF always returns the same result for identical input arguments, the UDF is DETERMINISTIC . If not, the UDF should be identified as NOT DETERMINISTIC . Any UDF that relies on external data sources that can change should be specified as NOT DETERMINISTIC . Other examples of functions that are not deterministic include any UDF that contains SQL SELECT , INSERT , UPDATE , or DELETE statements or a random number generator. DB2 uses the [NOT] DETERMINISTIC parameter to optimize view processing for SQL SELECT , INSERT , UPDATE , or DELETE statements that refer to the UDF. If the UDF is NOT DETERMINISTIC , view merge and parallelism will be disabled when the UDF is specified. Choose the UDF SECURITY Option WiselyThe SECURITY parameter indicates how the UDF will interact with an external security product, such as ACF2 or RACF. If SECURITY DB2 is specified, the UDF does not require an external security environment.This is the default value for SECURITY . If the UDF accesses resources protected by an external security product, the access is performed using the authid that is associated with the WLM-established stored procedure address space. If SECURITY USER is specified, an external security environment should be established for the function. If the function accesses resources that the external security product protects, the access is performed using the primary authid of the process that invoked the UDF. The third and final option for SECURITY is DEFINER . If this option is chosen and the UDF accesses resources protected by an external security product, the access is performed using the primary authid of the owner of the UDF. Handling Null Input ArgumentsThere are two option for handling null input arguments in user-defined functions: RETURNS NULL ON NULL INPUT and CALLED ON NULL INPUT . If nulls are to be allowed to be specified as input to a UDF, the UDF must be programmed to test for and handle null inputs. If RETURNS NULL ON INPUT is specified when the UDF is created, the function is not called if any of the input arguments are null. The result of the function call is null. If CALLED ON NULL INPUT is specified when the UDF is created, the function is called whether any input arguments are null or not. In this case, the UDF must test for null input arguments in the function program. UDF ScratchpadsThe [NO] SCRATCHPAD clause should be specified to indicate whether DB2 provides a scratchpad for the UDF to utilize. In general, external UDFs should be coded as reentrant, and a scratchpad can help to store data between invocations of the UDF. A scratchpad provides a storage area for the UDF to use from one invocation to the next. If a scratchpad is specified, a length should be provided. The length can be from 1 to 32,767; the default is 100, if no length is specified. The first time the UDF is invoked, DB2 allocates memory for the scratchpad and initializes it to contain all binary zeroes. The scope of a scratchpad is a single SQL statement. A separate scratchpad is allocated for each reference to the UDF in the SQL statement. So, if the UDF is specified once in the SELECT -list and once in the WHERE clause, two scratchpads would be allocated. Furthermore, if the UDF is run in parallel, one scratchpad is allocated for each parallel task. CAUTION Take care when using SCRATCHPAD with ALLOW PARALLEL because results can be difficult to predict.Consider, for example, a UDF that uses the scratchpad to count the number of times it is invoked.The count would be thrown off if run in parallel because the count would be for the parallel task, not the UDF.For this reason, be sure to specify DISALLOW PARALLEL for UDFs that will not operate in parallel. If the UDF acquires system resources, be sure to specify the FINAL CALL clause to make sure that DB2 calls the UDF one last time, so the UDF can free the system resources it acquired . Specify EXTERNAL ACTION UDFs in SELECT -List to Ensure ProcessingTo make sure that DB2 executes a UDF with external actions for each row of the result set, the UDF should be in the SELECT -list of the SQL statement. The access path chosen by DB2 determines whether UDFs in predicates are executed. Therefore, to be sure the external actions in a UDF are processed , the UDF should be invoked in the SELECT -list, not just in a predicate. Specify CARDINALITY Option to Guide Results for Table UDFsDB2 Version 8 adds the capability to override the expected cardinality of a table UDF on a case-by-case basis. The cardinality of the UDF is specified in the SYSIBM.SYSROUTINES catalog table when the UDF is registered to DB2. Consider overriding cardinality when you expect the results to be significantly greater than or less than the documented cardinality. Doing so enables DB2 to better gauge the access path for SQL queries against table UDFs. There are two options for using the CARDINALITY keyword:
Consider the following two examples: SELECT * FROM TABLE(FOOTBALL_RESULTS(0) CARDINALITY 28) AS WEEK2; SELECT * FROM TABLE(FOOTBALL_RESULTS(0) CARDINALITY MULTIPLIER 2) AS WEEK2; For the sake of argument, let's assume that the CARDINALITY column in SYSIBM.SYSROUTINES for this UDF is 14 (the normal number of NFL games in a week). Either of the two SQL statements can be used to estimate the number of rows to be returned after two weeks of play. For the MULTIPLIER option, we can specify non-integers. If only half a week's football results were available, we could change the cardinality using the multiplier as follows: SELECT * FROM TABLE(FOOTBALL_RESULTS(0) CARDINALITY MULTIPLIER 0.5) AS HALFWEEK; |
< Day Day Up > |