To start with, a brief example will be used to introduce dynamic SQL. This example will not use an SQL descriptor area. In the example, the SQL statements are marked with EXEC SQL and END-EXEC as in ESQL-COBOL. The actions carried out by the host language of the ESQL program are shown in italics.
Example
In the ORDERS table, the order status is to be changed to 3 in the row with job number 251 and customer number 105. This can be done with the following statement in static SQL:
UPDATE orders SET order_status=3 WHERE order_num=251 AND cust_num=105
This statement corresponds to the following sequence of statements in dynamic SQL:
Declaration of the host variables Sourcestmt and Condition Sourcestmt='UPDATE orders SET order_status=3 WHERE order_num=251'
Read the text 'AND cust_num=105' into Condition Sourcestmt=Sourcestmt||Condition
EXEC SQL EXECUTE IMMEDIATE :Sourcestmt END_EXEC
Explanation
Sourcestmt is a host variable declared in the ESQL program and which is assigned an alphanumeric string using the UPDATE statement.
The UPDATE statement is expanded to include a condition by concatenating the text contained in Sourcestmt with the text in Condition read in at runtime. Whereas static SQL requires the statement text for the UPDATE statement to be defined before compilation, dynamic SQL only requires the statement to be defined at runtime.
The EXECUTE IMMEDIATE statement checks, compiles and executes the statement.
Example
A more generalized form of the UPDATE statement shown above can be achieved with the following statement in static SQL:
UPDATE orders SET order_status=:ORDER_STATUS WHERE order_num=:ORDER_NUM
AND cust_num=105
Here, the values for ORDER_STATUS and ORDER_NUM are replaced by two host variables whose values are only defined at runtime. This statement corresponds to the following sequence of statements in dynamic SQL:
Declaration of the host variables SOURCEMT, CONDITION, HOSTVAR1 and HOSTVAR2 Sourcestmt='UPDATE orders SET order_status= ? WHERE order_num= ?'
Read the text 'AND cust_num=105' into CONDITION sourcestmt=sourcestmt||condition
EXEC SQL PREPARE dynstmt FROM :SOURCESTMT END-EXEC
Read the value 3 into HOSTVAR1 and 251 into HOSTVAR2
EXEC SQL EXECUTE dynstmt USING :HOSTVAR1,:HOSTVAR2 END-EXEC
Explanation
The UPDATE statement contains two placeholders, represented by question marks in place of the values for ORDER_STATUS and ORDER_NUM in the WHERE condition.
The UPDATE statement is expanded to include a condition by concatenating the text contained in SOURCESTMT with the text in CONDITION read in at runtime.
This dynamically compilable UPDATE statement is compiled with the following PREPARE statement. DYNSTMT stands for the dynamically compiled SQL statement. This name can then be used to address the statement in an EXECUTE statement.
Before the EXECUTE statement is executed, values for the host variables HOSTVAR1 and HOSTVAR2, which were declared in the ESQL program, are read in. These values are to replace the placeholders “?” in the UPDATE statement. The EXECUTE statement then executes the statement DYNSTMT as prepared by PREPARE.
Example | The cursor CUR_SERVICE is defined for the SERVICES table. The cursor
|
The statements EXECUTE IMMEDIATE, PREPARE and EXECUTE used in the examples are described in detail below. There first follows an overview of the statements which can be dynamically compiled.
Dynamically compilable statements
The following statements can be dynamically compiled (refer to "SQL statements for schema definition and administration" for details on the classification of the statements):
SQL statements for schema definition and administration
SQL statements for designing and managing routines
SQL statements for querying and updating data:
SELECT (without INTO clause)
UPDATE
DELETE
INSERT (without RETURN INTO clause)
MERGE
CALL
SQL statements for transaction management
SQL statements for session control
SQL statements for managing the storage structure
SQL statements for managing user entries
Utility statements
In addition, cursor descriptions can be dynamically compiled.
The following statements cannot be dynamically compiled
the SQL statements for dynamic SQL
the following SQL statements for working with a cursor:
DECLARE CURSOR
OPEN
FETCH
CLOSE
STORE
RESTORE
the SQL statements INCLUDE and WHENEVER.
EXECUTE IMMEDIATE statement
You use the EXECUTE IMMEDIATE statement to prepare and execute a dynamic statement in one step. In other words, EXECUTE IMMEDIATE corresponds to a PREPARE statement immediately followed by an EXECUTE statement. The statement does not, however, remain prepared and cannot be executed again with EXECUTE.
The statement text cannot include any host variables or question marks as placeholders for unknown values.
PREPARE statement
You use PREPARE to prepare a dynamic statement or the cursor description of a dynamic cursor for execution at a later time.
You execute a statement prepared with PREPARE with the EXECUTE statement.
The statement text cannot include any host variables. Question marks are specified as placeholders for unknown values .
Placeholder
The dynamically compilable statement or dynamically compilable cursor description in statement variable may not contain any host variables. Instead, they may contain placeholders for input values which are represented by question marks. These placeholders are provided with values with the USING clause of a subsequent EXECUTE or OPEN statement.
An SQL data type is determined for every placeholder. There are a number of rules which restrict the use of placeholders in statement_variable. A placeholder is only permitted in a context in which the data type of the placeholder can be determined uniquely.
For this reason, placeholders are not permitted
as elements of a select list in the form “?” (“SELECT ?+1” would, however be permitted)
as an operand of a monadic operator
as an argument of an aggregate function
in a query for a null value
if both operands of a dyadic operator or a comparison operator are placeholders
if, in a range query with BETWEEN where the first operand is a placeholder, one of the other two operands is also a placeholder
as the first operand in pattern matching with LIKE
if, when comparing an expression with a set of values, both the expression to be compared and the first value in the list following IN are placeholders.
if all operands are placeholders in a CASE expression. If the CASE expression contains one or more THEN or ELSE clauses, not all the operands in these clauses can be placeholders.
as operands of the string functions LOWER and UPPER
as the first operand (character) and/or second operand (expression) of the string function TRIM (e.g. TRIM (TRAILING FROM ?))
as the first operand of the string function SUBSTRING (e.g. SUBSTRING ? FROM 1 FOR 5)).
if both operands of the numeric function POSITION are placeholders.
EXECUTE statement
You use EXECUTE to execute a statement prepared with PREPARE. Placeholders for input values in the dynamic statement are replaced by specific values.
If the statement is a SELECT statement, the column values of the derived rows are stored in host variables or in an SQL descriptor area.
You can use EXECUTE to execute a previously prepared statement any number of times.
A statement can only be executed with EXECUTE in the compilation unit in which it was previously prepared with PREPARE.
Host variables or SQL descriptor areas can be used for input and output values in the EXECUTE statement. The use of SQL descriptor areas is described in the following section.