1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
|
// Copyright (c) 2000-2001 David Muse
// See the file COPYING for more information
#include "../../config.h"
#include <rudiments/environment.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#ifdef RUDIMENTS_NAMESPACE
using namespace rudiments;
#endif
#define FETCH_AT_ONCE 10
#define MAX_ITEM_BUFFER_SIZE 32768
extern "C" {
#include <oci.h>
}
sword ncols;
OCIEnv *env;
OCIServer *srv;
OCIError *err;
OCISvcCtx *svc;
OCISession *session;
OCITrans *trans;
OCIStmt *stmt;
int fetchatonce=FETCH_AT_ONCE;
int main(int argc, char **argv) {
if (argc<4) {
printf("usage: ora8test user password sid\n");
exit(0);
}
char *user=argv[1];
char *password=argv[2];
char *sid=argv[3];
char *query="begin select testclob into :clobindval from testtable2; end;";
environment envr;
envr.setValue("ORACLE_SID",sid);
envr.setValue("TWO_TASK",sid);
// init the timer
time_t starttime=time(NULL);
printf("oratest running, please wait...\n");
clock();
#ifdef HAVE_ORACLE_8i
OCIEnvCreate((OCIEnv **)&env,OCI_DEFAULT,(dvoid *)0,
(dvoid *(*)(dvoid *, size_t))0,
(dvoid *(*)(dvoid *, dvoid *, size_t))0,
(void (*)(dvoid *, dvoid *))0,
(size_t)0,(dvoid **)0);
#else
// initialize OCI
OCIInitialize(OCI_DEFAULT,(dvoid *)0,
(dvoid*(*)(dvoid *,size_t))0,
(dvoid*(*)(dvoid *,dvoid *,size_t))0,
(void(*)(dvoid *,dvoid *))0);
// init the environment
OCIEnvInit((OCIEnv **)&env,OCI_DEFAULT,(size_t)0,(dvoid **)0);
#endif
// allocate an error handle
OCIHandleAlloc((dvoid *)env,(dvoid **)&err,OCI_HTYPE_ERROR,
(size_t)0,(dvoid **)0);
// allocate a server handle
OCIHandleAlloc((dvoid *)env,(dvoid **)&srv,OCI_HTYPE_SERVER,
(size_t)0,(dvoid **)0);
// allocate a service context handle
OCIHandleAlloc((dvoid *)env,(dvoid **)&svc,OCI_HTYPE_SVCCTX,
(size_t)0,(dvoid **)0);
// attach to the server
OCIServerAttach(srv,err,(text *)sid,strlen(sid),0);
// attach the server to the service
OCIAttrSet((dvoid *)svc,OCI_HTYPE_SVCCTX,
(dvoid *)srv,(ub4)0,
OCI_ATTR_SERVER,(OCIError *)err);
// allocate a session handle
OCIHandleAlloc((dvoid *)env,
(dvoid **)&session,(ub4)OCI_HTYPE_SESSION,
(size_t)0,(dvoid **)0);
// set username and password
OCIAttrSet((dvoid *)session,(ub4)OCI_HTYPE_SESSION,
(dvoid *)user,(ub4)strlen(user),
(ub4)OCI_ATTR_USERNAME,err);
OCIAttrSet((dvoid *)session,(ub4)OCI_HTYPE_SESSION,
(dvoid *)password,(ub4)strlen(password),
(ub4)OCI_ATTR_PASSWORD,err);
// start a session
OCISessionBegin(svc,err,session,
OCI_CRED_RDBMS,(ub4)OCI_DEFAULT);
// attach the session to the service
OCIAttrSet((dvoid *)svc,(ub4)OCI_HTYPE_SVCCTX,
(dvoid *)session,(ub4)0,
(ub4)OCI_ATTR_SESSION,err);
// allocate a transaction handle
OCIHandleAlloc((dvoid *)env,
(dvoid **)&trans,OCI_HTYPE_TRANS,0,0);
// attach the transaction to the service
OCIAttrSet((dvoid *)svc,OCI_HTYPE_SVCCTX,
(dvoid *)trans,(ub4)0,
(ub4)OCI_ATTR_TRANS,err);
// initialize the column count
ncols=0;
// allocate a statement handle
OCIHandleAlloc((dvoid *)env,(dvoid **)&stmt,
OCI_HTYPE_STMT,
(size_t)0,(dvoid **)0);
// set the number of rows to prefetch
OCIAttrSet((dvoid *)stmt,OCI_HTYPE_STMT,
(dvoid *)&fetchatonce,(ub4)0,
OCI_ATTR_PREFETCH_ROWS,(OCIError *)err);
// prepare the query
OCIStmtPrepare(stmt,err,(text *)query,
(ub4)strlen(query),
(ub4)OCI_NTV_SYNTAX,
(ub4)OCI_DEFAULT);
ub2 stmttype;
OCIAttrGet(stmt,OCI_HTYPE_STMT,
(dvoid *)&stmttype,(ub4 *)NULL,
OCI_ATTR_STMT_TYPE,err);
ub4 iters=(stmttype!=OCI_STMT_SELECT);
// output bind
OCILobLocator *outbind_lob;
OCIDescriptorAlloc((dvoid *)env,
(dvoid **)&outbind_lob,(ub4)OCI_DTYPE_LOB,
(size_t)0,(dvoid **)0);
// bind the lob descriptor
OCIBind *outbind;
OCIBindByName(stmt,&outbind,err,
(text *)"clobindval",(sb4)10,
(dvoid *)&outbind_lob,
(sb4)sizeof(OCILobLocator *),
SQLT_CLOB,
(dvoid *)0,(ub2 *)0,(ub2 *)0,0,(ub4 *)0,
OCI_DEFAULT);
// execute the query
OCIStmtExecute(svc,stmt,err,iters,(ub4)0,NULL,NULL,
OCI_DEFAULT);
// fetch the clob
ub4 loblength;
OCILobGetLength(svc,err,outbind_lob,&loblength);
printf("length=%d\n",loblength);
char buf[MAX_ITEM_BUFFER_SIZE];
ub4 retlen=MAX_ITEM_BUFFER_SIZE;
ub4 offset=1;
int loop=0;
while (offset<=loblength) {
// read a segment from the lob
sword retval=OCILobRead(svc,
err,
outbind_lob,
&retlen,
offset,
(dvoid *)buf,
MAX_ITEM_BUFFER_SIZE,
(dvoid *)NULL,
(sb4(*)(dvoid *,CONST dvoid *,ub4,ub1))NULL,
(ub2)0,
(ub1)SQLCS_IMPLICIT);
// OCILobRead returns OCI_INVALID_HANDLE if
// the LOB is NULL. In that case, return a
// NULL field.
// Otherwise, start sending the field (if we
// haven't already), send a segment of the LOB,
// move to the next segment and reset the
// amount to read.
if (retval==OCI_INVALID_HANDLE) {
break;
} else {
offset=offset+retlen;
retlen=MAX_ITEM_BUFFER_SIZE;
}
loop++;
}
printf("%d loops\n",loop);
// free resources
OCILobFreeTemporary(svc,err,outbind_lob);
OCILobClose(svc,err,outbind_lob);
OCIDescriptorFree(outbind_lob,OCI_DTYPE_LOB);
OCIHandleFree(stmt,OCI_HTYPE_STMT);
// log off
OCIHandleFree(trans,OCI_HTYPE_TRANS);
OCISessionEnd(svc,err,session,OCI_DEFAULT);
OCIHandleFree(session,OCI_HTYPE_SESSION);
OCIServerDetach(srv,err,OCI_DEFAULT);
// clean up
OCIHandleFree(svc,OCI_HTYPE_SVCCTX);
OCIHandleFree(srv,OCI_HTYPE_SERVER);
OCIHandleFree(err,OCI_HTYPE_ERROR);
printf("total system time used: %ld\n",clock());
printf("total real time: %ld\n",time(NULL)-starttime);
}
|