sqludf_length()--SQL LOB locator length


  Syntax
 #include <sqludf.h>

 extern int SQL_API_FN sqludf_length(   
    udf_locator * udfloc_p,                                       
    long *        return_len_p)

  Service Program Name: QSYS/QSQAPIS

  Default Public Authority: *USE

  Threadsafe: Yes

The sqludf_length() function returns the length of the LOB data represented by a LOB locator.


Parameters

udfloc_p
(Input) Pointer to the LOB locator value.

return_len_p
(Input/Output) Pointer to the length of the LOB data represented by the LOB locator.


Authorities

No authorization is required.


Return Value

sqludf_length()

returns an integer. Possible values are:

0
sqludf_length() was successful. The information is returned in the buffer pointed to by return_len_p.

-3
squdf_length() was not successful. An invalid parameter was passed into the function.

-423
squdf_length() was not successful. The udfloc_p parameter points to an invalid locator value.

-901
sqludf_length() was not successful. An SQL system error has occurred.

-7034
sqludf_length() was not successful. LOB locators are not allowed with COMMIT(*NONE).


Error Messages

Message ID Error Message Text
SQL7034 D LOB locators are not allowed with COMMIT(*NONE).
SQL0901 D SQL system error.
SQL0952 D Processing of the SQL statement ended.
CPF9872 E Program or service program &1 in library &2 ended. Reason code &3.

Usage Notes

  1. This API is used to find out the length of a LOB value when it receives a locator.

Related Information


Example

See Code disclaimer information for information pertaining to code examples.

This UDF takes a locator for an input LOB, and returns a locator for another LOB which is a subset of the input LOB. There are some criteria passed as a second input value, which tell the UDF how exactly to break up the input LOB.

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sql.h>
#include <sqludf.h>
 
void SQL_API_FN lob_subsetter(
          udf_locator * lob_input,   /* locator of LOB value to carve up */
          char        * criteria,    /* criteria for carving */
          udf_locator * lob_output,  /* locator of result LOB value */
          sqlint16 * inp_nul,
          sqlint16 * cri_nul,
          sqlint16 * out_nul,
          char     * sqlstate,
          char     * funcname,
          char     * specname,
          char     * msgtext ) {
 
       /* local vars */
       short j;              /* local indexing var */
       int   rc;             /* return code variable for API calls */
       sqlint32  input_len;  /* receiver for input LOB length */
       sqlint32  input_pos;  /* current position for scanning input LOB */
       char lob_buf[100];    /* data buffer */
       sqlint32  input_rec;  /* number of bytes read by sqludf_substr */
       sqlint32  output_rec; /* number of bytes written by sqludf_append */
 
       /*---------------------------------------------
        * UDF Program Logic Starts Here
        *---------------------------------------------
        * What we do is create an output handle, and then
        * loop over the input, 50 bytes at a time.
        * Depending on the "criteria" passed in, we may decide
        * to append the 50 byte input lob segment to the output, or not.
        *---------------------------------------------
        * Create the output locator, right in the return buffer.
        */
 
       rc = sqludf_create_locator(SQL_TYP_CLOB, &lob_output);
       /* Error and exit if unable to create locator */
       if (rc) {
          memcpy (sqlstate, "38901", 5); 
          /* special sqlstate for this condition */
          goto exit;
       }
       /* Find out the size of the input LOB value */
       rc = sqludf_length(lob_input, &input_len) ;
       /* Error and exit if unable to find out length */
       if (rc) {
          memcpy (sqlstate, "38902", 5); 
          /* special sqlstate for this condition */
          goto exit;
       }
       /* Loop to read next 50 bytes, and append to result if it meets
        * the criteria.
        */
       for (input_pos = 1; (input_pos < input_len); input_pos += 50) {
         /* Read the next 50 (or less) bytes of the input LOB value */
         rc = sqludf_substr(lob_input, input_pos, 50,
                            (unsigned char *) lob_buf, &input_rec) ;
         /* Error and exit if unable to read the segment */
         if (rc) {
            memcpy (sqlstate, "38903", 5); 
            /* special sqlstate for this condition */
            goto exit;
         }
         /* apply the criteria for appending this segment to result
	  * if (...predicate involving buffer and criteria...) {
	  * The example shows if the segment matches the first 6
          * characters with the criteria it is appended.
	  */
         if (memcmp(lob_buf,criteria,6) == 0) {         
            rc = sqludf_append(lob_output,
                       (unsigned char *) lob_buf, input_rec, &output_rec) ;
            /* Error and exit if unable to read the 50 byte segment */
            if (rc) {
               memcpy (sqlstate, "38904", 5); 
               /* special sqlstate for this condition */
               goto exit;
	    }
	 }
         /* } end if criteria for inclusion met */
       } /* end of for loop, processing 50-byte chunks of input LOB
          * if we fall out of for loop, we are successful, and done.
	  */
       *out_nul = 0;
       exit: /* used for errors, which will override null-ness of output. */
       return;
       }

Referring to this UDF code, observe that:

Following is the CREATE FUNCTION statement for this UDF:

     CREATE FUNCTION carve(CLOB(50M) AS LOCATOR, VARCHAR(255) ) 
       RETURNS CLOB(50M) AS LOCATOR 
       NOT NULL CALL 
       DETERMINISTIC
       NO SQL 
       NO EXTERNAL ACTION 
       LANGUAGE C 
       PARAMETER STYLE DB2SQL 
       EXTERNAL NAME 'MYLIB/LOBUDFS(lob_subsetter)' ;

Referring to this statement, observe that:

Now you can successfully run the following statement:

    strcpy(hvchar,"return this text 1                                "         
                  "remove 1                                          "         
                  "return this text 2                                "         
                  "remove 2                                          ");       
    exec sql set :hvloc = clob(:hvchar);                                       
    exec sql set :hvloc2 = carve(:hvloc,'return');                             
    strcpy(hvchar,"");                                                         
    exec sql set :hvchar = char(:hvloc2);                                      

The UDF is used to subset the value represented by the host variable :hvchar. The first and third 50 byte character segments are returned from the UDF.



API introduced: V5R3
Top | Database and File APIs |APIs by category