Re: Blobs (JPEG images) and Pro*C/C++ (Oracle 8)
Date: 1998/09/14
Message-ID: <35fe67b1.83374245_at_newshost.us.oracle.com>#1/1
here is a way to access the LOB data from any of the recent precompilers. This demos insert/update, you could turn it around for a read...[Tom Kyte had the original Idea for this BTW]
Name: proc_blob.PC
Category: Pro*C
Port: Generic
Description: Example of Using Pro*C to insert/update a BLOB column,
(piecewise). This would work with a V7 precopiler. Uses DBMS_LOB.WRITE
to do the work... [could be further extended to store the filename in
the table and even use the DBMS_LOB.READ to read it back]
/*
create table test_o8blob ( the_blob blob );
and the package:
create package test_o8blob_pkg
as
g_blob blob;
end;
*/
/*
I use the package to maintain my Lob Locator instead of trying to muck
around with it in pro*c
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sqlproto.h>
#include <sqlca.h>
#define BUF_SIZE 15000
#define min(a, b) (((a) < (b)) ? (a) : (b))
void sqlerror(void); /* handles unrecoverable errors */
typedef struct { short len; char arr[32000]; } my_blob;
EXEC SQL BEGIN DECLARE SECTION;
EXEC SQL TYPE my_blob is VARRAW(32000);
my_blob blob_piece; char * data; int data_size; int amt_to_write; int amt_written; VARCHAR username[20]; VARCHAR password[20]; VARCHAR connect[20];
EXEC SQL END DECLARE SECTION; int main(int argc, char *argv[ ], char *envp[ ]) {
FILE* input; char Infile[128]; int fsize, chunk; char *buff; int count = 0; if(argc < 5) { printf("Not enough arguments\nUsage: progname.exe user password connect filename\n"); return 1; } strcpy((char *)username.arr, argv[1]); /* copy the username */ username.len = (short) strlen((char *)username.arr); strcpy((char *)password.arr, argv[2]); /* copy the password */ password.len = (short) strlen((char *)password.arr); strcpy((char *)connect.arr, argv[3]); /* copy the connect string */ connect.len = (short) strlen((char *)connect.arr); strcpy(Infile,argv[4]); input = fopen( Infile, "rb" ); if ( input == NULL ) { printf( "unable to open input file %s\n",argv[4]); return 1; } printf( "Input file %s opened\n",Infile); buff = (char *) malloc(BUF_SIZE); if (buff == NULL) { printf("unable to allocate %d bytes for temp buffer\n", BUF_SIZE); return 1; } fseek(input,0,SEEK_END); fsize = ftell(input); rewind(input); printf( "Input File length: %d\n", fsize); data_size = fsize; data = (char *)malloc( data_size ); memset( data, 0, data_size ); if (data == NULL) { printf("unable to allocate %d bytes for data buffer\n", fsize); return 1; } while ((chunk = fread(buff, 1, BUF_SIZE, input )) == BUF_SIZE ) { memcpy(data+(count * chunk),buff,chunk); count += 1; } printf("memory buffers allocated\n"); free(buff); EXEC SQL WHENEVER SQLERROR DO sqlerror(); EXEC SQL CONNECT :username IDENTIFIED BY :password USING :connect; printf("\nConnected to ORACLE as user: %s\n", username.arr); EXEC SQL EXECUTE BEGIN insert into test_o8blob values ( empty_blob() ) return the_blob into test_o8blob_pkg.g_blob; END; END-EXEC; for( amt_to_write = min(data_size,32000), amt_written = 0; amt_written < data_size; amt_written += amt_to_write, amt_to_write = min(32000,data_size-amt_written) ) { memmove( blob_piece.arr, data+amt_written, amt_to_write ); blob_piece.len = (short)amt_to_write; printf( "Writing blob from offset %d, for %d bytes\n", amt_written+1, amt_to_write ); EXEC SQL EXECUTE BEGIN dbms_lob.write( lob_loc =>test_o8blob_pkg.g_blob,amount => :amt_to_write,offset => :amt_written+1,buffer => :blob_piece );
END; END-EXEC; } printf("done\n"); free(data); EXEC SQL COMMIT WORK RELEASE; return 0;
}
void sqlerror()
{
EXEC SQL WHENEVER SQLERROR CONTINUE;
printf("\nORACLE error detected:\n"); printf("\n% .70s \n", sqlca.sqlerrm.sqlerrmc); EXEC SQL ROLLBACK RELEASE; exit(1);
} Received on Mon Sep 14 1998 - 00:00:00 CEST