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
