![]() |
|
Any variable that you use in an SPL routine, other than a variable that is implicitly defined in the parameter list of the routine, must be defined in the body of the routine.
The value of a variable is held in memory; the variable is not a database object. Therefore, rolling back a transaction does not restore the values of SPL variables.
To define a variable in an SPL routine, use the DEFINE statement. DEFINE is not an executable statement. DEFINE must appear after the CREATE PROCEDURE statement and before any other statements. The examples in Figure 10-19 are all legal variable definitions.
Figure 10-19
For more information on DEFINE, see the description in the Informix Guide to SQL: Syntax.
An SPL variable has a name and a data type. The variable name must be a valid identifier, as described in the Identifier segment in the Informix Guide to SQL: Syntax.
You can define a variable to be either local or global in scope. This section describes local variables. In an SPL routine, local variables:
You can define a local variable on any of the following data types:
The scope of a local variable is the statement block in which it is declared. You can use the same variable name outside the statement block with a different definition.
For more information on defining global variables, see Declaring Global Variables.
A local variable is valid within the statement block in which it is defined and within any nested statement blocks, unless you redefine the variable within the statement block.
In the beginning of the SPL procedure in Figure 10-20, the integer variables x, y, and z are defined and initialized.
Figure 10-20
The BEGIN and END statements mark a nested statement block in which the integer variables x and q are defined as well as the CHAR variable z. Within the nested block, the redefined variable x masks the original variable x. After the END statement, which marks the end of the nested block, the original value of x is accessible again.
Built-in type variables hold data retrieved from built-in data types. You can define an SPL variable with any built-in type, except SERIAL and SERIAL8 as Figure 10-21 shows.
Figure 10-21
A variable for a BLOB or CLOB object (or a data type that contains a smart large object) does not contain the object itself but rather a pointer to the object. Figure 10-22 shows how to define a variable for BLOB and CLOB objects.
Figure 10-22
A variable for a simple large object (a TEXT or BYTE object) does not contain the object itself but rather a pointer to the object. When you define a variable on the TEXT or BYTE data type, you must use the keyword REFERENCES before the data type, as Figure 10-23 shows.
Figure 10-23
In order to hold a collection fetched from the database, a variable must be of type SET, MULTISET, or LIST.
Important: A collection variable must be defined as a local variable. You cannot define a collection variable as a global variable.
A variable of SET, MULTISET, or LIST type is a collection variable that holds a collection of the type named in the DEFINE statement. Figure 10-24 shows how to define typed collection variables.
Figure 10-24
You must always define the elements of a collection variable as NOT NULL. In this example, the variable a is defined to hold a SET of non-null integers; the variable b holds a MULTISET of non-null row types; and the variable c holds a LIST of non-null sets of non-null decimal values.
In a variable definition, you can nest complex types in any combination or depth to match the data types stored in your database.
You cannot assign a collection variable of one type to a collection variable of another type. For example, if you define a collection variable as a SET, you cannot assign another collection variable of MULTISET or LIST type to it.
Row-type variables hold data from named or unnamed row types. You can define a named row variable or an unnamed row variable. Suppose you define the named row types that Figure 10-25 shows.
If you define a variable with the name of a named row type, the variable can only hold data of that row type. In Figure 10-26, the person variable can only hold data of employee_t type.
Figure 10-26
To define a variable that holds data stored in an unnamed row type, use the ROW keyword followed by the fields of the row type, as Figure 10-27 shows.
Figure 10-27
Because unnamed row types are type-checked for structural equivalence only, a variable defined with an unnamed row type can hold data from any unnamed row type that has the same number of fields and the same type definitions. Therefore, the variable manager can hold data from any of the row types in Figure 10-28.
Figure 10-28
Important: Before you can use a row type variable, you must initialize the row variable with a LET statement or SELECT...INTO statement.
Declaring Opaque- and Distinct-Type Variables
Opaque-type variables hold data retrieved from opaque data types. Distinct- type variables hold data retrieved from distinct data types. If you define a variable with an opaque data type or a distinct data type, the variable can only hold data of that type.
If you define an opaque data type named point and a distinct data type named centerpoint, you can define SPL variables to hold data from the two types, as Figure 10-29 shows.
Figure 10-29
The variable a can only hold data of type point, and b can only hold data of type centerpoint.
If you use the LIKE clause, the database server defines a variable to have the same data type as a column in a table or view.
If the column contains a collection, row type, or nested complex type, the variable has the complex or nested complex type defined in the column.
In Figure 10-30, the variable loc1 defines the data type for the locations column in the image table.
Figure 10-30
In an SPL routine, you can define a variable of type PROCEDURE and assign the variable the name of an existing SPL routine or external routine. Defining a variable of PROCEDURE type indicates that the variable is a call to a user-defined routine, not a built-in routine of the same name.
For example, the statement in Figure 10-31 defines length as an SPL procedure or SPL function, not as the built-in LENGTH function.
Figure 10-31
This definition disables the built-in LENGTH function within the scope of the statement block. You would use such a definition if you had already created an SPL or external routine with the name LENGTH.
Because Dynamic Server supports routine overloading, you can define more than one SPL routine or external routine with the same name. If you call any routine from an SPL routine, Dynamic Server determines which routine to use, based on the arguments specified and the routine determination rules. For information about routine overloading and routine determination, see Extending Informix Dynamic Server 2000.
Tip: If you create an SPL routine with the same name as an aggregate function (SUM, MAX, MIN, AVG, COUNT) or with the name extend, you must qualify the routine name with an owner name.
Using Subscripts with Variables
You can use subscripts with variables of CHAR, VARCHAR, NCHAR, NVARCHAR, BYTE, or TEXT data type. The subscripts indicate the starting and ending character positions that you want to use within the variable.
Subscripts must always be constants. You cannot use variables as subscripts. Figure 10-32 illustrates how to use a subscript with a CHAR(15) variable.
Figure 10-32
In this example, the customer's last name is placed between positions 4 and 7 of name. The first three characters of the customer's first name is retrieved into positions 1 through 3 of name. The part of the variable that is delimited by the two subscripts is referred to as a substring.
If you define a variable as an SQL keyword, ambiguities can occur. The following rules for identifiers help you avoid ambiguities for SPL variables, SPL routine names, and built-in function names:
In general, avoid using an ANSI-reserved word for the name of the variable. For example, you cannot define a variable with the name count or max because they are the names of aggregate functions. For a list of the reserved keywords that you should avoid using as variable names, see the Identifier segment in the Informix Guide to SQL: Syntax.
Variables and Column NamesIf you use the same identifier for an SPL variable that you use for a column name, the database server assumes that each instance of the identifier is a variable. Qualify the column name with the table name, using dot notation, in order to use the identifier as a column name.
In the SELECT statement in Figure 10-33, customer.lname is a column name and lname is a variable name.
Figure 10-33
If you use the same identifier for an SPL variable as for an SQL function, the database server assumes that an instance of the identifier is a variable and disallows the use of the SQL function. You cannot use the SQL function within the block of code in which the variable is defined. The example in Figure 10-34 shows a block within an SPL procedure in which the variable called user is defined. This definition disallows the use of the USER function in the BEGIN ... END block.
Figure 10-34
For information about ambiguities between SPL routine names and SQL function names, see the Informix Guide to SQL: Syntax.
A global variable has its value stored in memory and is available to other SPL routines, run by the same user session, on the same database. A global variable has the following characteristics:
Important: You cannot define a collection variable as a global variable.
Figure 10-35 shows two SPL functions that share a global variable.
Figure 10-35
Although you must define a global variable with a default value, the variable is only set to the default the first time you use it. If you execute the two functions in Figure 10-36 in the order given, the value of gvar would be 4.
Figure 10-36
But if you execute the functions in the opposite order, as Figure 10-37 shows, the value of gvar would be 7.
Figure 10-37
For more information, see Executing Routines.
Within an SPL routine, use the LET statement to assign values to the variables you have already defined.
If you do not assign a value to a variable, either by an argument passed to the routine or by a LET statement, the variable has an undefined value. An undefined value is different than a null value. If you attempt to use a variable with an undefined value within the SPL routine, you receive an error.
You can assign a value to a routine variable in any of the following ways:
With a LET statement, you can use one or more variable names with an equal (=) sign and a valid expression or function name. Each example in Figure 10-38 is a valid LET statement.
Figure 10-38
Dynamic Server allows you to assign a value to an opaque-type variable, a row-type variable, or a field of a row type. You can also return the value of an external function or another SPL function to an SPL variable.
Suppose you define the named row types zip_t and address_t, as Figure 10-25 on page 10-24 shows. Anytime you define a row-type variable, you must initialize the variable before you can use it. Figure 10-39 shows how you might define and initialize a row-type variable. You can use any row-type value to initialize the variable.
Figure 10-39
After you define and initialize the row-type variable, you can write the LET statements that Figure 10-40 shows.
Figure 10-40
Tip: Use dot notation in the form variable.field or variable.field.field to access the fields of a row type, as Handling Row-Type Data describes.
Suppose you define an opaque-type point that contains two values that define a two-dimensional point, and the text representation of the values is '(x,y)'. You might also have a function circum() that calculates the circumference of a circle, given the point '(x,y)' and a radius r.
If you define an opaque-type center that defines a point as the center of a circle, and a function circum() that calculates the circumference of a circle, based on a point and the radius, you can write variable declarations for each. In Figure 10-41, c is an opaque type variable and d holds the value that the external function circum() returns.
Figure 10-41
The Informix Guide to SQL: Syntax describes in detail the syntax of the LET statement.
You can use the SELECT statement to fetch a value from the database and assign it directly to a variable, as Figure 10-42 shows.
Figure 10-42
Use the CALL or EXECUTE PROCEDURE statements to assign values returned by an SPL function or an external function to one or more SPL variables. You might use either of the statements in Figure 10-43 to return the full name and address from the SPL function read_address into the specified SPL variables.
Figure 10-43