| René Nyffenegger's collection of things on the web | |
|
René Nyffenegger on Oracle - Most wanted - Feedback
|
A simple OCI program | ||
|
The following code fragment is supposed to show how a connection can be made to an Oracle database with OCI.
Obviously, it won't do anything meaningful. However, it is possible to see that the application has connected
to the database using v$session.
I was able to compile and link it on Linux with gcc:
gcc -c -I$ORACLE_HOME/rdbms/demo \
-I$ORACLE_HOME/rdbms/public \
-I$ORACLE_HOME/plsql/public \
-I$ORACLE_HOME/network/public \
-I$ORACLE_HOME/precomp/public oci_test.c
gcc -L$ORACLE_HOME/lib/ -L$ORACLE_HOME/rdbms/lib/ -o oci_test oci_test.o -lclntsh `cat $ORACLE_HOME/lib/sysliblist`
With mingw, the programm can be compiled and linked like this:
gcc -o first.exe -I%ORACLE_HOME%\oci\include oci_test.c %ORACLE_HOME%\bin\oci.dll
#include <oci.h>
void checkerr(OCIError* err, sword status) {
text errbuf[512];
ub4 buflen;
ub4 errcode;
switch (status) {
case OCI_SUCCESS:
break;
case OCI_SUCCESS_WITH_INFO:
printf("Error - OCI_SUCCESS_WITH_INFO\n");
break;
case OCI_NEED_DATA:
printf("Error - OCI_NEED_DATA\n");
break;
case OCI_NO_DATA:
printf("Error - OCI_NO_DATA\n");
break;
case OCI_ERROR:
OCIErrorGet ( err, (ub4) 1, (text *) NULL, &errcode,
errbuf, (ub4) sizeof(errbuf), (ub4) OCI_HTYPE_ERROR);
printf("Error - %s\n", errbuf);
break;
case OCI_INVALID_HANDLE:
printf("Error - OCI_INVALID_HANDLE\n");
break;
case OCI_STILL_EXECUTING:
printf("Error - OCI_STILL_EXECUTE\n");
break;
case OCI_CONTINUE:
printf("Error - OCI_CONTINUE\n");
break;
default:
break;
}
}
void parse_connect_string(
char* connect_str, /* in */
text username[30], /* out */
text password[30], /* out */
text dbname [30] /* out */
) {
username[0] = 0;
password[0] = 0;
dbname [0] = 0;
char* to=username;
while (*connect_str) {
if (*connect_str == '/') {
*to=0;
to=password;
connect_str++;
continue;
}
if (*connect_str == '@') {
*to=0;
to=dbname;
connect_str++;
continue;
}
*to=*connect_str;
to++;
connect_str++;
}
*to=0;
}
int main(int argc, char* argv[]) {
/* (void) OCIInitialize((ub4) OCI_DEFAULT, (dvoid *) 0,
(dvoid * (*)(dvoid *, size_t)) 0,
(dvoid * (*)(dvoid *, dvoid *, size_t))0,
(void (*)(dvoid *, dvoid *)) 0 ); */
/* The environment handle defines a context in which all OCI functions are
invoked. Each environment handle contains a memory cache, which allows for
fast memory access. All memory allocation under the environment handle is
done from this cache. Access to the cache is serialized if multiple
threads try to allocate memory under the same environment handle. When
multiple threads share a single environment handle, they may block on
access to the cache. The environment handle is passed as the parent
parameter to the OCIHandleAlloc() call to allocate all other handle types.
Bind and define handles are allocated implicitly.
*/
OCIEnv* env;
/* The error handle is passed as a parameter to most OCI calls. The error
handle maintains information about errors that occur during an OCI
operation. If an error occurs in a call, the error handle can be passed to
OCIErrorGet() to obtain additional information about the error that
occurred. Allocating the error handle is one of the first steps in an OCI
application because most OCI calls require an error handle as one of its
parameters. */
OCIError* err;
OCIServer* srv;
OCISvcCtx* svc;
OCISession* ses;
text username[30];
text password[30];
text dbname [30];
sword r;
if (argc < 2) {
printf("usage %s username/password[@dbname]\n");
exit (-1);
}
parse_connect_string(argv[1],username, password, dbname);
env = 0;
err = 0;
srv = 0;
svc = 0;
ses = 0;
r=OCIEnvCreate( &env, OCI_DEFAULT, 0, 0, 0, 0, 0, 0);
if (r != OCI_SUCCESS) {
printf("OCIEnvCreate failed!\n");
goto clean_up;
}
OCIHandleAlloc(env, (dvoid**)&err, OCI_HTYPE_ERROR, 0, 0);
OCIHandleAlloc(env, (dvoid**)&srv, OCI_HTYPE_SERVER, 0, 0);
OCIHandleAlloc(env, (dvoid**)&svc, OCI_HTYPE_SVCCTX, 0, 0);
OCIHandleAlloc(env, (dvoid**)&ses, OCI_HTYPE_SESSION, 0, 0);
r=OCIServerAttach(srv, err, dbname, strlen(dbname), (ub4) OCI_DEFAULT);
if (r != OCI_SUCCESS) {
checkerr(err, r);
goto clean_up;
}
/* set attribute server context in the service context */
OCIAttrSet(svc, OCI_HTYPE_SVCCTX, srv, 0, OCI_ATTR_SERVER, err);
OCIAttrSet(ses, OCI_HTYPE_SESSION, username, strlen(username), OCI_ATTR_USERNAME, err);
OCIAttrSet(ses, OCI_HTYPE_SESSION, password, strlen(password), OCI_ATTR_PASSWORD, err);
r=OCISessionBegin (svc, err, ses, OCI_CRED_RDBMS, OCI_DEFAULT);
checkerr(err, r);
clean_up:
if (env) OCIHandleFree(env, OCI_HTYPE_ENV );
if (err) OCIHandleFree(err, OCI_HTYPE_ERROR );
if (srv) OCIHandleFree(srv, OCI_HTYPE_SERVER);
if (svc) OCIHandleFree(svc, OCI_HTYPE_SVCCTX);
OCITerminate(OCI_DEFAULT);
return 0;
}
Links
See also adpoci.
|