isc_dsql_describe_bind()

From InterBase

Go Up to API Function Reference


Provides information about dynamic input parameters required by a previously prepared DSQL statement.

Syntax

 ISC_STATUS isc_dsql_describe_bind(
 ISC_STATUS *status_vector,
 isc_stmt_handle *stmt_handle,
 unsigned short da_version,
 XSQLDA *xsqlda);
Parameter Type Description

status_vector

ISC_STATUS *

Pointer to the error status vector

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

da_version

unsigned short

Specifies that the XSQLDA descriptor, rather than SQLDA, should be used; set this value to 1

xsqlda

XSQLDA *

Pointer to a previously allocated XSQLDA used for input

Description: isc_dsql_describe_bind() stores into the input XSQLDA xsqlda information about the dynamic input parameters required by a DSQL statement previously prepared with isc_dsql_prepare().

Before an application can execute a statement with input parameters, it must supply values for them in an input XSQLDA structure. If you know exactly how many parameters are required, and their datatypes, you can set up the XSQLDA directly without calling isc_dsql_describe_bind(). But if you need InterBase to analyze the statement and provide information such as the number of parameters and their datatypes, you must call isc_dsql_describe_bind() to supply the information.

In a parameterized query, the order of parameters received for an Input SQLDA has been fixed. The fixed order is now both intuitive and in "visible order" as per ANSI/SQL standard requirements. This is useful especially when parameters are used in the main query's conjuncts (WHERE conditions), and in the query's column-list which have one or more sub-query(s) themselves with parameters in them. The client API, isc_dsql_describe_bind(), now correctly returns the visual order sequence number for each parameter in the input SQLDA and uses it internally to transform the user provided SQLVARs to InterBase engine expected order. The changes are only available for SQLDA version >= 2.

A new example, api17.c, has been provided to showcase how this works. The sample below showcases how named parameters are used in IBX and FireDAC components. The named parameters should work for both :TEST and :NO in that parameter order. The client component is expected to provide values in the SQLVAR array in the visible order of :TEST followed by :NO parameters.

select P.emp_no, P.first_name, P.last_name, (select 1 from RDB$DATABASE where 1 <> :TEST) 
from employee P 
where P.emp_no = :NO


Example: The following program fragment illustrates a sequence of calls that allocates an input XSQLDA, prepares a DSQL UPDATE statement, calls the function isc_dsql_describe_bind(), checks whether or not the appropriate number of XSQLVARs was allocated, and corrects the situation if necessary.

#include <ibase.h>
ISC_STATUS status_vector[20];
XSQLDA *isqlda
int n;
char *str = "UPDATE DEPARTMENT SET BUDGET = ?, LOCATION = ?";

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, str, 1, NULL);
if (status_vector[0] == 1 && status_vector[1]) {
     /* Process error. */
     isc_print_status(status_vector);
     return(1);
}
/* Allocate an input XSQLDA. */
isqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(1);
isqlda->version = SQLDA_CURRENT_VERSION;
isqlda->sqln = 1;
isc_dsql_describe_bind( status_vector,
                  &stmt_handle, /* Allocated previously by
                                     * isc_dsql_allocate_statement()
                                     * or isc_dsql_alloc_statement2() call. */
                  1, isqlda);
if (status_vector[0] == 1 && status_vector[1]) {
/* Process error. */
isc_print_status(status_vector);
return(1);
}
if (isqlda->sqld > isqlda->sqln) { /* Need more XSQLVARs. */
     n = isqlda->sqld;
     free(isqlda);
     isqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(n);
     isqlda->sqln = n;
     isqlda->version = SQLDA_CURRENT_VERSION;
     isc_dsql_describe_bind( status_vector, &stmt_handle, 1, isqlda);
     if (status_vector[0] == 1 && status_vector[1]) {
          /* Process error. */
          isc_print_status(status_vector);
          return(1);
}
}

Return value: isc_dsql_describe_bind() 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, 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.

See Also

isc_dsql_describe(), isc_dsql_execute(), isc_dsql_execute2(), isc_dsql_prepare()

For more information about preparing a DSQL statement with input parameters, see DSQL Programming Methods. For more information about creating and populating the XSQLDA, see Understanding the XSQLDA.

Advance To: