2. Embedded SQL for C : C Variables and Data Types : Data Type Conversion : How Varchar is Used to Receive and Set Character Data
 
Share this page                  
How Varchar is Used to Receive and Set Character Data
You can also use the C varchar storage class to retrieve and set character data. Typically, varchar variables are used when simple C char variables are not sufficient, as when null bytes are embedded in the character data. In those cases the runtime system cannot differentiate between embedded nulls and the null terminator of the string.
When using varchar variables, the 2-byte length specifier indicates how many bytes are used in the fixed length character array. The runtime system sets this length after a data retrieval, or the program sets it before assigning data to Ingres. This length does not include a null terminator, as the null terminator is not copied or included in the data. The runtime system copies, at most, the size of the fixed length data buffer into the variable.
You can also use varchar variables to retrieve character data that does not contain embedded nulls. Here too, the null terminator is not included in the data.
Because varchar variables never include a null terminator, the program should avoid sending the data member of varchar variables to C functions that assume null-terminated strings (such as strlen and strcmp).
The following program fragment demonstrates the use of the varchar storage class for C variables.
Example: Varchar storage class usage
exec sql begin declare section;
    exec sql declare vch table
        (row integer,
        data varchar(10));       /* Note the VARCHAR type */
        static varchar struct vch_ {
            short vch_length;
            char vch_data[10];
 } vch_store[3] = {
               /* Statically initialized data with nulls */
          {3, {'1', '2', '3'}},
          {6, {'1', '2', '3', '\0', '5', '6'}},
          {8, {'\0', '2', '3', '4', '\0', '6', '7', '8'}}
};
        varchar struct vch_ vch_res;
        int i, j;
 exec sql end declare section;
exec sql whenever sqlerror call sqlprint;
/*
** Add all three rows of data from table above (including mulls).
** Note that the members of the varchar structure are not mentioned.
*/
for (i = 0; i < 3; i++)
{
exec sql insert into vch
values (:i+1, :vch_store[i]);
}
/*
** Now SELECT the data back. Note that the runtime system implicitly
** assigns to the length field the size of the data.
*/
exec sql select *
into :i, :vch_res
from vch;
exec sql begin;
/*
** Print the values of each row. Before printing the values,
** convert all embedded nulls to the '?' character for printing.
** The results are:
** [1] '123'
** [2] '123?56'
** [3] '?234?678'
*/
for (j = 0; j < vch_res.vch_length; j++)
{
if (vch_res.vch_data[j] == '\0')
vch_res.vch_data[j] = '?';
}
printf("[%d] '%.*s'\n", i, vch_res.vch_length,
vch_res.vch_data);
/*
** Note the printf format used here is %.*s rather than %s
** because Ingres does not null terminate varchar data.
*/
 
exec sql end;