访问www.tomcoding.com网站,学习Oracle内部数据结构,详细文档说明,下载Oracle的exp/imp,DUL,logminer,ASM工具的源代码,学习高技术含量的内容。
有分片插入的操作,就会有分片查询的操作,分片插入用OCI_DATA_AT_EXEC模式来绑定输入变量,分片查询需要用到OCI_DYNAMIC_FETCH模式来定义输出变量。分片查询的步骤如下。
1. 分片OCI语句句柄。
2. 准备SQL语句,语法分析。
3. 定义输出变量,输出变量为空指针,运行时再提供缓冲区。使用OCI_DYNAMIC_FETCH模式。
4. 执行查询语句。
5. 执行OCIStmtFetch()函数,这时会返回OCI_NEED_DATA。
6. 执行OCIStmtSetPieceInfo()函数,指定接收数据的缓冲区地址和缓冲区大小。
7. 再执行OCIStmtFetch()函数,这时接收缓冲区中会有返回的数据,如果没有后续的数据了,Fetch函数会返回OCI_SUCESS,整个分片查询结束,如果还有剩余数据,Fetch函数还会返回OCI_NEED_DATA,这时跳到第6步,继续执行。
我们把上一次插入的数据再读出来,使用分片查询的步骤,请看完整的代码。
OCIEnv *envhp = NULL;
OCIError *errhp = NULL;
OCIServer *svrhp = NULL;
OCISession *usrhp = NULL;
OCISvcCtx *svchp = NULL;
OCIStmt *smthp = NULL;/* 分片查询LONG数据 */
int select_long_piece(void){sword rc;int slen;sb2 ind_info;ub4 alen_info;ub2 rcode_info;OCIDefine *defp;char sqltxt[1024];char long_buf[4096];/* 分配OCI语句句柄 */rc = OCIHandleAlloc((void *)envhp,(void **)&smthp,OCI_HTYPE_STMT,0,(void **)NULL);if (rc != OCI_SUCCESS) {fprintf(stderr, "OCIHandleAlloc() - allocate statement handle error !\n");return (-1);}/* 生成SQL语句文本 */strcpy(sqltxt, "SELECT INFO FROM test_long_tab WHERE ID=1");slen = strlen(sqltxt);/* 准备语句 */if (check_oci_error(errhp,OCIStmtPrepare(smthp, errhp, (const OraText *)sqltxt, slen,OCI_NTV_SYNTAX, OCI_DEFAULT)) < 0)return (-1);/* 定义INFO的输出变量,使用NULL值,使用OCI_DYNAMIC_FETCH模式,* value_sz要设置成读取数据的最大值*/if (check_oci_error(errhp,OCIDefineByPos((OCIStmt *)smthp,(OCIDefine **)&defp,errhp,(ub4)1, /* position */(void *)NULL, /* valuep */(sb4)0x7FFFFFFF, /* value_sz */(ub2)SQLT_LNG, /* dty */(void *)NULL, /* indp */(ub2 *)NULL, /* alenp */(ub2 *)NULL, /* column return code pointer */(ub4)0, /* maxarr_len */(ub4 *)NULL, /* curelep */(ub4)OCI_DYNAMIC_FETCH)) < 0)return (-1);/* 执行OCI语句 */if (check_oci_error(errhp,OCIStmtExecute(svchp,smthp, /* stmthp */errhp, /* errhp */0, /* iters */0, /* rowoff */NULL, /* snap_in */NULL, /* snap_out */OCI_DEFAULT) /* mode */) < 0)return (-1);/* 循环处理获取的数据,在这里为了方便,只把数据长度打印出来 */while (1) {if ((rc = check_oci_error(errhp,OCIStmtFetch(smthp, errhp, 1, OCI_FETCH_NEXT, OCI_DEFAULT))) < 0)return (-1);if (rc == OCI_SUCCESS) {/* 返回数据完毕,退出循环,注意这里还有数据,要处理掉 */fprintf(stdout, "data actual length: %d\n", alen_info);break;}if (rc != OCI_NEED_DATA) {fprintf(stderr, "data fetch not completed !\n");return (-1);}/* 处理数据 */fprintf(stdout, "data actual length: %d\n", alen_info);/* 设置数据片信息,alen_info设置一次返回的最大数据量 */alen_info = 4000;if (check_oci_error(errhp,OCIStmtSetPieceInfo((void *)defp, OCI_HTYPE_DEFINE,errhp, (const void *)long_buf, &alen_info,OCI_ONE_PIECE, (const void *)&ind_info, &rcode_info)) < 0)return (-1);}return (0);
}