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
![]() |
![]() |