isc_array_get_slice2()

From InterBase

Go Up to API Function Reference


Retrieves data from an array column in a row returned by a SELECT.

Syntax

 ISC_STATUS isc_array_get_slice2(
 ISC_STATUS *status_vector, 
 isc_db_handle *db_handle, 
 isc_tr_handle *trans_handle,
 ISC_QUAD *array_id,
 ISC_ARRAY_DESC_V2 *desc,
 void *dest_array,
 ISC_LONG *slice_length);
Parameter Type Description

status_vector

ISC_STATUS *

Pointer to the error status vector

db_handle

isc_db_handle *

Pointer to a database handle set by a previous call to ­isc_attach_database(); the handle identifies the database containing the array column.

db_handle returns an error in status_vector if it is NULL.

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.

array_id

ISC_QUAD *

Internal identifier for the array; the array ID must be previously retrieved through API DSQL ­functions.

desc

ISC_ARRAY_DESC _V2*

Descriptor defining the array slice (entire array or subset) to be retrieved.

dest_array

void *

Pointer to a buffer of length slice_length into which the array slice will be copied by this ­function.

slice_length

ISC_LONG *

Length, in bytes, of the dest_array buffer

Description

isc_array_get_slice2() retrieves data from an array column of a table row using an array ID. You can either retrieve all the array elements in that column, or a subset of contiguous array elements, called a slice. The upper and lower boundaries in the desc structure specify which elements are to be retrieved.

InterBase copies the elements into the buffer, dest_array, whose size is specified by slice_length. This should be at least the expected length required for the elements retrieved. Before returning from isc_array_get_slice2(), InterBase sets slice_length to the actual number of bytes copied.

Before calling isc_array_get_slice2(), there are many operations you must do in order to fill in the array descriptor, desc, determine the appropriate internal array identifier, array_id, and fetch the rows whose array columns you want to access. For complete step-by-step instructions for setting up an array descriptor and retrieving array information, see Working with Array Data.

Note:
Never execute a DSQL statement that tries to access array column data directly unless you are fetching only a single element. The way to access slices of array column data is to call isc_array_get_slice2() or ­isc_array_put_slice2(). The only supported array references in DSQL statements are ones that specify an entire array column (that is, just the column name) in order to get the internal identifier for the array, which is required by isc_array_get_slice2() and isc_array_put_slice2(), or single element references.

Example

The following program operates on a table named PROJ_DEPT_BUDGET.
This table contains the quarterly head counts allocated for each project in each department of an organization. Each row of the table applies to a particular department and project. The quarterly head counts are contained in an array column named QUARTERLY_HEAD_CNT. Each row has four elements in this column, one per quarter. Each element of the array is a number of type long.

The example below selects the rows containing 1994 information for the project named VBASE. For each such row, it retrieves and prints the department number and the data in the array column (that is, the quarterly head counts).

In addition to illustrating the usage of isc_array_lookup_bounds2() and isc_array_get_slice2(), the program shows data structure initializations and calls to the DSQL functions required to prepare and execute the SELECT statement, to obtain the array_id needed by isc_array_get_slice2(), and to fetch the selected rows one by one.

#include <ibase.h>
#define Return_if_Error(stat) if (stat[0] == 1 && stat[1]) {
isc_print_status(stat);
return(1);
}
char *sel_str = "SELECT dept_no, quarterly_head_cnt
FROM proj_dept_budget
WHERE year = 1994 AND proj_id = 'VBASE'";
char dept_no[6];
long hcnt[4], tr_handle, database_handle, SQLCODE;
short len, i, flag0, flag1;
ISC_QUAD array_id;
ISC_ARRAY_DESC_V2 desc;
ISC_STATUS status_vector[20], fetch_stat;
isc_stmt_handle stmt = NULL;
XSQLDA *osqlda;
tr_handle = database_handle = 0L;
/* Attach to a database here--this code omitted for brevity */
/* Start a transaction here--this code omitted for brevity */
/* Set up the SELECT statement. */
/* Allocate the output XSQLDA for holding the array data. */
osqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(2));
osqlda->sqln = 2;
osqlda->version = 1;
/* Allocate a statement handle. */
isc_dsql_allocate_statement(status_vector, &database_handle, &stmt);
Return_if_Error(status_vector);
/* Prepare the query for execution. */
isc_dsql_prepare(status_vector, &tr_handle, &stmt, 0, sel_str, 1, osqlda);
Return_if_Error(status_vector);
/* Set up an XSQLVAR structure to allocate space for each
 * item to be retrieved. */
osqlda->sqlvar[0].sqldata = (char *) dept_no;
osqlda->sqlvar[0].sqltype = SQL_TEXT + 1;
osqlda->sqlvar[0].sqlind = &flag0;
osqlda->sqlvar[1].sqldata = (char *) &array_id;
osqlda->sqlvar[1].sqltype = SQL_ARRAY + 1;
osqlda->sqlvar[1].sqlind = &flag1;
/* Execute the SELECT statement. */
isc_dsql_execute(status_vector, &tr_handle, &stmt, 1, NULL);
Return_if_Error(status_vector);
/* Set up the array descriptor. */
isc_array_lookup_bounds2(status_vector,
&database_handle, /* Set by previous isc_attach_database() call. */
&tr_handle, /* Set by previous isc_start_transaction() call. */
"PROJ_DEPT_BUDGET", /* Table name. */
"QUARTERLY_HEAD_CNT", /* Array column name. */
&desc);
Return_if_Error(status_vector);

/* Fetch the head count for each department's four quarters. */
while ((fetch_stat = isc_dsql_fetch(status_vector, &stmt, 1, osqlda)) == 0){
if (!flag1) {
/* There is array data; get the current values. */
len = sizeof(hcnt);
/* Fetch the data from the array column into hcnt array. */
isc_array_get_slice2( status_vector, &database_handle, &tr_handle,
&array_id, &desc, hcnt, &len);
Return_if_Error(status_vector);
/* Print department number and head counts. */
dept_no[osqlda->sqlvar[0].sqllen] = '\0';
printf("Department #: %s\n\n", dept_no);
printf("\tCurrent counts: %d %d %d %d\n",
hcnt[0], hcnt[1], hcnt[2], hcnt[3]);
};
}
if (fetch_stat != 100L){
SQLCODE = isc_sqlcode(status_vector);
isc_print_sqlerror(SQLCODE, status_vector);
return(1);
}

Return value

isc_array_get_slice2() 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.

See Also

Advance To: