Large amounts of LOB data is sent in streams to the server to better manage resources. Use ct_send_data() in a loop to send data to the server in chunks.
To send a LOB data parameter in chunks, use these settings to define the parameter:
Set the datatype field of the CS_DATAFMT structure to CS_TEXT_TYPE, CS_UNITEXT_TYPE, or CS_IMAGE_TYPE.
Set maxlength field of the CS_DATAFMT structure to CS_UNUSED.
Set the *data pointer argument of the ct_param() function to NULL.
Set the datalen argument of the ct_param() function to 0.
Example 1 Sends a large LOB data parameter in chunks:
#define BUFSIZE 2048
int fp;
char sendbuf[BUFSIZE]
/*
** Clear and setup the CS_DATAFMT structure, then pass
** each of the parameters for the RPC.
*/
memset(¶mfmt, 0, sizeof(paramfmt));
strcpy(paramfmt.name, "@intparam");
paramfmt.namelen = CS_NULLTERM;
paramfmt.datatype = CS_INT_TYPE;
paramfmt.maxlength = CS_UNUSED;
paramfmt.status = CS_INPUTVALUE;
paramfmt.locale = NULL;
ct_param(cmd, ¶mfmt, (CS_VOID *)&intvar,
sizeof(CS_INT), 0))
/*
** Text parameter, sent as a BLOB.
*/
strcpy(paramfmt.name, "@textparam");
paramfmt.namelen = CS_NULLTERM;
paramfmt.datatype = CS_TEXT_TYPE;
paramfmt.maxlength = CS_UNUSED;
paramfmt.status = CS_INPUTVALUE;
paramfmt.locale = NULL;
/*
** Although the actual data will not be sent here, we
** must invoke ct_setparam() for this parameter to send
** the parameter format (paramfmt) information to the
** server, prior to sending all parameter data.
** Set *data to NULL and datalen = 0, to indicate that
** the length of text data is unknown and we want to
** send it in chunks to the server with ct_send_data().
*/
ct_setparam(cmd, ¶mfmt, NULL, 0, 0);
/*
** Another LOB parameter (image), sent in chunks with
** ct_send_data()
*/
strcpy(paramfmt.name, "@textparam");
paramfmt.namelen = CS_NULLTERM;
paramfmt.datatype = CS_IMAGE_TYPE;
paramfmt.maxlength = CS_UNUSED;
paramfmt.status = CS_INPUTVALUE;
paramfmt.locale = NULL;
/*
** Just like the previous parameter, invoke
** ct_setparam() for this parameter to send the
** parameter format.
*/
ct_setparam(cmd, ¶mfmt, NULL, 0, 0);
/*
** Repeat this sequence of filling paramfmt and calling
** ct_param() for any subsequent parameter that needs
** to be sent before finally sending the data chunks for
** the LOB type parameters.
*/
strcpy(paramfmt.name, "@any_otherparam");
paramfmt.namelen = CS_NULLTERM;
paramfmt.datatype = CS_MONEY_TYPE;
...
/*
** Send the first LOB (text) parameter in chunks of
** ‘BUFSIZE’ to the server. We must end with a 0 bytes
** write to indicate the end of the current parameter.
*/
fp = open(“huge_text_file”, O_RDWR, 0666);
do
{
num_read = read(fp, sendbuf, BUFSIZE);
ct_send_data(cmd, (CS_VOID *)sendbuf, num_read);
} while (num_read != 0);
/*
** Repeat the ct_send_data() loop for the next LOB
** parameter.
** Send the image parameter in chunks of ‘BUFSIZE’
** to the server as well and end with a 0 bytes write
** to indicate the end of the current parameter.
*/
fp = open(“large_image_file”, O_RDWR, 0666);
do
{
num_read = read(fp, sendbuf, BUFSIZE);
ct_send_data(cmd, (CS_VOID *)sendbuf, num_read);
} while (num_read != 0);
/*
** Ensure that all the data is flushed to the server
*/
ct_send(cmd);
Example 2 Sends LOB data as a stream using a prepared SQL statement:
/*
** Prepare the sql statement.
*/
sprintf(statement, "select title_id from mybooks
where title like (?) ");
/*
** Send the prepared statement to the server
*/
ct_dynamic(cmd, CS_PREPARE, "mydyn_stmt", CS_NULLTERM,
statement, CS_NULLTERM);
ct_send(cmd);
handle_results();
/*
** Promt user to provide a value for title
*/
printf("Enter title id value - enter an X if you wish
to stop: \n");
while (toupper(myblobtitle[0]) != 'X')
{
printf("Retrieve detail record for title: ?");
fgets(myblobtitle, 50, stdin);
/*
** Execute the dynamic statement.
*/
ct_dynamic(cmd, CS_PREPARE, "my_dyn_stmt",
CS_NULLTERM, statement, CS_NULLTERM);
/*
** Define the input parameter, a TEXT type that we
want to send in chunks to the server.
*/
memset(&data_format, 0, sizeof(data_format)) ;
data_format.namelen = CS_NULLTERM ;
data_format.datatype = CS_TEXT_TYPE;
data_format.maxlength = CS_UNUSED;
data_format.status = CS_INPUTVALUE;
ct_setparam(cmd, &data_format, NULL, 0, 0);
/*
** Send the ‘myblobtitle’ data in chunks of
** ‘CHUNKSIZE’ to the server with ct_send_data() and
** end with 0 bytes to indicate the end of data for
** this parameter. This is just an example to show
** how chunks can be sent. (myblobtitle[] is used as
** a simple example. This could also be replaced by
** large file which would be read in chunks from disk
** for example).
*/
bytesleft = strlen(myblobtitle);
bufp = myblobtitle;
do
{
sendbytes = min(bytesleft, CHUNKSIZE);
ct_send_data(cmd, (CS_VOID *)bufp, sendbytes);
bufp += bufp + sendbytes;
bytesleft -= sendbytes;
} while (bytesleft > 0)
/*
** End with 0 bytes to indicate the end of current
data.
*/
ct_send_data(cmd, (CS_VOID *)bufp, 0);
/*
** Insure that all the data is sent to the server.
*/
ct_send(cmd);
handle_results(cmd)
...
}
/*
** Deallocate the prepared statement and finish up.
*/
ct_dynamic(cmd, CS_DEALLOC, "my_dyn_stmt", CS_NULLTERM,
NULL, CS_UNUSED);
ct_send(cmd);
handle_results(cmd);