IBM Books

Net.Data Programming Guide


Net.Data Macro Functions

Net.Data provides many functions you will find useful in your Web applications. It is easy to write your own functions too.

Defining Functions

You can define your own functions or use Net.Data's library of functions. For functions which are not in the Net.Data library, use a FUNCTION block to define the function to the Net.Data macro. Details are in Net.Data Language Environment Guide. The syntax is shown here:

%FUNCTION(type) function-name([usage parameter, ...]) [RETURNS(return-var)] {
  executable-statements
  [report-block]
  [message-block]
%}

type

Identifies a language environment that is configured in the initialization file. The language environment invokes a specific language processor (which processes the executable statements) and provides a standard interface between Net.Data and the language processor.

Several default language environments are provided with Net.Data.

function-name

This is the name of the FUNCTION block. The FUNCTION block is executed by referencing this name elsewhere in the Net.Data macro, preceded by an at (@) sign. Executing a FUNCTION block is a function call. See "Calling Functions" for details.

Multiple FUNCTION blocks can exist with the same name. They must all have identical parameter lists. When the function is called, all FUNCTION blocks with the same name are executed in the order that they are defined in the Net.Data macro.

usage
IN, OUT, or INOUT. This indicates whether the parameter is passed into or received back from the FUNCTION block, or both. The usage type applies to all of the following parameters in the parameter list until changed by another usage type. The default type is IN.

parameter

The name of a variable with local scope that is replaced with the value of a corresponding argument specified on a function call. Parameter references, for example $(parm1), in the executable statements or report block are replaced with the actual value of the parameter. In addition, parameters are passed to the language environment and are accessible to the executable statements using the natural syntax of that language or as environment variables. Parameter variable references are not valid outside the FUNCTION block.

You can also pass implicit parameters on a function call of a type you specify. You must define the parameters in the ENVIRONMENT statement in the initialization file.

return-var
Specify this parameter after the RETURNS keyword. It identifies a special OUT parameter. The value of the return variable is assigned to the function call, and replaces the function call in the Net.Data macro processing. If you do not specify the RETURNS clause, the value of the function call is the null string if the return code from the call to the language environment is 0 or the value of the return code otherwise.

executable-statements
After the variables are substituted and the functions are processed, these statements are passed to the specified language environment for execution. Each language environment processes the statements differently. For details on specifying executable statements or calling executable programs, see "Executable Variables".

report-block
See "Report Blocks".

message-block
See "Message Blocks".

Define functions at the outermost Net.Data macro layer and before they are called in the Net.Data macro.

Calling Functions

Invoke a function from a Net.Data macro using the at (@) character followed by a FUNCTION block name:

@function_name([ argument,... ])

function_name
This is the name of the FUNCTION block to invoke. The function must already be defined in the Net.Data macro, unless this is a built-in function.

argument
This is the name of a defined variable or a literal character string. Arguments on a function call are matched up with the parameters on a FUNCTION block, and each parameter is assigned the value of its corresponding argument for the duration of the FUNCTION block. The arguments must be the same number and type as the corresponding parameters.

When a FUNCTION block is invoked, Net.Data proceeds this way:

  1. Net.Data matches up all of the arguments on the function call with the parameters from the FUNCTION block. If the number or usage type of the variables do not match, an error occurs.

  2. A set of variables is built from all of the function parameters specified in the FUNCTION block and the arguments specified in the ENVIRONMENT statement in the initialization file. There are two distinct sets of variables at this step: the global set, consisting of all variables that have been defined so far, and the local set just built for the function. Global variables are discussed in "Net.Data Macro Variables".

  3. Variable references in the executable text of the FUNCTION block are replaced with the actual value of the variable by looking for the variable in the local variable set, then in the global variable set. If the variable exists in both sets (for example, it was specified as a function parameter and on a previous DEFINE), the local set takes precedence.

  4. Function calls in the executable text of the FUNCTION block are processed. The context of the function call does not matter to Net.Data within executable text. For example, if your function calls have conditional logic in executable text, Net.Data processes the function call even if it does not meet the conditions you specify.

  5. The variables in the local set are passed to the language environment, along with the text of the executable statements. The language environment is responsible for passing the IN and INOUT variables to the language processor, interpreting the executable statements or invoking the language processor to execute the statements, and retrieving any OUT or INOUT variables back from the language processor when the program completes.

  6. When the language environment returns to Net.Data, any OUT or INOUT parameters are obtained from the parameter list, and their values are used to replace the values of their corresponding arguments in the local and global variable sets. If there is a RETURNS clause, the value of the return variable is saved with the FUNCTION block information so that it can be used to replace the function call in the Net.Data macro expansion.

The rules for using and modifying variables from a FUNCTION block in a function call can be summarized as follows:

When MESSAGE block and REPORT block processing is done, the value of the function call is used to replace the function call in the Net.Data macro.

Calling Stored Procedures

Stored procedures are called simply as an SQL function. Stored procedures can offer greater performance and integrity by keeping compiled SQL statements with the database server.

Stored procedures can use these data types for most platforms:

Table 2. Stored Procedures Data Types
BLOB DOUBLEPRECISION SMALLINT
CHAR FLOAT TIME
CLOB INTEGER TIMESTAMP
DATE GRAPHIC VARCHAR
DBCLOB LONGVARCHAR VARGRAPHIC
DOUBLE LONGVARGRAPHIC

See your database documentation for more information about these data types. Net.Data might not support all the data types supported by your database. See the appendix of Net.Data Reference Guide for details.

Here is an example of calling a stored procedure as a function named stored_proc1:

%FUNCTION(DTW_SQL) stored_proc1 ( IN float(7,2) arg1, 
                                  INOUT SMALLINT arg2, 
                                  OUT VARCHAR(9) retval) 
                                  RETURNS (RESULT) {
CALL statsrpt              
%}                      
       
%HTML(REPORT) {     
@stored_proc1(arg1, arg2, retval)
%}   

The name of the stored procedure is statsrpt, which is called with the CALL statement. The function stored_proc1 is the name of the function that calls the stored procedure.

Message Blocks

The MESSAGE block lets you determine how to proceed after a function call based on the success or failure of the function call, and lets you display information to the caller of the function.

Net.Data sets RETURN_CODE, an implicit variable, for each function call. RETURN_CODE is set to the return code of the call to the language environment the function calls. When the function call completes, the MESSAGE block uses the value of RETURN_CODE to determine how to proceed. A MESSAGE block consists of a series of message statements, each statement specifying a return code value, message text, and an action to take. The syntax of a MESSAGE block is shown here:

>>-%message--{-------------------------------------------------->
 
   +----------------------------------------------------------------------+
   V                                                                      |
>----+------------------------------------------------------------------+-+->
     +-| return code spec |--:--| message text spec |--| action spec |--+
 
>-%}-----------------------------------------------------------><
 
return code spec
 
|--+-DEFAULT-------+-------------------------------------------|
   +- +DEFAULT-----+
   +- -DEFAULT-----+
   +-+---+-number--+
     +---+
     +-+-+
 
message text spec
 
         +-----------------------+
         V                       |
|---+-"----+--------------------++--"---+----------------------|
    |      +-string-------------+       |
    |      +-variable reference-+       |
    |      +-function call------+       |
    |    +-----------------------+      |
    |    V                       |      |
    +-{----+--------------------++--%}--+
           +-string-------------+
           +-variable reference-+
           +-function call------+
 
action spec
 
|--:--+-EXIT-----+---------------------------------------------|
      +-CONTINUE-+
 

%message

A keyword for the section that defines a set of return codes, the associated messages, and the actions Net.Data takes when a function call is returned.

return_code spec:

A positive or negative integer. If the value of the Net.Data RETURN_CODE variable matches the return_code spec value, the remaining information in the message statement is used to process the function call. You can also specify messages for return codes not specifically entered in the $MESSAGE block.

DEFAULT

A keyword used to specify a default message code. If RETURN_CODE does not equal zero (0), and an exact match is not specified, the information in this message statement is used to process the function call.

+DEFAULT

A keyword used to specify a default negative message code. If RETURN_CODE is less than zero (0), and an exact match is not specified, the information in this message statement is used to process the function call.

-DEFAULT

A keyword used to specify a default positive message code. If RETURN_CODE is greater than zero (0), an exact match is not specified, and the +DEFAULT (for RETURN_CODE greater than 0) or -DEFAULT (for RETURN_CODE for less than 0) value is not specified, the information in this message statement is used to process the function call.

number

The message code that specifies errors and warnings that can occur during processing. A string of numerical digits from 0 to 9.

message text spec

A string that is sent to the Web's browser if the RETURN_CODE matches the return_code value in this message's message statement.

string

Any sequence of alphabetic and numeric characters and punctuation except a tabulator, newline character, or a space.

variable reference

Returns the value of a previously defined variable and is specified with $ and (). For example: if VAR = 'abc', then $(VAR) returns the value 'abc'.

function call

Invokes one or more previously defined FUNCTION blocks with specified arguments.

action spec:

Determines what action Net.Data takes if the RETURN_CODE matches the return_code value in this message's message statement.

EXIT

A keyword that specifies to exit the macro immediately when the error or warning corresponding to the specified message code occurs.

CONTINUE

A keyword that specifies to continue processing when the error or warning corresponding to the specified message code occurs.

A MESSAGE block can have a global or a local scope. If the MESSAGE block is defined in a FUNCTION block, its scope is local to that FUNCTION block. If it is specified at the outermost macro layer, it has global scope, and is active for all function calls executed in the Net.Data macro. If you defined more than one global MESSAGE block, the last one defined is active.

Net.Data uses these rules to process a RETURN_CODE from a function call:

  1. Check local MESSAGE block for an exact match, exit or continue as specified.

  2. If RETURN_CODE is not 0, check local MESSAGE block for +default or -default, depending on the sign of RETURN_CODE, exit or continue as specified.

  3. If RETURN_CODE is not 0, check local MESSAGE block for default, exit or continue as specified.

  4. Check global MESSAGE block for an exact match, exit or continue as specified.

  5. If RETURN_CODE is not 0, check global MESSAGE block for +default or -default, depending on the sign of RETURN_CODE, exit or continue as specified.

  6. If RETURN_CODE is not 0, check global MESSAGE block for default, exit or continue as specified.

  7. If RETURN_CODE is not 0, issue Net.Data internal default message and exit.

Here's an example of part of a Net.Data macro with a global MESSAGE block and a MESSAGE block for a function.

%{ global message block %}
%MESSAGE {
   -100     : "Return code -100 message"   : exit
    100     : "Return code 100 message"    : continue
   +default : { 
This is a long message that spans more
than one line. You can use HTML tags, including
anchors and forms, in this message. %}   : continue
%}
 
%{ local message block inside a FUNCTION block %}
%FUNCTION(DTW_REXX) my_function() {
  %EXEC { my_command.cmd %}
  %MESSAGE {
     -100     : "Return code -100 message"   : exit
      100     : "Return code 100 message"    : continue
     -default : { 
This is a long message that spans more
than one line. You can use HTML tags, including
anchors and forms, in this message. %}   : exit
  %}

If my_function() returns with RETURN_CODE set to 50, Net.Data processes the error in this order:

  1. Check for an exact match in the local MESSAGE block. (There is none.)

  2. Check for +default in the local MESSAGE block. (There is none.)

  3. Check for default in the local MESSAGE block. (There is none.)

  4. Check for an exact match in the global MESSAGE block. (There is none.)

  5. Check for +default in the global MESSAGE block. (There is one.)

Now that Net.Data found a match, it sends the message text to the Web browser and checks the requested action. Because continue is specified, Net.Data continues to process the Net.Data macro after printing the message text.

For example, if a macro calls my_functions() five times and error 100 is found during processing with the MESSAGE block in the example, output from a program can look like this:

.
11 May 1997                  $245.45
13 May 1997                  $623.23
19 May 1997                  $ 83.02
return code 100 message
22 May 1997                  $ 42.67
 
Total:                       $994.37

See Appendix A. "Dynamic Query Sample" for another example of a local message block.


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