Re: Reading a Long raw into a PRO*C variable

From: Thomas J Kyte <tkyte_at_us.oracle.com>
Date: 1995/06/13
Message-ID: <3rkint$oj4_at_inet-nntp-gw-1.us.oracle.com>#1/1


mortens_at_cibadiag.com (Eric Mortensen) wrote:
>Has anyone been able to move a long raw field from an Oracle table into
>a C variable in PRO*C. We are having trouble figuring out how to do this.
>
>Eric Mortensen
>mortens_at_cibadiag.com

Here is a C subroutine that

- creates a table with a long raw in it.
- sets up a data structure capable of handling up to 10meg of raw data
- inserts a 'known' value into the table
- commits work
- retrieves and validates that 'known' value
- drops the table

It does this with 500,000 bytes of long raw stuff.

It shows *one* way of handling long raws. Another would be to use a mix of OCI and Pro*C to be able to fetch the long raw by piece.

Thomas Kyte
tkyte_at_us.oracle.com
Oracle Government


static void process()
{

/*
 * This is the data structure we will use with our LONG RAWs.  We will
 * always use pointers to this structure as we don't know how big we need
 * until runtime.  Will use malloc to allocate storage on the fly.
 */
 

typedef struct TAGmy_raw
{

	long		len;
	unsigned char	arr[1];
}
	my_raw;

/*
 * Use type equivalencing to tell Oracle that the C type "my_raw" is
 * equivalent to the Oracle type LONG VARRAW and can hold upto 10,000,000 
 * bytes of data (we will never allocate that much here, just an upper
  • bound */ EXEC SQL TYPE my_raw IS LONG VARRAW(10000000) REFERENCE;
my_raw	* buffer;
long	size = 500000;
int	i;

	/*
	 * we will allocate a little over 1/2 meg of space
	 */
	buffer = (my_raw *)malloc( size+sizeof(my_raw) );

	/*
	 * fill it up with every possible byte value from 0..254
	 */
	for( i = 0; i < size; i++ )
		buffer->arr[i] = i % 255;

	/*
	 * Just like a varchar, set the length field
	 */
	buffer->len = size;

	EXEC SQL WHENEVER SQLERROR CONTINUE;

	/*
	 * create a database table for the example, 
         * we drop at end of demo
	 */
	printf( " CREATE TABLE LONG_RAW_EXAMPLE ( X LONG RAW );\n" );
	EXEC SQL CREATE TABLE LONG_RAW_EXAMPLE ( X LONG RAW );

	EXEC SQL WHENEVER SQLERROR DO sqlerror_hard();

	/*
	 * Insert the long raw into the database
	 */
	printf( "INSERT INTO LONG_RAW_EXAMPLE (X) VALUES (:buffer);\n");
	EXEC SQL INSERT INTO LONG_RAW_EXAMPLE ( X ) VALUES (:buffer);

	/*
	 * commit the changes
	 */
	printf("EXEC SQL COMMIT WORK;\n" );
	EXEC SQL COMMIT WORK;

	/*
	 * Now, ZERO out the buffer so when we fetch, we know that the buffer
	 * was NOT equal to what it was on the insert.  Just to *prove* that
	 * the fetch got back the data we inserted
	 */
	memset( buffer->arr, 0, size );

	/*
	 * Select out the data
	 */
	printf( " SELECT X INTO :buffer FROM LONG_RAW_EXAMPLE;\n" );
	EXEC SQL SELECT X
			 INTO :buffer
			 FROM LONG_RAW_EXAMPLE;

	/* 
	 * show what size we got 
	 */
	printf( "The Length = %ld\n", buffer->len );

	/*
	 * Check each character to make sure it is what we inserted
	 */
	for( i = 0; i < size; i++ )
		if ( buffer->arr[i] != i % 255 ) 
		{
			printf( "Error! %d != %d\n", buffer->arr[i], i%255 );
			break;
		}

	/*
	 * drop that table
	 */
	printf( " DROP TABLE LONG_RAW_EXAMPLE;\n" );
	EXEC SQL DROP TABLE LONG_RAW_EXAMPLE;

} Received on Tue Jun 13 1995 - 00:00:00 CEST

Original text of this message