有关于oci的中文资料吗? oracle的文档最全,orafaq.com上关于oci的比较多 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 http://www.pdown.net/那里也有很多资料书 OCI(Oracle Call Interface)是ORACLE提供的面向程序员的C语言编程接口,是开发ORACLE数据库应用软件的较好的工具。用它开发出的应用程序运行效率比用Pro*C/C++的要高。程序员利用其中提供的函数,能访问Oracle数据库服务器。OCI应用程序的主要任务之一是处理SQL语句或PL/SQL脚本,在程序执行的过程中将用户对数据库服务器的请求送到ORACLE服务器,并接收来自服务器的响应。Oracle数据库服务器和OCI函数库的线程安全特征允许程序开发人员在多线程环境中使用OCI。有了线程安全特征,OCI函数代码才具有可重入性,因此从应用程序的多个线程中同时发出OCI调用才不会彼此产生不良影响。要实现多线程安全化,应用程序必须在调用OCI初始化函数时定义mode参数为OCI_THREADED,它告诉OCI接口层,本应用程序运行在安全的多线程方式中。OCI的OCIThread软件包提供了一些线程化函数,主要有三种类型。实际使用情况见后面的编程实例。⑴初始化和结束函数在调用其他函数之前必须调用OCIThreadProcessInit()函数,执行OCIThread软件包的初始化工作,然后再调用OCIThreadInit()函数,初始化OCIThread上下文,供其他OCIThread函数使用。调用OCIThreadTerm()函数,结束OCIThread接口层的处理,释放OCIThread上下文内存。⑵线程管理函数类型为OCIThreadHandle的线程句柄用于表示线程的内部数据结构。在使用之前,应该用OCIThreadHndInit()来分配和初始化,用完后应调用OCIThreadHndDestroy()来释放内存。用OCIThreadCreate()函数创建新线程。用OCIThreadId类型变量来标识一个线程。使用OCIThreadIdInit()来分配和初始化线程ID,而用OCIThreadIdDestroy()来释放线程ID的结构。用OCIThreadClose()函数关闭线程。OCIThreadJoin()函数允许调用者线程与其他线程连接,当要想连接的线程正在运行时,阻塞调用该函数的线程。直到指定的线程运行结束,这个调用者线程才被唤醒,方能继续执行下去。⑶互斥锁管理函数在应用程序中用类型OCIThreadMutex的变量来表示互斥锁。互斥锁在使用之前必须用OCIThreadMutexInit()初始化,用完后要用OCIThreadMutexDestroy()释放内存结构。一个线程可用OCIThreadMutexAcquire()来掌握一把互斥锁,任何时候至多只能有一个线程掌握这把互斥锁,掌握这把互斥锁的线程能够用OCIThreadMutexRelease()来释放它。当一个线程掌握这把互斥锁后,其它线程若想再掌握这把互斥锁,就会被阻塞。直到掌握这把锁的线程释放它,被阻塞的线程之一才能得到它,获得互斥锁的线程才能继续执行下去。3. 多线程应用软件的编制下面用一个实例来讲述多线程方式ORACLE应用程序的编写和多线程的运行机制,仍以显示地震三维数据体为例。将从数据库中读数据当作一个线程,数据解压,三维图象处理和显示当作另一个线程,在进程中给出二个数据缓冲区,使这二个线程轮流交叉使用这二个缓冲区。并用二把互斥锁来协调这二个线程对缓冲区的使用。为能清楚而简单地说明线程和互斥锁的使用,这里仅给出程序的主要代码段。#include <oci.h>struct thrs_data { OCIThreadMutex *mutex1; 缓冲区1互斥锁 int buffer1[10240]; 缓冲区1 OCIThreadMutex *mutex2; 缓冲区2互斥锁 int buffer2[10240]; 缓冲区2 int flag; 数据处理结束标志 int start_read; 开始读数据标志 int start_disp; 开始显示数据标志};OCIEnv *envhp; OCI环境句柄OCIError *errhp; OCI错误记录句柄void read_fun(dvoid *arg);void disp_fun(dvoid *arg);int main(int argc, char* argv[]){ OCIThreadId *tId1,*tId2; 线程ID句柄 OCIThreadHandle *tHnd1,*tHnd2; 线程句柄 struct thrs_data op_data; 定义数据OCI初始化(线程安全性)和分配句柄: OCIEnvCreate((OCIEnv **) &envhp,OCI_THREADED,(dvoid *)0, (dvoid* (*)(dvoid*,size_t))0,(dvoid* (*)(dvoid*,dvoid*,size_t))0, (void (*)(dvoid *, dvoid *)) 0, (size_t) 0,(dvoid **) 0 ); OCIHandleAlloc((dvoid *)envhp, (dvoid **)&errhp, OCI_HTYPE_ERROR,(size_t)0, (dvoid **)0);线程软件包和线程初始化: OCIThreadProcessInit(); OCIThreadInit(envhp,errhp);初始化线程ID和线程句柄: OCIThreadIdInit(envhp,errhp,&tId1); OCIThreadHndInit(envhp,errhp,&tHnd1); OCIThreadIdInit(envhp,errhp,&tId2); OCIThreadHndInit(envhp,errhp,&tHnd2);分配和初始化互斥锁: OCIThreadMutexInit(envhp,errhp,&(op_data.mutex1)); OCIThreadMutexInit(envhp,errhp,&(op_data.mutex2));创建新的线程,执行线程函数调用: op_data.start_read=0; op_data.start_disp=0; OCIThreadCreate(envhp,errhp,read_fun,(dvoid *)&op_data, tId1,tHnd1); OCIThreadCreate(envhp,errhp,disp_fun,(dvoid *)&op_data, tId2,tHnd2);参数read_fun和disp_fun是二个线程函数,op_data是送给线程函数的变量。等待线程执行完成并关闭线程句柄: OCIThreadJoin(envhp,errhp,tHnd1); OCIThreadClose(envhp,errhp,tHnd1); OCIThreadJoin(envhp,errhp,tHnd2); OCIThreadClose(envhp,errhp,tHnd2);释放互斥锁内存: OCIThreadMutexDestroy(envhp,errhp,&(op_data.mutex1));OCIThreadMutexDestroy(envhp,errhp,&(op_data.mutex2));释放线程ID和线程句柄:OCIThreadIdDestroy(envhp,errhp,&tId1); OCIThreadHndDestroy(envhp,errhp,&tHnd1); OCIThreadIdDestroy(envhp,errhp,&tId2); OCIThreadHndDestroy(envhp,errhp,&tHnd2);释放线程上下文: OCIThreadTerm(envhp,errhp);释放所有分配的句柄。 OCIHandleFree((dvoid *)errhp, OCI_HTYPE_ERROR); OCIHandleFree((dvoid *)envhp, OCI_HTYPE_ENV);}下面是二个线程函数主要代码段:void read_fun(dvoid* arg) { 读数据进缓冲区函数 struct thrs_data *op_data; int n=0; op_data=(struct thrs_data *)arg; for(int k=0;k<5;k++) { 在实际应用中,此处可为for(;;) ,让退出循环的条件由要读的实际数据确定,这里用5次循环,是为了能够运行给出的框架程序。 OCIThreadMutexAcquire(envhp,errhp,op_data->mutex1); 获得互斥锁 op_data->start_read=1; 告诉显示线程,读线程已使用缓冲区 printf("read data into buffer1 ...\n");在实际应用中,此处应调用“读数据进缓冲区1”的函数。 OCIThreadMutexRelease(envhp,errhp,op_data->mutex1); 释放互斥锁在实际应用中,此处可为:当所有数据都读完时,使op_data->flag=1;并退出循环体 OCIThreadMutexAcquire(envhp,errhp,op_data->mutex2); printf("read data into buffer2 ...\n");在实际应用中,此处应调用“读数据进缓冲区2”的函数。 if(n==0) while(op_data->start_disp==0); 循环第一次结束时要等待显示线程启 n=1; 动并使用缓冲区 OCIThreadMutexRelease(envhp,errhp,op_data->mutex2); if(k==2) { 这里的代码段,是为了能演示框架程序; op_data->flag=2; 在实际应用中,此处可为: break; 当所有数据都读完时,使op_data->flag=2; } 并退出循环体 }}void disp_fun(dvoid* arg) { 处理和显示数据函数 struct thrs_data *op_data; op_data=(struct thrs_data *)arg; for(;;) { while(op_data->start_read==0); 开始时保证读数据线程先使用缓冲区 OCIThreadMutexAcquire(envhp,errhp,op_data->mutex1); op_data->start_disp=1; 告诉读数据线程,显示线程已开始使用缓冲区 printf(" display buffer1 ...\n");在实际应用中,此处应调用“使用缓冲区1中数据,解压,图象处理和显示”的函数。 OCIThreadMutexRelease(envhp,errhp,op_data->mutex1); if(op_data->flag==1) break; 退出循环体,返回 OCIThreadMutexAcquire(envhp,errhp,op_data->mutex2); printf(" display buffer2 ...\n");在实际应用中,此处应调用“使用缓冲区2中数据,解压,图象处理和显示”的函数。 OCIThreadMutexRelease(envhp,errhp,op_data->mutex2); if(op_data->flag==2) break; 退出循环体,返回 }} thrs_data结构中的几个变量用于读数据线程和显示线程的开始控制和结束控制。start_read:当二个线程同时启动或显示线程先启动时,保证读数据线程先使用缓冲区,=1表示读数据线程已使用了缓冲区;start_disp:在读数据线程对缓冲区进行第一轮操作时,当它已将2个缓冲区写满,而此时显示线程还没有启动或还没有使用过缓冲区,这时应将读数据线程阻塞住,防止它覆盖掉缓冲区中未显示的数据,=1表示显示线程已启动并已使用了缓冲区。在后续交替读数据和显示数据的过程中,由互斥锁来协调二个线程之间的关系。Flag:用于标识数据的结束,=1表示在缓冲区1上结束,=2表示在缓冲区2上结束。 在PC机LINUX下,使用ORACLE 8i数据库,框架程序的编译连结命令为:gcc -g -o thread thread.cpp \-I$ORACLE_HOME/rdbms/demo -I/usr/i386-glibc20-linux/include \-I$ORACLE_HOME/rdbms/public -I$ORACLE_HOME/network/public \-L$ORACLE_HOME/lib -lclntsh 标准 + 全面 : otn.oracle.com 编译包就卡机的问题 nls_length_semantics参数这个意思吗? 在Solaris上安装oracle 10g提示错误 谁有ORACLE FOR VISTA的请联系QQ:81194882谢谢 一个sql或存储过程的问题。 Update一个表格里的属性的问题 Oracle权限设置问题 如何从sale表COPY一条记录插入sale表中? 在linux7.2下安装oracle8.16的问题 敏感话题---值得讨论 oracle9i没有pro*c了吗?为什么在网上下载的软件中安装选项没有? 急!!!!!oracle安装问题???????给分
那里也有很多资料书
Oracle数据库服务器和OCI函数库的线程安全特征允许程序开发人员在多线程环境中使用OCI。有了线程安全特征,OCI函数代码才具有可重入性,因此从应用程序的多个线程中同时发出OCI调用才不会彼此产生不良影响。要实现多线程安全化,应用程序必须在调用OCI初始化函数时定义mode参数为OCI_THREADED,它告诉OCI接口层,本应用程序运行在安全的多线程方式中。
OCI的OCIThread软件包提供了一些线程化函数,主要有三种类型。实际使用情况见后面的编程实例。
⑴初始化和结束函数
在调用其他函数之前必须调用OCIThreadProcessInit()函数,执行OCIThread软件包的初始化工作,然后再调用OCIThreadInit()函数,初始化OCIThread上下文,供其他OCIThread函数使用。调用OCIThreadTerm()函数,结束OCIThread接口层的处理,释放OCIThread上下文内存。
⑵线程管理函数
类型为OCIThreadHandle的线程句柄用于表示线程的内部数据结构。在使用之前,应该用OCIThreadHndInit()来分配和初始化,用完后应调用OCIThreadHndDestroy()来释放内存。用OCIThreadCreate()函数创建新线程。用OCIThreadId类型变量来标识一个线程。使用OCIThreadIdInit()来分配和初始化线程ID,而用OCIThreadIdDestroy()来释放线程ID的结构。用OCIThreadClose()函数关闭线程。OCIThreadJoin()函数允许调用者线程与其他线程连接,当要想连接的线程正在运行时,阻塞调用该函数的线程。直到指定的线程运行结束,这个调用者线程才被唤醒,方能继续执行下去。
⑶互斥锁管理函数
在应用程序中用类型OCIThreadMutex的变量来表示互斥锁。互斥锁在使用之前必须用OCIThreadMutexInit()初始化,用完后要用OCIThreadMutexDestroy()释放内存结构。一个线程可用OCIThreadMutexAcquire()来掌握一把互斥锁,任何时候至多只能有一个线程掌握这把互斥锁,掌握这把互斥锁的线程能够用OCIThreadMutexRelease()来释放它。当一个线程掌握这把互斥锁后,其它线程若想再掌握这把互斥锁,就会被阻塞。直到掌握这把锁的线程释放它,被阻塞的线程之一才能得到它,获得互斥锁的线程才能继续执行下去。
3. 多线程应用软件的编制
下面用一个实例来讲述多线程方式ORACLE应用程序的编写和多线程的运行机制,仍以显示地震三维数据体为例。将从数据库中读数据当作一个线程,数据解压,三维图象处理和显示当作另一个线程,在进程中给出二个数据缓冲区,使这二个线程轮流交叉使用这二个缓冲区。并用二把互斥锁来协调这二个线程对缓冲区的使用。为能清楚而简单地说明线程和互斥锁的使用,这里仅给出程序的主要代码段。
#include <oci.h>
struct thrs_data {
OCIThreadMutex *mutex1; 缓冲区1互斥锁
int buffer1[10240]; 缓冲区1
OCIThreadMutex *mutex2; 缓冲区2互斥锁
int buffer2[10240]; 缓冲区2
int flag; 数据处理结束标志
int start_read; 开始读数据标志
int start_disp; 开始显示数据标志
};
OCIEnv *envhp; OCI环境句柄
OCIError *errhp; OCI错误记录句柄
void read_fun(dvoid *arg);
void disp_fun(dvoid *arg);
int main(int argc, char* argv[])
{
OCIThreadId *tId1,*tId2; 线程ID句柄
OCIThreadHandle *tHnd1,*tHnd2; 线程句柄
struct thrs_data op_data; 定义数据
OCI初始化(线程安全性)和分配句柄:
OCIEnvCreate((OCIEnv **) &envhp,OCI_THREADED,(dvoid *)0,
(dvoid* (*)(dvoid*,size_t))0,(dvoid* (*)(dvoid*,dvoid*,size_t))0,
(void (*)(dvoid *, dvoid *)) 0, (size_t) 0,(dvoid **) 0 );
OCIHandleAlloc((dvoid *)envhp, (dvoid **)&errhp,
OCI_HTYPE_ERROR,(size_t)0, (dvoid **)0);
线程软件包和线程初始化:
OCIThreadProcessInit();
OCIThreadInit(envhp,errhp);
初始化线程ID和线程句柄:
OCIThreadIdInit(envhp,errhp,&tId1);
OCIThreadHndInit(envhp,errhp,&tHnd1);
OCIThreadIdInit(envhp,errhp,&tId2);
OCIThreadHndInit(envhp,errhp,&tHnd2);
分配和初始化互斥锁:
OCIThreadMutexInit(envhp,errhp,&(op_data.mutex1));
OCIThreadMutexInit(envhp,errhp,&(op_data.mutex2));
创建新的线程,执行线程函数调用:
op_data.start_read=0;
op_data.start_disp=0;
OCIThreadCreate(envhp,errhp,read_fun,(dvoid *)&op_data,
tId1,tHnd1);
OCIThreadCreate(envhp,errhp,disp_fun,(dvoid *)&op_data,
tId2,tHnd2);
参数read_fun和disp_fun是二个线程函数,op_data是送给线程函数的变量。
等待线程执行完成并关闭线程句柄:
OCIThreadJoin(envhp,errhp,tHnd1);
OCIThreadClose(envhp,errhp,tHnd1);
OCIThreadJoin(envhp,errhp,tHnd2);
OCIThreadClose(envhp,errhp,tHnd2);
释放互斥锁内存:
OCIThreadMutexDestroy(envhp,errhp,&(op_data.mutex1));
OCIThreadMutexDestroy(envhp,errhp,&(op_data.mutex2));
释放线程ID和线程句柄:
OCIThreadIdDestroy(envhp,errhp,&tId1);
OCIThreadHndDestroy(envhp,errhp,&tHnd1);
OCIThreadIdDestroy(envhp,errhp,&tId2);
OCIThreadHndDestroy(envhp,errhp,&tHnd2);
释放线程上下文:
OCIThreadTerm(envhp,errhp);
释放所有分配的句柄。
OCIHandleFree((dvoid *)errhp, OCI_HTYPE_ERROR);
OCIHandleFree((dvoid *)envhp, OCI_HTYPE_ENV);
}
下面是二个线程函数主要代码段:
void read_fun(dvoid* arg) { 读数据进缓冲区函数
struct thrs_data *op_data;
int n=0;
op_data=(struct thrs_data *)arg;
for(int k=0;k<5;k++) { 在实际应用中,此处可为for(;;) ,让退出循环的
条件由要读的实际数据确定,这里用5次循环,是为
了能够运行给出的框架程序。
OCIThreadMutexAcquire(envhp,errhp,op_data->mutex1); 获得互斥锁
op_data->start_read=1; 告诉显示线程,读线程已使用缓冲区
printf("read data into buffer1 ...\n");
在实际应用中,此处应调用“读数据进缓冲区1”的函数。
OCIThreadMutexRelease(envhp,errhp,op_data->mutex1); 释放互斥锁
在实际应用中,此处可为:当所有数据都读完时,使op_data->flag=1;并退出循环体
OCIThreadMutexAcquire(envhp,errhp,op_data->mutex2);
printf("read data into buffer2 ...\n");
在实际应用中,此处应调用“读数据进缓冲区2”的函数。
if(n==0) while(op_data->start_disp==0); 循环第一次结束时要等待显示线程启
n=1; 动并使用缓冲区
OCIThreadMutexRelease(envhp,errhp,op_data->mutex2);
if(k==2) { 这里的代码段,是为了能演示框架程序;
op_data->flag=2; 在实际应用中,此处可为:
break; 当所有数据都读完时,使op_data->flag=2;
} 并退出循环体
}
}void disp_fun(dvoid* arg) { 处理和显示数据函数
struct thrs_data *op_data;
op_data=(struct thrs_data *)arg; for(;;) {
while(op_data->start_read==0); 开始时保证读数据线程先使用缓冲区
OCIThreadMutexAcquire(envhp,errhp,op_data->mutex1);
op_data->start_disp=1; 告诉读数据线程,显示线程已开始使用缓冲区
printf(" display buffer1 ...\n");
在实际应用中,此处应调用“使用缓冲区1中数据,解压,图象处理和显示”的函数。
OCIThreadMutexRelease(envhp,errhp,op_data->mutex1);
if(op_data->flag==1) break; 退出循环体,返回
OCIThreadMutexAcquire(envhp,errhp,op_data->mutex2);
printf(" display buffer2 ...\n");
在实际应用中,此处应调用“使用缓冲区2中数据,解压,图象处理和显示”的函数。
OCIThreadMutexRelease(envhp,errhp,op_data->mutex2);
if(op_data->flag==2) break; 退出循环体,返回
}
}
thrs_data结构中的几个变量用于读数据线程和显示线程的开始控制和结束控制。start_read:当二个线程同时启动或显示线程先启动时,保证读数据线程先使用缓冲区,=1表示读数据线程已使用了缓冲区;start_disp:在读数据线程对缓冲区进行第一轮操作时,当它已将2个缓冲区写满,而此时显示线程还没有启动或还没有使用过缓冲区,这时应将读数据线程阻塞住,防止它覆盖掉缓冲区中未显示的数据,=1表示显示线程已启动并已使用了缓冲区。在后续交替读数据和显示数据的过程中,由互斥锁来协调二个线程之间的关系。Flag:用于标识数据的结束,=1表示在缓冲区1上结束,=2表示在缓冲区2上结束。
在PC机LINUX下,使用ORACLE 8i数据库,框架程序的编译连结命令为:
gcc -g -o thread thread.cpp \
-I$ORACLE_HOME/rdbms/demo -I/usr/i386-glibc20-linux/include \
-I$ORACLE_HOME/rdbms/public -I$ORACLE_HOME/network/public \
-L$ORACLE_HOME/lib -lclntsh