Large Object Locator Support

These connection capabilities indicate support for sending and receiving LOB locators.

Requesting LOB Locators from the Server

By default, when selecting LOB columns or values, Adaptive Server sends LOB data instead of LOB locators, regardless of the negotiated LOB locator support.

To explicitly request LOB locators or to request prefetched data, set these query-processing options using ct_options():
  • CS_OPT_LOBLOCATOR – a Boolean that, when set to CS_TRUE, requests the server to return a locator instead of a LOB value. Set this option before sending the query to the server. The default is CS_FALSE.

  • CS_OPT_LOBPREFETCHSIZE – an integer that specifies the size of the prefetched data that the server must send. For image locators, this size indicates the number of prefetched data bytes; for text and unitext locators, the number of characters.

    CS_OPT_LOBPREFETCHSIZE has a default value of 0, which informs the server not to send prefetched data. A value of -1 retrieves the entire LOB data for the requested LOB along with its locator.

Locator values and optional prefetched data are stored in the CS_LOCATOR datatype. Clients must allocate memory for CS_LOCATOR variables before requesting for locator data.

Example
Retrieves the LOB locator for a text value that needs to be truncated. See the Open Client Client-Library/C Reference Manual for more code examples.
CS_LOCATOR *lobloc;
CS_INT     prefetchsize;
CS_BOOL    boolval;
CS_INT     start, length;
CS_INT     outlen;
CS_CHAR    charbuf[1024];
CS_BIGINT  totallen;
...

/*
** Turn on option CS_LOBLOCATOR first and set the prefetchsize to 100.
*/boolval = CS_TRUE;
ct_options(conn, CS_SET, CS_OPT_LOBLOCATOR, &boolval, CS_UNUSED, NULL);
prefetchsize = 100;
ct_options(conn, CS_SET, CS_OPT_LOBPREFETCHSIZE, &prefetchsize, CS_UNUSED,
   NULL);

/*
** Allocate memory for the CS_LOCATOR.
*/
cs_locator_alloc(ctx, &lobloc);

/*
** Open a transaction and get the locator. The locator is only valid within a
** transaction.
*/
sprintf(cmdbuf, “begin transaction \
   select au_id, copy from pubs2..blurbs where au_id \
   like ‘486-29-%’”);
ct_command(cmd, CS_LANG_CMD, cmdbuf , CS_NULLTERM, CS_UNUSED);
ct_send(cmd);

/*
** Process results.
*/
while ((results_ret = ct_results(...)) == CS_SUCCEED)
{
   ...
}
   /*
   ** Bind the locator and fetch it.
   */
   strcpy(prmfmt.name, "@locatorparam");
   prmfmt.namelen = CS_NULLTERM;
   prmfmt.datatype = CS_TEXTLOCATOR_TYPE;
   prmfmt.maxlength = CS_UNUSED;
   ...

   ct_bind(cmd, 1, &fmt, lobloc, NULL, &indicator);
   ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, &count);
}

/*
** Use the cs_locator() routine to retrieve data from the fetched locator. 
** Get the prefetch length and the prefetch data.
*/
cs_locator(ctx, CS_GET, lobloc, CS_LCTR_PREFETCHLEN, (CS_VOID *)&prefetchsize,
   sizeof(CS_INT), &outlen);

cs_locator(ctx, CS_GET, lobloc, CS_LCTR_PREFETCHDATA, (CS_VOID *)charbuf,
   sizeof(charbuf), &outlen);

/*
** Retrieve the total length of the LOB data in the server for this
** locator.
*/
cs_locator(ctx, CS_GET, lobloc, CS_LCTR_LOBLEN,(CS_VOID *)&totallen,
   sizeof(totallen), &outlen);

/*
** Use the retrieved locator to perform an action to the LOB, pointed to by
** this locator in the server. 
**
** Get a substring from the text in the server, using a parameterized language
** command.
*/
start = 10;
length = 20;
sprintf(cmdbuf, “select return_lob(text, substring(@locatorparam, \
   start, length))”);
ct_command(cmd, CS_LANG_CMD, cmdbuf, CS_NULLTERM, CS_UNUSED);

/*
** Set the format structure and call ct_param()
*/
strcpy(prmfmt.name, "@locatorparam");
prmfmt.namelen = CS_NULLTERM;
prmfmt.datatype = CS_TEXTLOCATOR_TYPE;
prmfmt.format = CS_FMT_UNUSED;
prmfmt.maxlength = CS_UNUSED;
prmfmt.status = CS_INPUTVALUE;

indicator = 0;
ct_param(cmd, &prmfmt, (CS_VOID *)lobloc, CS_UNUSED, indicator);

/*
** Send the locator commands to the server.
*/
ct_send(cmd);

/*
** Process results.
*/
while ((results_ret = ct_results(...)) == CS_SUCCEED)
{
   ...
}

/*
** Truncate the text to 20 bytes and commit the transaction.
*/
sprintf(cmdbuf, “truncate lob @locatorparam (length) \
   commit transaction”);
ct_command(cmd, CS_LANG_CMD, cmdbuf, CS_NULLTERM, CS_UNUSED);
ct_param(cmd, &prmfmt, (CS_VOID *)lobloc, CS_UNUSED, indicator);

ct_send(cmd);

/*
** Process results.
*/
while ((results_ret = ct_results(...)) == CS_SUCCEED) 
{
   ...
}

/*
** The transaction is closed, deallocate the locator.
*/
cs_locator_drop(ctx, lobloc);