OCI编程高级篇(五) 分片查询
访问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); }
学习Oracle高级知识,编写高质量代码,尽在www.tomcoding.com

浙公网安备 33010602011771号