在前面的OCI编程基础中有些函数还有替代品,我们在这里介绍一下,希望你在看到别的代码中用了不同的函数而不至于迷惑。
前面我们介绍绑定函数时用到了OCIBindByPos()函数,这是一个按照占位符位置来绑定变量的函数,还有一个相关的函数叫OCIBindByName(),是按照占位符的名称来绑定变量的。函数原型如下。
sword OCIBindByName ( OCIStmt *stmtp,
OCIBind **bindpp,
OCIError *errhp,
const OraText *placeholder,
sb4 placeh_len,
void *valuep,
sb4 value_sz,
ub2 dty,
void *indp,
ub2 *alenp,
ub2 *rcodep,
ub4 maxarr_len,
ub4 *curelep,
ub4 mode );
其他参数都与OCIBindByPos()函数一样,只是原来的position参数变成了两个参数,一个是占位符的名称,一个是占位符的长度,参数含义如下。
placeholder是一个输入参数,是占位符的名称,以NULL结尾的字符串。
placeh_len是一个输入参数,是上面占位符名称的长度,以字节计算。
我们前面的例子中向test_tab中插入一条数据,用位置绑定函数时SQL语句为INSERT INTO test_tab VALUES (:1, :2, :3),那么用名称绑定函数时SQL语句就是INSERT INTO test_tab VALUES (:v_id, :v_name, :v_addr)。那么在绑定时函数应该是下面这样的,只拿第一个字段ID作为例子。
rc = OCIBindByName(smtp, errhp, ":v_id", strlen(":v_id"), &id, 4, SQLT_INT,
&ind_id, &alen_id, &rcode_id, 0, NULL, OCI_DEFAULT);
上面灰色背景的部分,就是绑定占位符名称的示例,函数通过这个名称在SQL语句文本中进行匹配。
绑定函数有位置绑定和名称绑定两个函数,但是定义函数只有位置定义一个函数,这一点要注意。
前面我们在查询语句返回结果集时用到了OCIStmtFetch()函数,这个函数在11g之后被废弃掉了,代替它的是OCIStmtFetch2()函数,让程序员能更好的控制怎样获取结果集中的数据。
sword OCIStmtFetch2 ( OCIStmt *stmthp,
OCIError *errhp,
ub4 nrows,
ub2 orientation,
sb4 fetchOffset,
ub4 mode );
参数stmthp,errhp,nrows,mode跟OCIStmtFetch()中的一样,不同的是下面两个参数。
orientation,取数据的方向,现在有了更多的选择。
OCI_DEFAULT - 与OCI_FETCH_NEXT一样,作为缺省值。
OCI_FETCH_CURRENT - 获取当前行的数据。
OCI_FETCH_NEXT - 获取当前行的下一条数据。
OCI_FETCH_FIRST - 取结果集中的第一条数据。
OCI_FETCH_LAST - 取结果集中的最后一条数据。
OCI_FETCH_PRIOR - 取当前行的上一条数据。
OCI_FETCH_ABSOLUTE - 获取fetchOffset参数指定行号的那条数据。
OCI_FETCH_RELATIVE - 获取fetchOffset参数指定的相对于当前行的那行数据。
fetchOffset是一个新增加的输入参数,指定获取数据的偏移量,也就是行号。上面参数中取绝对数据时,fetchOffset指定结果集中的数据绝对行号。上面参数中取相对数据时,fetchOffset指定结果集中相对当前行号的偏移量,比如fetchOffset=5,那么是当前行号加5后的行号,所在的数据。如果fetchOffset=-3,那么是当前行号减3后的行号,所在的数据,相当于当前行前面第三行的数据。
前几节的例子中我们在表中插入一条数据后,要提交改变,相当于sqlplus中的commit命令。如果我们不想提交改变,怎样放弃数据呢?在sqlplus中会用到rollback命令,那么在OCI中也有一个函数对应,叫做OCITransRollback()。看一下它的原型和参数。
sword OCITransRollback ( void *svchp,
OCIError *errhp,
ub4 flags );
svchp是一个输入参数,服务上下文句柄。
errhp是一个输入参数,错误句柄,返回错误码和错误信息文本。
flags是一个输入参数,唯一值为OCI_DEFAULT。
当调用OCI函数更改数据时(包括插入、更新、删除,还有其他操作),如果没有用OCITransCommit()函数显式提交改变,而是直接断开数据库连接,那么Oracle不会回滚这些操作,而是做了隐式提交,改变已经记录到了数据库中,所以在断开数据库前有不确定的数据改变,要用OCITransRollback()函数把改变回滚回来。