Home » Developer & Programmer » Precompilers, OCI & OCCI » reading CLOB in Pro*C
reading CLOB in Pro*C [message #200671] Tue, 31 October 2006 19:49 Go to next message
schentor
Messages: 2
Registered: October 2006
Junior Member
I'm working on a Pro*C program that passes a temporary CLOB to a stored procedure, which then fills the CLOB with data. I'm trying to read the CLOB and stream its contents over an open network connection, but the data read is garbage. I know the stored procedure works because I've used it together with another procedure that creates a file on the server containing the CLOB contents. When I read that file and stream its contents, everything works, but writing, reading, and then deleting a file is an inefficient method.

My code looks like this:
EXEC SQL BEGIN DECLARE SECTION;
   char buf[513];
EXEC SQL END DECLARE SECTION;
 
EXEC SQL BEGIN DECLARE SECTION;
        char db[64];
        char n[4], s[10], c[4], loc[3];
        char dt_on[24];
        char dt_off[24];
        int recordlen = BLKSIZE; /* BLKSIZE = 4096 */
        long total;
        long offset = 0;
        long amount = 512;
EXEC SQL END DECLARE SECTION;
int done = 0;

/* Code to load n, s, c, loc, dt_on, dt_off and to open database connection. */

 EXEC SQL AT :db EXECUTE
        DECLARE
        myclob CLOB;
        BEGIN
          DBMS_LOB.createtemporary(myclob, TRUE, DBMS_LOB.session);
          mypkg.myproc(:n, :s, :c, :loc, :dt_on, :dt_off, myclob, :recordlen);
         :total := DBMS_LOB.GETLENGTH(myclob);
       END;
       END-EXEC;

/* Read CLOB. */
while (!done) {
            fprintf(stderr, "offset=%ld\n", offset);

            EXEC SQL AT :sisdb EXECUTE
            BEGIN
              DBMS_LOB.READ(myclob, :amount, :offset, :buf);
            END;
            END-EXEC;
        offset += amount;
        if (offset >= total) { done = 1; }
        fprintf(stderr, "buf len=%d\n", strlen(buf));
        put_data(fp, buf, strlen(buf)); /* Function that uses fwrite to write buf to open file stream. */
}


When I used printf to display the contents of buf, every run of the loop displayed garbage values like
DV\uffff(\uffff@X b@\uffff@\uffff@\uffffUc
(The characters after DV appear as symbols onscreen.)
I've also tried declaring buf like this:
 typedef struct {short len; char arr[513];} vc;

EXEC SQL BEGIN DECLARE SECTION;
   EXEC SQL TYPE vc IS VARCHAR(512);
   vc buf;
EXEC SQL END DECLARE SECTION;

and then using buf.arr as the string in put_data, but the results are the same. I've also tried declaring myclob as an OCIClobLocator* with no luck.

Any help would be appreciated! Thanks in advance.

[Updated on: Tue, 31 October 2006 19:49]

Report message to a moderator

Re: reading CLOB in Pro*C [message #201134 is a reply to message #200671] Thu, 02 November 2006 14:02 Go to previous message
schentor
Messages: 2
Registered: October 2006
Junior Member
Ok, I've fixed the problem. The problematic function is part of a larger Pro*C application, and it was not displaying Oracle error messages. When I put the function is a separate testing application, I got error messages about the way myclob was declared and about an out-of-bounds argument in DBMS_LOB.read. When I made myclob an OCIClobLocator pointer, treated it as a host variable, and set offest to an initial value of 1, everything worked.
Previous Topic: occi connection pool is not working
Next Topic: Pro*C and Express Edition
Goto Forum:
  


Current Time: Fri Dec 09 05:47:32 CST 2016

Total time taken to generate the page: 0.26501 seconds