DECLARE statement

Use the DECLARE statement to define a variable, the data type of the variable and, optionally, its initial value.

You can define three types of variable with the DECLARE statement:
  • External
  • Normal
  • Shared
For more information, see ESQL variables.

Syntax

Read syntax diagramSkip visual syntax diagramDECLARE <<-,-<<-Name SHARED (1) (2)EXTERNAL (3) (4) CONSTANTDataType (5)NAMESPACE (6)NAME (6) InitialValueExpression
Notes:
  1. The SHARED keyword is not valid within a function or procedure.
  2. You cannot specify SHARED with a DataType of REFERENCE TO. To store a message tree in a shared variable, use the ROW data type.
  3. EXTERNAL variables are implicitly constant.
  4. It is good programming practice to give an EXTERNAL variable an initial value.
  5. If you specify a DataType of REFERENCE TO, you must specify an initial value (of either a variable or a tree) in InitialValueExpression.
  6. When you use the NAMESPACE and NAME clauses, their values are implicitly constant and of type CHARACTER.

Follow the links to see more information about all these parameters:

CONSTANT

Use CONSTANT to define a constant. You can declare constants within schemas, modules, routines, or compound statements (both implicit and explicit). The behavior of these cases is shown in the following list:

  • Within a compound statement, constants and variables occupy the same namespace.
  • Within expressions, a constant or variable that is declared within a compound statement overlays all constants and variables of the same name that are declared in containing compound statements, modules, and schemas.
  • Within field reference namespace fields, a namespace constant that is declared within a compound statement overlays all namespace constants of the same name that are declared in containing compound statements.

A constant or variable that is declared within a routine overlays any parameters of the same name, as well as all constants and variables of the same name that are declared in a containing module or schema.

DataType

The values that you can specify for DataType are:
  • BOOLEAN
  • INT
  • INTEGER
  • FLOAT
  • DECIMAL
  • DATE
  • TIME
  • TIMESTAMP
  • GMTTIME
  • GMTTIMESTAMP
  • INTERVAL. This value does not apply to external variables (EXTERNAL keyword specified).
  • CHAR
  • CHARACTER
  • BLOB
  • BIT
  • ROW. This value does not apply to external variables (EXTERNAL keyword specified).
  • REFERENCE TO. This value does not apply to external or shared variables (EXTERNAL or SHARED keyword specified).

EXTERNAL

Use EXTERNAL to denote a user-defined property (UDP). A UDP is a user-defined constant whose initial value (optionally set by the DECLARE statement) can be modified, at design time, by the Message Flow editor (see Message Flow editor) or overridden, at deployment time, by the BAR editor (see BAR file editor). The value of a UDP cannot be modified by ESQL.

When a UDP is given an initial value on the DECLARE statement, this value becomes its default. However, any value that you specify in the Message Flow editor at design time, or in the BAR editor at deployment time (even a zero length string) overrides any initial value that was coded on the DECLARE statement.

For example, if you code:
       DECLARE deployEnvironment EXTERNAL CHARACTER 'Dev';
you have defined a UDP variable of deployEnvironment with an initial value Dev.

Add the UDP to the message flow by using the UDP tab in the message flow editor. When you add the flow to the BAR file, the UDP is there as an attribute of the flow; you must name the attribute to be the same as the ESQL variable in the DECLARE statement (in this case, deployEnvironment) to ensure that the initial value that you set is unchanged.

All the UDPs in a message flow must have a value, given either on the DECLARE statement or by the Message Flow or BAR editor; otherwise a deployment-time error occurs. At run time, after the UDP has been declared, its value can be queried by subsequent ESQL statements.

You can define a UDP for a subflow. A UDP has global scope and is not specific to a particular subflow. If you reuse a subflow in a message flow, and those subflows have identical UDPs, you cannot set the UDPs to different values.

The advantage of UDPs is that their values can be changed at deployment time. For example, if you use the UDPs to hold configuration data, it means that you can configure a message flow for a particular computer, task, or environment at deployment time, without having to change the code at the node level. UDPs can also be modified at run time by using the IBM Integration API.

You can declare UDPs only in modules or schemas; that is, you can use the DECLARE statement with the EXTERNAL keyword only at the MODULE or SCHEMA level. If you use a DECLARE statement with the EXTERNAL keyword within a PROCEDURE or FUNCTION, a BIP2402E exception occurs when you deploy the message flow.

The following types of message flow node can access UDPs:
  • Compute node
  • Database node
  • Filter node
  • Nodes that are derived from these node types

Take care when specifying the data type of a UDP, because a CAST is used to change the value to the requested DataType.

For an overview of UDPs, see User-defined properties in ESQL.

Example 1:

DECLARE mycolor EXTERNAL CHARACTER 'blue'; 

Example 2:

DECLARE TODAYSCOLOR EXTERNAL CHARACTER;
SET COLOR = TODAYSCOLOR;
where TODAYSCOLOR is a user-defined property that has a TYPE of CHARACTER and a VALUE set by the Message Flow editor.

NAME

Use NAME to define an alias (an alternative name) by which a variable can be known.

Example 1:

-- The following statement gives Schema1 an alias of 'Joe'.
DECLARE Schema1 NAME 'Joe';  
-- The following statement produces a field called 'Joe'.
SET OutputRoot.XMLNS.Data.Schema1 = 42; 
 
-- The following statement inserts a value into a table called Table1 
-- in the schema called 'Joe'.
INSERT INTO Database.Schema1.Table1 (Answer) VALUES 42; 

Example 2:

-- At Module scope define ColourElementName and set it external
-- so that its default value of 'black' can be overridden as a UDP  
DECLARE ColourElementName EXTERNAL NAME 'black';


-- Use the ColourElementName in a function
CREATE FIRSTCHILD OF OutputRoot.XMLNSC.TestCase.ColourElementName
                     Domain('XMLNSC') 
                     NAME 'Node1' VALUE '1';

If the owning message flow has been configured with a UDP named ColourElementName of type String, which has been given the value red, the following output message is generated:

<xml version="1.0"?>
<TestCase>
  <red>
    <Node1>1</Node1>
  </red>

NAMESPACE

Use NAMESPACE to define an alias (an alternative name) by which a namespace can be known.

Example:

This example illustrates a namespace declaration, its use as a SpaceId in a path, and its use as a character constant in a namespace expression:

       DECLARE prefixOne NAMESPACE 'http://www.example.com/PO1';

       -- On the right hand side of the assignment a namespace constant
       -- is being used as such while, on the left hand side, one is 
       -- being used as an ordinary constant (that is, in an expression).

       SET OutputRoot.XMLNS.{prefixOne}:{'PurchaseOrder'} = 
                      InputRoot.XMLNS.prefixOne:PurchaseOrder;

SHARED

Use SHARED to define a shared variable. Shared variables are private to the flow (if declared within a schema) or node (if declared within a module), but are shared between instances of the flow (threads). No type of variable is visible beyond the flow level; for example, you cannot share variables across integration servers.

You can use shared variables to implement an in-memory cache in the message flow; see Optimizing message flow response times. Shared variables have a long lifetime and are visible to multiple messages passing through a flow; see Long-lived variables.

Shared variables exist for the lifetime of the:
  • Integration server process
  • Flow or node, or
  • Node ESQL code that declares the variable
(whichever is the shortest). They are initialized when the first message passes through the flow or node after each integration node startup.

You cannot define a shared variable within a function or procedure.

The advantages of shared variables, relative to databases, are that:
  • Write access is much faster.
  • Read access to small data structures is faster.
  • Access is direct; that is, there is no need to use a special function (SELECT) to get data, or special statements (INSERT, UPDATE, or DELETE) to modify data. You can refer to the data directly in expressions.
The advantages of databases, relative to shared variables, are that:
  • The data is persistent.
  • The data is changed transactionally.

These read/write variables are ideal for users who are prepared to sacrifice the persistence and transactional advantages of databases in order to obtain better performance, because they have a longer life than only one message and perform better than a database.

Because SHARED variables can be updated by multiple additional instances, you must ensure that you do not change SHARED variables that might cause unexpected results, for example, if the variable is being used as a counter.

As SHARED variables are initialized once on the first message through a node, it is possible to initialize a SHARED ROW variable once with the results from a Database query. The following code shows an example of how this is achieved:
      CREATE SCHEMA testSchema 
         DECLARE mySharedRow SHARED ROW; 
         DECLARE initialized SHARED BOOLEAN myINIT(); 
  
         CREATE COMPUTE MODULE testModule 
        
         CREATE FUNCTION Main() RETURNS BOOLEAN 
         BEGIN 
         SET OutputRoot.XMLNSC.Top.TEST.Result1 VALUE = initialized; 
         SET OutputRoot.XMLNSC.Top.TEST.Result2 = mySharedRow; 
       END; 

     END MODULE; 

     CREATE FUNCTION myINIT( ) RETURNS BOOLEAN 
     BEGIN 
         LOG EVENT VALUES('myINIT CALLED'); 
         SET mySharedRow.Top[] = SELECT A.MyCol1, A.MyCol2 from Database.Test AS A; 
         RETURN TRUE; 
     END; 

You can prevent other instances seeing the intermediate stages of the data by using a BEGIN ATOMIC construct; see BEGIN ... END statement.

Your user program can make an efficient read, or write, copy of an input message in the input node by using shared-row variables, which simplifies the technique for handling large messages.

Restriction:

Subtrees cannot be copied directly from one shared row variable to another shared row variable. Subtrees can be copied indirectly by using a non-shared row variable. Scalar values that are extracted from one shared row variable (by using the FIELDVALUE function) can be copied to another shared row variable.