Subject Varchar array fields question
Author Carlos Guzmán Álvarez
Hello:

What is the correct slice length that it's needed to be passed to
isc_array_get_slice and isc_array_put_slice for varchar fields ??, i'm
making test with an varchar(30)[1:4] array field, but i can get it to
work well.

Attached to this email is the code that i'm using to do the test, in the
first execution the program will update the field contents and in the
second it will read values, but values are readed are incorrect, and
update contents again, and i think it's a problem with slice_length
parameter.






--
Best regards

Carlos Guzmán Álvarez
Vigo-Spain

"No tengo dones especiales.Sólo soy apasionadamente curioso"
Albert Einstein, científico.

----------

/*
* Program type: API
*
* Description:
* This program selects and updates an array type.
* Projected head count is displayed and updated for
* a set of projects.
* The contents of this file are subject to the Interbase Public
* License Version 1.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy
* of the License at http://www.Inprise.com/IPL.html
*
* Software distributed under the License is distributed on an
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
* or implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code was created by Inprise Corporation
* and its predecessors. Portions created by Inprise Corporation are
* Copyright (C) Inprise Corporation.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/

#include <stdlib.h>
#include <string.h>
#include <ibase.h>
#include <stdio.h>
#include "example.h"

char *sel_str = "SELECT varray_field FROM TEST_TABLE_01 WHERE int_field = 1";

char *upd_str = "update TEST_TABLE_01 set varray_field = ? WHERE int_field = 1";

int main (ARG(int, argc), ARG(char **, argv))
ARGLIST(int argc)
ARGLIST(char **argv)
{
char hcnt[4][30];
char* string = "12345678";
ISC_QUAD array_id;
ISC_ARRAY_DESC desc;
long len;
isc_db_handle DB = NULL;
isc_tr_handle trans = NULL;
ISC_STATUS status[ISC_STATUS_LENGTH];
short flag0 = 0, flag1 = 0;
isc_stmt_handle stmt = NULL;
isc_stmt_handle ustmt = NULL;
XSQLDA * osqlda, *isqlda;
long fetch_stat;
short i, j;
char empdb[128];
char* user_name = "SYSDBA";
char* user_password = "masterkey";
char* charset = "ISO8859_1";
char dpb_buffer[256], *dpb, *p;
isc_db_handle handle = NULL;
short dpb_length;

strcpy(empdb, "TESTDB.GDB");

/* Construct the database parameter buffer. */
dpb = dpb_buffer;
*dpb++ = isc_dpb_version1;

*dpb++ = isc_dpb_user_name;
*dpb++ = strlen(user_name);
for (p = user_name; *p;)
{
*dpb++ = *p++;
}
*dpb++ = isc_dpb_password;
*dpb++ = strlen(user_password);
for (p = user_password; *p;)
{
*dpb++ = *p++;
}
*dpb++ = isc_dpb_lc_ctype;
*dpb++ = strlen(charset);
for (p = charset; *p;)
{
*dpb++ = *p++;
}
/* An alternate choice for the above construction is to call: isc_expand_dpb(). */
dpb_length = dpb - dpb_buffer;

if (isc_attach_database(status, 0, empdb, &DB, dpb_length, dpb_buffer))
{
ERREXIT(status, 1)
}

if (isc_start_transaction(status, &trans, 1, &DB, 0, NULL))
{
ERREXIT(status, 1)
}

/*
* Set up the array description structure
*/


if (isc_array_lookup_bounds(status, &DB, &trans,
"TEST_TABLE_01", "DARRAY_FIELD", &desc))
{
ERREXIT(status, 1)
}

/*
* Set-up the select statement.
*/

osqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(2));
osqlda->sqln = 1;
osqlda->version = 1;

osqlda->sqlvar[0].sqldata = (char *) &array_id;
osqlda->sqlvar[0].sqltype = SQL_ARRAY + 1;
osqlda->sqlvar[0].sqlind = &flag1;

isc_dsql_allocate_statement(status, &DB, &stmt);
isc_dsql_allocate_statement(status, &DB, &ustmt);

/* Prepare and execute query */
if (isc_dsql_prepare(status, &trans, &stmt, 0, sel_str, 1, osqlda))
{
ERREXIT(status, 1)
}

if (isc_dsql_execute(status, &trans, &stmt, 1, NULL))
{
ERREXIT(status, 1)
}

/*
* Set-up the update statement.
*/

isqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(1));
isqlda->sqln = 1;
isqlda->version = 1;

/* Use describe_bind to set up input sqlda */

if (isc_dsql_prepare(status, &trans, &ustmt, 0, upd_str, 1, NULL))
{
ERREXIT(status, 1)
}
isc_dsql_describe_bind(status, &ustmt, 1, isqlda);

isqlda->sqlvar[0].sqldata = (char *) &array_id;
isqlda->sqlvar[0].sqlind = &flag1;

while ((fetch_stat = isc_dsql_fetch(status, &stmt, 1, osqlda)) == 0)
{
len = sizeof(hcnt);

/* Get the current array values. */
if (!flag1)
{
if (isc_array_get_slice(status, &DB, &trans,
(ISC_QUAD *) &array_id,
(ISC_ARRAY_DESC *) &desc,
hcnt,
(long *) &len))
{
ERREXIT (status, 1)
};

printf("Current values: \n %s \n %s \n %s \n %s \n",
(char*)hcnt[0], (char*)hcnt[1], (char*)hcnt[2], (char*)hcnt[3]);
}

flag1 = 0;

/* Add 1 to each count. */
for (i = 0; i < 4; i++)
for (j = 0; j < strlen(string); j++)
hcnt[i][j] = string[j];

hcnt[0][strlen(string)] = '\0';
hcnt[1][strlen(string)] = '\0';
hcnt[2][strlen(string)] = '\0';
hcnt[3][strlen(string)] = '\0';

/* Save new array values. */
if (isc_array_put_slice(status, &DB, &trans,
(ISC_QUAD *) &array_id,
(ISC_ARRAY_DESC *) &desc,
hcnt,
(long *) &len))
{
ERREXIT (status, 1)
};

/* Update the array handle. */
if (isc_dsql_execute(status, &trans, &ustmt, 1, isqlda))
{
ERREXIT(status, 1)
}

printf("New values: \n %s \n %s \n %s \n %s\n\n",
hcnt[0], hcnt[1], hcnt[2], hcnt[3]);
}

if (fetch_stat != 100L)
{
ERREXIT(status, 1)
}

isc_dsql_free_statement(status, &stmt, DSQL_close);
isc_dsql_free_statement(status, &ustmt, DSQL_close);

if (isc_commit_transaction(status, &trans))
{
ERREXIT(status, 1)
}

if (isc_detach_database(status, &DB))
{
ERREXIT(status, 1)
}

free(osqlda);
free(isqlda);

return 0;
}


[Non-text portions of this message have been removed]