|
To execute an SQL statement, the database server must have the following information about the statement:
If information in an SQL statement varies according to some conditions in the application, your ESQL/C program can use dynamic SQL to build the SQL statement at runtime. The basic process to dynamically execute SQL statements consists of the following steps:
Dynamic SQL allows you to assemble an SQL statement in a character string as the user interacts with your program. A dynamic SQL statement is like any other SQL statement that is embedded into a program, except that the statement string cannot contain the names of any host variables. The PREPARE statement sends the contents of an SQL statement string to the database server, which parses it and creates a statement identifier structure (statement identifier).
Assign the text for the SQL statement to a single host variable, which appears in the PREPARE statement. The key to dynamically execute an SQL statement is to assemble the text of the statement into a character string. You can assemble this statement string in the following two ways:
If you know the whole statement structure, you can list it after the FROM keyword of the PREPARE statement. Single quotes or double quotes around the statement text are valid, although the ANSI SQL standard specifies single quotes.
For example:
Tip: Although ESQL/C does not allow newline characters in quoted strings, you can include newline characters in the quoted string of a PREPARE statement. The quoted string is passed to the database server with the PREPARE statement and, if you specify that it should, the database server will allow newline characters in quoted strings. Therefore, you can allow a user to enter the preceding SQL statement from the command line as follows:
For more information on allowing newlines in quoted strings, see Including Newline in Quoted Strings.
Alternatively, you can copy the statement into a char variable as shown in Figure 14-1.
Both of these methods have the same restriction as a static SQL statement. They assume that you know the entire statement structure at compile time. The disadvantage of these dynamic forms over the static one is that any syntax errors encountered in the statement will not be discovered until runtime (by the PREPARE statement). If you statically execute the statement, the ESQL/C preprocessor can uncover syntactic errors at compile time (semantic errors might remain undiagnosed until runtime). You can improve performance when you dynamically execute an SQL statement that is to be executed more than once. The statement is parsed only once.
In Figure 14-1, the stmt_txt variable is a host variable because it is used in an embedded SQL statement (the PREPARE statement). Also the INTO clause of the SELECT statement was removed because host variables cannot appear in a statement string. Instead, you specify the host variables in the INTO clause of an EXECUTE or FETCH statement (see page 14-10). Other SQL statements like DESCRIBE, EXECUTE, and FREE can access the prepared statement when they specify the slct_id statement identifier.
Important: By default, the scope of a statement identifier is global. If you create a multifile application and you want to restrict the scope of a statement identifier to a single file, preprocess the file with the -local preprocessor option.
For more information on -local, see Chapter 1, Programming with INFORMIX-ESQL/C.
If you do not know all the information about the statement at compile time, you can use the following features to assemble the statement string:
Figure 14-2 shows the SELECT statement of Figure 14-1 changed so that it uses a host variable to determine the customer number dynamically.
Figure 14-3 shows how you can use an input parameter to program this same SELECT statement so that the user can enter the customer number.
You can prepare almost any SQL statement dynamically. The only statements that you cannot prepare dynamically are those directly concerned with dynamic SQL and cursor management (such as FETCH and OPEN), and the SQL connection statements. For a complete list of statements, see the PREPARE statement in the Informix Guide to SQL: Syntax.
Tip: You can use the Deferred-PREPARE feature to defer execution of a prepared SELECT, INSERT, or EXECUTE FUNCTION statement until the OPEN statement.
For more information, see Deferring Execution of the PREPARE Statement.
You use the Collection Derived Table clause with an INSERT or SELECT statement to access an ESQL/C collection variable. (For more information on how to use the Collection Derived Table clause and collection variables, see Chapter 9 of this manual.)
When you prepare a statement that manipulates an ESQL/C collection variable, the following restrictions apply:
For example, the following ESQL/C code fragment prepares an INSERT on the a_set client collection variable:
Important: You must declare an ESQL/C collection variable as a client collection variable (a collection variable that is stored on the client computer).
Checking the Prepared Statement
When PREPARE sends the statement string to the database server, the database server parses it to analyze it for errors. The database server indicates the success of the parse in the sqlca structure, as follows:
Once an SQL statement was prepared, the database server can execute it. The way to execute a prepared statement depends on:
Figure 14-4 summarizes how to execute the different types of prepared SQL statements.
Figure 14-4
Sometimes you can ignore the cost of resources allocated to prepared statements and cursors. However, the number of prepared objects that the application can create is limited. Free resources that ESQL/C uses to execute a prepared statement, as follows:
You can use the AUTOFREE feature to have the database server automatically free resources for a cursor and its prepared statement. For more information, see Automatically Freeing a Cursor.
If your program uses a dynamic-management structure to describe an SQL statement at runtime, also deallocate the resources of this structure once the structure is no longer needed. For information on how to deallocate a system-descriptor area, see Freeing Memory Allocated to a System-Descriptor Area. For information on how to deallocate an sqlda structure, see Freeing Memory Allocated to an sqlda Structure.