#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <oci.h>
static text *username = (text *) "system";
static text *password = (text *) "orcl";
/* Define SQL statements to be used in program. */
static text *insert = (text *)"INSERT INTO cdemo81_emp(empno, ename, job, sal, deptno)\VALUES (:empno, :ename, :job, :sal, :deptno)";
static text *seldept = (text *)"SELECT dname FROM cdemo81_dept WHERE deptno = :1";
static text *maxemp = (text *)"SELECT NVL(MAX(empno), 0) FROM cdemo81_emp";
static text *selemp = (text *)"SELECT ename, job FROM cdemo81_emp";
static OCIEnv *envhp;
static OCIError *errhp;
static void checkerr(/*_ OCIError *errhp, sword status _*/);
static void cleanup(/*_ void _*/);
static void myfflush(/*_ void _*/);
static void disconnect_server(/*_ OCISvcCtx *svchp, OCISession *authp,
OCIServer *srvhp _*/);
static void drop_tables(/*_ OCISvcCtx *svchp, OCIStmt *stmthp _*/);
static int setup_tables(/*_ OCISvcCtx *svchp, OCIStmt *stmthp _*/);
int main(/*_ int argc, char *argv[] _*/);
static sword status;
int main(argc, argv)
int argc;
char *argv[];
{
sword empno, sal, deptno;
sword len, len2, rv, dsize, dsize2;
sb4 enamelen = 10;
sb4 joblen = 9;
sb4 deptlen = 14;
sb2 sal_ind, job_ind;
sb2 db_type, db2_type;
sb1 name_buf[20], name2_buf[20];
text *cp, *ename, *job, *dept;
sb2 ind[2]; /* indicator */
ub2 alen[2]; /* actual length */
ub2 rlen[2]; /* return length */
OCIDescribe *dschndl1 = (OCIDescribe *) 0,
*dschndl2 = (OCIDescribe *) 0,
*dschndl3 = (OCIDescribe *) 0;
OCISession *authp = (OCISession *) 0;
OCIServer *srvhp;
OCISvcCtx *svchp;
OCIStmt *inserthp,
*stmthp,
*stmthp1;
OCIDefine *defnp = (OCIDefine *) 0;
OCIBind *bnd1p = (OCIBind *) 0; /* the first bind handle */
OCIBind *bnd2p = (OCIBind *) 0; /* the second bind handle */
OCIBind *bnd3p = (OCIBind *) 0; /* the third bind handle */
OCIBind *bnd4p = (OCIBind *) 0; /* the fourth bind handle */
OCIBind *bnd5p = (OCIBind *) 0; /* the fifth bind handle */
OCIBind *bnd6p = (OCIBind *) 0; /* the sixth bind handle */
boolean tab_exists = FALSE;
/*
函数原型:sword OCIInitialize (ub4 mode,CONST dvoid *ctxp,CONST dvoid *(*malocfp) (dvoid *ctxp,size_t size _),
CONST dvoid *(*ralocfp)(_ dvoid *ctxp,dvoid *memptr,size_t newsize _),
CONST void (*mfreefp)(_ dvoid *ctxp,dvoid *memptr _))
参数说明
: mode——详细说明OCI初始化(Initialize)模式(mode)。
它的取值如下: OCI_DEFAULT——缺省模式; OCI_THREADED——多线程模式;
在该模式下,各并发处理中不为用户所见的内在数据结构受各自线程的保护,而不受别的线程干扰;
OCI_OBJECT——使用目标特性; OCI_SHARED——使用共享内存; OCI_EVENTS—— Mode参数可以拥有多个值,以“|”符号分隔各取值项。
*Ctxp——用户定义的内存回调程序;默认为0
*(*malocfp)——用户定义的内存分配程序;默认为0
*(*ralocfp)——重新分配内存程序;默认为0
*memptr 是指向内存块的指针;
*mfreefp——用户定义的内存释放程序;默认为0
该函数使用举例如下:
OCIInitialize((ub4) OCI_THREADED | OCI_OBJECT,
(dvoid *)0,(dvoid *(*)(dvoid *, size_t)) 0,
(dvoid * (*)(dvoid *,dvoid *,size_t))0,
(void (*)(dvoid *,dvoid *)) 0 )
注意!OCIEnvCreate() 可以代替OCIInitialize() 和OCIEnvInit()
*/
(void) OCIInitialize((ub4) OCI_DEFAULT, (dvoid *)0,
(dvoid * (*)(dvoid *, size_t)) 0,
(dvoid * (*)(dvoid *, dvoid *, size_t))0,
(void (*)(dvoid *, dvoid *)) 0 );
/*
在初始化OCI程序环境以后,使用OCIEnvInit来初始化OCI的环境句柄,该函数成功返回0。
函数原型:sword OCIEnvInit(OCIEnv **envhpp, ub4 mode, size_t xtramemsz, dvoid **usrmempp )
参数说明: **envhpp——指向环境句柄的指针;
mode——指定初始化环境句柄的模式,其取值如下:
OCI_DEFAULT——缺省模式;在缺省模式下,OCI库始终互斥各环境句柄;
OCI_NO_MUTEX——非互斥模式;在该模式下,OCI库各环境句柄并不互斥,所有的掉用都使用同一个环境句柄,并且只能有一个环境句柄起作用。
OCI_ENV_NO_UCB——禁止回滚模式;该模式用以禁止在环境句柄初始化过程中的动态CALL_BACK函数掉用;
Xtramemsz——指定在该环境句柄生存期内分配内存的数量;
**usrmempp——指向Xtramemsz参数的指针;usermempp参数是函数返回值;
该函数使用举例如下:
应用例子:
OCIEnvInit((OCIEnv **) envhp, (ub4) OCI_DEFAULT, (size_t) 0,(dvoid **) 0)
*/
(void) OCIEnvInit( (OCIEnv **) &envhp, OCI_DEFAULT, (size_t) 0,
(dvoid **) 0 );
/*
一个OCI连接在建立前,还需要将所需要的句柄一一分配成功,在OCI8里,使用函数OCIHandleAlloc来分配各句柄,成功返回0。
函数原型:sword OCIHandleAlloc(CONST dvoid *parenth, dvoid **hndlpp, ub4 type, size_t xtramem_sz, dvoid **usrmempp )
参数说明: *parenth——已初始化后的环境句柄;
**hndlpp——函数执行成功后,返回的一个OCI句柄;
该返回值的具体含义由type参数来决定;
type——参数hndlpp的返回值的类型;其常用取值如下:
OCI_HTYPE_SVCCTX——返回一个服务类型的句柄;
OCI_HTYPE_ERROR——返回一个错误类型的句柄;
OCI_HTYPE_SESSION——返回一个会话类型的句柄;
OCI_HTYPE_SERVER——返回一个服务器类型的句柄;
OCI_HTYPE_STMT——返回一个陈述类型的句柄;
其中,陈述类型的句柄是在创建与数据库会话成功后,将要对数据库进行操作时分配的,其余类型的句柄是在环境句柄初始化后分配的;
xtramem_sz——指定在该句柄生存期内分配内存的数量;
**usrmempp——指向xtramem_sz参数的指针,由函数返回;
该函数使用举例如下:
OCIHandleAlloc((dvoid *) *envhp, (dvoid **) errhp, (ub4) OCI_HTYPE_ERROR, (size_t) 0, (dvoid **) 0)
*/
(void) OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &errhp, OCI_HTYPE_ERROR,
(size_t) 0, (dvoid **) 0);
/* server contexts */
(void) OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &srvhp, OCI_HTYPE_SERVER,
(size_t) 0, (dvoid **) 0);
(void) OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &svchp, OCI_HTYPE_SVCCTX,
(size_t) 0, (dvoid **) 0);
/*
分配各OCI句柄后,还需要做的工作是为OCI操作数据源创建存储路径,并将各项参数设置到相应的句柄中,
这项工作由函数OCIServerAttach和OCIAttrSet来实现。成功,返回0。
函数原型:sword OCIServerAttach(OCIServer *srvhp, OCIError *errhp, CONST text *dblink, sb4 dblink_len, ub4 mode )
参数说明:
*srvhp——已分配成功的服务器句柄;
*errhp——已分配成功的错误类型句柄;若该函数执行出错,则该参数承载出错的原因;
*dblink——登陆数据库的实例名;
dblink_len——参数*dblink字符串的长度;
mode——指定不同操作的模式。现在只有一种模式可选:OCI_DEFAULT。
该函数使用举例如下:OCIServerAttach(srvhp, errhp, (text *) cstring, (sb4) strlen((char *)cstring), (ub4) OCI_DEFAULT))
*/
(void) OCIServerAttach( srvhp, errhp, (text *)"", strlen(""), 0);
/*
函数原型:sword OCIAttrSet (CONST dvoid *trgthndlp, ub4 trghndltyp, dvoid *attributep, ub4 *sizep, ub4 attrtype, OCIError *errhp )
参数说明:
*trgthndlp——需要设置的句柄,该句柄在这之前已分配成功;该参数由trghndltyp参数决定;
trghndltyp——参数trgthndlp的类型,其取值参见OCIHandleAlloc函数说明中的type参数说明;
*attributep——设置参数trgthndlp的值;
*sizep——attributep参数指向的字符串长度;
attrtype——参数attributep的类型;
其取值如下:
OCI_ATTR_SERVER——服务器类型;
OCI_ATTR_USERNAME——用户名类型
OCI_ATTR_PASSWORD——用户密码类型 �