| Oracle FAQ | Your Portal to the Oracle Knowledge Grid | |
Home -> Community -> Usenet -> c.d.o.server -> Re: utl_file: to fflush or not to fflush?
> Chapter 18 shows how to do this with C > external procedures, and Chapter 19 does > it with Java.
Done this below. Thanks for the suggestion. I stil think utl_file !$*ks and that it is not properly documented that utl_file is not appropriate for binary files.
Note the "Sighs" in the comments.
Thanks, Joost
/*
* file_io.c: My First OCI for doing file I/O from whithin the database.
* It's goal is to provide an alternative to the freakin'
* utl_file package which refuses write large blob's.
*/ #include <oci.h> #include<stdio.h> #include<string.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h>
#define NullValue -1
#define CHUNKSIZ (1048576)
/*
/*
/* * open the file. creat if it does not exist and trunc if it exists. */
/*
long fiowrite (context, path, sql_select_lob)
OCIExtProcContext *context;
char *sql_select_lob;
{
int handle;
int i ;
unsigned char byte0, byte1;
char *initial_msg;
text *error_msg;
OCIEnv *envhp = (OCIEnv *) 0; /* env. handle */ OCISvcCtx *svchp = (OCISvcCtx *) 0; /* service handle */ OCIError *errhp = (OCIError *) 0; /* error handle */ OCIStmt *stmthp = (OCIStmt *) 0; /* statement handle */ /*
/* * Open the file. It should exist here */
if ((handle = open(path, O_RDWR|O_APPEND)) < 0) {
initial_msg = (text *)"Cannot open file ";
error_msg = OCIExtProcAllocCallMemory(context,
strlen(path) + strlen(initial_msg) + 1);
strcpy((char *)error_msg, (char *)initial_msg);
strcat((char *)error_msg, path);
OCIExtProcRaiseExcpWithMsg(context, 20001, error_msg, 0);
}
else {
OCILobLocator *lobloc;
OCIDefine *defnp1;
ub1 buffer [CHUNKSIZ];
ub4 amount, position,length;
sword status;
/*
* Allocate a lob locator.
*/
status = OCIDescriptorAlloc ((dvoid*) envhp, (dvoid**) &lobloc,
(ub4) OCI_DTYPE_LOB, (size_t) 0, (dvoid**) 0);
if (status) {
/*
* Select the lob into the locator. This seems to be a four step approach !
*
* 0. Allocate a statement handle (?)
*/
status = OCIHandleAlloc((dvoid *) envhp, (dvoid **)&stmthp,
(ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **)0);
if (status) {
/*
* 1. This call is magic. I think it wakes up the oracle.
*/
status = OCIStmtPrepare (stmthp, errhp, sql_select_lob,
(ub4) strlen ( (char *) sql_select_lob),
(ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT);
if (status) {
/*
* 2. Associate column 0 with our lob locator
*/
status = OCIDefineByPos (stmthp, &defnp1, errhp, (ub4) 1,
(dvoid *)&lobloc, (sb4)0,
(ub2) SQLT_BLOB,(dvoid *) 0,
(ub2 *) 0, (ub2 *) 0, (ub4) OCI_DEFAULT);
if (status) {
/*
* 3. Execute the select and fetch one row
*/
status = OCIStmtExecute (svchp, stmthp, errhp, (ub4) 1, (ub4) 0,
(CONST OCISnapshot*) 0, (OCISnapshot*) 0,
(ub4) OCI_DEFAULT);
if (status) {
/* * We now have a blob in lobloc. Get the totol length of the freakin' thing, * read in the chunks and append those to a file. Sigh^16. */
for (position = 1; position < length; position += amount) {
if ( (length - position) > CHUNKSIZ)
amount = CHUNKSIZ;
else
amount = length - position + 1;
/*
* I don't quite understand the streaming mechanism.. and I would
* be quite happy if this just works.
*/
status = OCILobRead (svchp, errhp, lobloc, &amount, position,
(dvoid *) buffer, sizeof (buffer), (dvoid *)0,
(sb4 (*)(dvoid *, dvoid *, ub4, ub1)) 0,
(ub2) 0, (ub1) SQLCS_IMPLICIT);
if (status) {
write (handle, buffer, amount);
} /* for (pos.. */
/* * Done (hopefully), clean up the mess.. */
} /* elze file is open ..*/
}
Received on Mon Nov 05 2001 - 17:04:40 CST
![]() |
![]() |