OCI编程高级篇(五) 分片查询

有分片插入的操作,就会有分片查询的操作,分片插入用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);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值