isc_dsql_prepare()

From InterBase
Jump to: navigation, search

Go Up to API Function Reference


Prepares a DSQL statement for repeated execution.

Syntax

ISC_STATUS isc_dsql_prepare(
ISC_STATUS *status_vector,
isc_tr_handle *trans_handle,
isc_stmt_handle *stmt_handle,
unsigned short length,
char *statement,
unsigned short dialect,
XSQLDA *xsqlda);

Parameter Type Description

status_vector

ISC_STATUS *

Pointer to the error status vector

trans_handle

isc_tr_handle *

Pointer to a transaction handle whose value has been set by a previous isc_start_transaction() call; trans_handle returns an error if NULL.

stmt_handle

isc_stmt_handle *

Pointer to a statement handle previously allocated with isc_dsql_allocate_statement() or ­isc_dsql_alloc_statement2(); the handle returns an error in status_vector if it is NULL.

length

unsigned short

Length of the DSQL statement, in bytes; set to 0 in C programs to indicate a null-terminated string.

statement

char *

DSQL string to be executed

dialect

unsigned short

  • Indicates the SQL dialect of statement.
  • Must be less than or equal to the SQL dialect of the client.

xsqlda

XSQLDA *

Pointer to an optional, previously allocated XSQLDA used for results of statement execution.

Description

isc_dsql_prepare() readies the DSQL statement specified in statement for repeated execution by checking it for syntax errors and parsing it into a format that can be efficiently executed. All SELECT statements must be prepared with isc_dsql_prepare().

After a statement is prepared, it is available for execution as many times as necessary during the current session. Preparing a statement for repeated execution is more efficient than using isc_dsql_execute_immediate() or ­isc_dsql_exec_immed2() over and over again to prepare and execute a ­statement.

If a statement to be prepared does not return data, set the output XSQLDA to NULL. Otherwise, the output XSQLDA must be allocated prior to calling ­isc_dsql_prepare(). Allocate the XSQLDA using the macro, XSQLDA_LENGTH, defined in ibase.h, as follows:

xsqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(n));

XSQLDA_LENGTH calculates the number of bytes required when <n> result columns will be returned by the statement, and allocates the appropriate amount of storage.

After allocating the XSQLDA xsqlda, set xsqlda->version to SQLDA_CURRENT_VERSION, and set xsqlda_sqln to indicate the number of XSQLVAR structures allocated.

When isc_dsql_prepare() is called, it fills in the other fields of the XSQLDA and all the XSQLVAR with information such as the data type, length, and name of the corresponding select-list items in the statement. It fills in xsqlda->sqld with the actual number of select-list items returned. If xsqlda->sqld is greater than xsqlda->sqln, then enough room is not allocated, and the XSQLDA must be resized by following these steps:

  1. Record the current value of the xsqlda->sqld.
  2. Free the storage previously allocated for xsqlda.
  3. Reallocate storage for xsqlda, this time specifying the correct number (from step 1) in the argument to XSQLDA_LENGTH.
  4. Reset xsqlda->sqld and xsqlda->version.
  5. Execute isc_dsql_describe() to fill in the xsqlda fields.
Note: If the prepared statement requires input parameter values, then an input XSQLDA will need to be allocated and filled in with appropriate values prior to calling isc_dsql_execute() or isc_dsql_execute2(). You can either allocate and directly fill in all the fields of the input XSQLDA, or you can allocate it, call isc_dsql_describe_bind() to get information regarding the number and types of parameters required, then fill in appropriate values.

Example

The following program fragment illustrates the allocation of the output XSQLDA, and a call to isc_dsql_prepare():

#include <ibase.h>
ISC_STATUS status_vector[20];
XSQLDA *osqlda;
char *query = "SELECT CITY, STATE, POPULATION
FROM CITIES
WHERE STATE = "NY" ORDER BY CITY DESCENDING";
osqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(3);
osqlda->version = SQLDA_CURRENT_VERSION;
osqlda->sqln = 3;
isc_dsql_prepare(
status_vector,
&tr_handle, /* Set in previous isc_start_transaction() call. */
&stmt_handle, /* Allocated previously by isc_dsql_allocate_statement()
or isc_dsql_alloc_statement2() call. */
0, query, 1, osqlda);
if (status_vector[0] == 1 && status_vector[1]) {
isc_print_status(status_vector);
return(1);
}

More complete examples showing the subsequent execution and fetching of result data are provided in the example programs for isc_dsql_execute(), isc_dsql_execute2(), and isc_dsql_fetch().

Return value

isc_dsql_prepare() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to ­isc_bad_stmt_handle, isc_bad_trans_handle, or another InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly. For more information about examining the status vector, see Handling Error Conditions.

For more information about creating and populating the XSQLDA, see Understanding the XSQLDA of Working with Dynamic SQL.

See Also