Oracle通过OCI批量加载需要注意的问题
采用OCI的最大好处就是:它是最切近Oracle底层的技术,因此,效率是最高的。同时,它是跨平台的。因此,在我给出的ORADBI库,除了OCI之外,没有其他外部依赖,稍加改动,就可以移植到非Windows平台上或其他嵌入式平台。
然而,OCI也比较不容易使用。它的功能之强,粒度之细,语法之烦琐,都不适合今天熟悉了快速开发模式的人员使用。然而,OCI的高效,直接根植于数据库核心,跨平台的语言特性,是其他如OO4O、OLEDB、ADO等COM方式不具备的。
下面就从之前一段时间参与SN数据库集群中间件开发的实践中积累的一点经验,分享如下:
1.支持的类型 char , unsigned char, int, double,float,long ,char*
大部分类型直接调用接口不会出什么问题,但是char*尤其需要注意,容易出现乱码。
2.加载的流程大致如下:
建立连接-》准备sql statement -》 绑定数据-》excute-》commit
对于字符串数据的加载的,需要采用三维数组,表中字符串类型的列数为一维,行数为第二维,每个字段的长度为第三维。
三维数组的变量声明必须与excute的调用在同一个作用域内,否则,execute的时候,三维数组的所在的内存可能已经被重新分配,execute读取绑定数据便会出现乱码。
此处比较容易出错,虽然execute并没有显示的调用绑定的数据变量,但是内部实现确实读取绑定变量的数据批量加载到数据库中。此处不注意,容易导致加载数据变成乱码。并且此错误是偶发性错误,不是每次运行都会出现,毕竟内存分配是随机的。
3.加载NULL字段。
批量加载的接口都是逐列加载某种类型的数据,并且保证各列之间通过位置保证一行数据的对应关系,那么如果一列数据中有NULL字段又该如何呢?
OCI接口中也是支持NULL数据加载的,是通过indicator(指示器)实现的。indicator是一个指针,类型是sb2,可以指向一个字段,也可以指向一列字段。在绑定接口:OCIBindByPos(stmthp,&bindhp,errhp,1, (dvoid *)&aa,4, SQLT_INT, (void*)&indicator, NULL, NULL,0,0,0); 作为参数传入,其元素数目与绑定的数据列表aa的元素数目相等。位置一一对应。indicator对应位置为-1
的表示写入NULL,>=0表示写入数据列表aa中的值。
下面是官方文档中,对指示器使用的介绍。
1.加载,数据写入NULL:
Input
For input host variables, the OCI application can assign the following values to an indicator variable:
Table 2-7 Input Indicator Values
Input Indicator Value | Action Taken by Oracle |
---|---|
-1 |
Oracle assigns a |
>=0 |
Oracle assigns the value of the input variable to the column. |
2.查询,数据读取NULL:
Output
On output, Oracle can assign the following values to an indicator variable:
Table 2-8 Output Indicator Values
Indicator Variables for Named Data Types and REFs
参考文献:
1.OCI安装部署以及常用的OCI函数介绍
http://www.cnblogs.com/joeblackzqq/archive/2011/04/24/2026461.html
2. OCI读取单条记录
http://www.cnblogs.com/joeblackzqq/archive/2011/04/26/2028847.html
3.OCI写入NULL