OCI编程高级篇(六) LOB定位符

从这节开始我们来处理LOB数据的操作,LOB是Large Object的缩写,是Oracle用于替换LONG和LONG RAW类型而设置的,目前LOB的存储数据量最大达到了128T字节。随着LOB使用越来越频繁,LOB的操作也变得重要。LOB主要分为CLOB和BLOB两种,分别用于存放字符数据和二进制数据。

LOB操作中有一个重要的概念是LOB定位符,顾名思义就是通过它找到LOB数据存储的位置,由于LOB数据与LOB列数据是分开存储的,所以Oracle在LOB列数据中存储了LOB定位符,通过定位符再找到LOB数据存储的位置。

在OCI中LOB定位符是一个指针,类型为OCILobLocator,它指向一个分配的空间,空间中包含了LOB定位的信息。所以在使用LOB定位符之前,要先分配定位符,用到函数为OCIDescriptorAlloc(),先看看函数的原型和参数。

sword OCIDescriptorAlloc ( const void *parenth,
    void    **descpp,
    ub4     type,
    size_t  xtramem_sz,
    void     **usrmempp);

parenth是一个输入参数,要分配描述符的父句柄,这里是环境句柄。

descpp是一个输出参数,是一个指针的指针,返回描述符的指针。

type是一个输入参数,指示返回描述符的类型,这里输入OCI_DTYPE_LOB,返回LOB定位符。

xtramem_sz是一个输入参数,随描述符额外分配的内存大小。

usrmempp是一个输出参数,返回用户分配的额外内存的指针。

用OCIDescriptorAlloc()分配的描述符,需要用OCIDescriptorFree()函数释放,不要错用OCIHandleFree()函数。

sword OCIDescriptorFree ( void *descp, ub4 type );

descp是一个输入参数,是描述符的指针。

type是一个输入参数,是描述符的类型。

看一个分配LOB定位符的例子。

OCIEnv		*envhp = NULL;

int alloc_lob_locator(void)
{
    sword		     rc;
    sb4              ec;
    OCILobLocator    *locp;
    text             errbuf[512];


    /* 分配LOB定位符 */
    rc = OCIDescriptorAlloc((const void *)envhp, (void **)&locp,
        OCI_DTYPE_LOB, 0, (void **)NULL);
    if (rc != OCI_SUCCESS) {
        OCIErrorGet(envhp, 1, NULL, &ec, errbuf, 512, OCI_HTYPE_ERROR);
        fprintf(stderr, "OCIDescriptorAlloc() - [%d] %s\n", ec, errbuf);
        return (-1);
    }

    /* 释放LOB定位符 */
    rc = OCIDescriptorFree((void *)locp, OCI_DTYPE_LOB);
    if (rc != OCI_SUCCESS) {
        OCIErrorGet(errhp, 1, NULL, &ec, errbuf, 512, OCI_HTYPE_ERROR);
        fprintf(stderr, "OCIDescriptorFree() - [%d] %s\n", ec, errbuf);
        return (-1);
    }

    return (0);
}

LOB定位符在分配之后,只能在查询时才有用,这时可以通过查询结果填充LOB定位符空间,使之与一个LOB字段关联起来,然后才能再操作这个字段。但是如果想要插入一个LOB字段,分配后的LOB定位符由于没有内容,是不能使用的,首先要把它变成一个空LOB定位符才行,也就是要初始化这个定位符。这一步要用到OCIAttrSet()函数,设置空LOB定位符的操作如下。

ub4    lob_empty = 0;

if (OCI_SUCCESS != check_oci_error(errhp,
    OCIAttrSet((void *)(*locp), (ub4)OCI_DTYPE_LOB,
    (void *)&lob_empty, (ub4)0, (ub4)OCI_ATTR_LOBEMPTY, errhp))) 
    return (-1);

这样就创建好了一个空的LOB定位符,就可以通过OCI函数插入到一个LOB字段中了,然后通过查询语句再把定位符与LOB字段关联起来,就可以操作LOB字段了。那么不通过查询关联定位符和LOB字段可不可以呢?答案是不行。空LOB字段在插入时,Oracle要做一系列操作,才能生成真正的定位符数据,这个数据与空LOB定位符中的数据是不一样的,所以通过空LOB定位符插入LOB字段后,不能用这个空LOB定位符直接操作LOB字段。

下一节我们看看怎样插入LOB数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值