OCI编程高级篇(十) 如何更简单的获取LOB定位符

OCI_LOB样例程序 OCI中有关LOB相关函数使用的样例程序 立即下载

访问www.tomcoding.com网站,学习Oracle内部数据结构,详细文档说明,下载Oracle的exp/imp,DUL,logminer,ASM工具的源代码,学习高技术含量的内容。

前面我们看到在LOB操作之前都要执行一个LOB SELECT操作,用于得到LOB定位符,尤其在插入一个空LOB,随后写入的情况,操作起来非常繁琐。那时我们希望有一种方法能简洁的得到LOB定位符,现在我们来看一下。

OCI在SQL语句INSERT,UPDATE,DELETE后面可以跟随一个RETURNING字句,相当于一个查询语句跟一个DML语句合并在一起执行,先执行完DML语句,然后执行一个查询语句,把查询的内容返回给程序。

这里仿照前面插入空LOB然后写入数据的例子,看看怎样使用这个字句。我们插入一条数据,SQL语句是INSERT INTO test_clob_tab (ID, MESSAGE)  VALUES (2, EMPTY_CLOB()),然后执行SELECT MESSAGE FROM test_clob_tab WHERE ID=2,定义一个LOB定位符的输出变量,得到LOB定位符。如果合并到一起SQL语句是这样的INSERT INTO test_clob_tab (ID, MESSAGE)  VALUES (2, EMPTY_CLOB()) RETURNING MESSAGE INTO :1。然后通过绑定函数绑定一个LOB定位符的输出变量,只要执行一次,就能插入空LOB数据然后得到一个LOB定位符。是不是简单多了?尤其在一次插入多个空LOB然后分别写入的情况,使用这种方法,更简单,代码更简洁。

下面我们还是通过一个例子来看看完整的代码怎样实现。

OCIEnv		*envhp = NULL;
OCIError	*errhp = NULL;
OCIServer	*svrhp = NULL;
OCISession	*usrhp = NULL;
OCISvcCtx	*svchp = NULL;
OCIStmt		*smthp = NULL;

​​
int insert_one_lob(void)
{
    int              i;
    sword	         rc;
    sb4		         ec;
    int		         slen;
    sb2              ind_msg;
    ub2              alen_msg;
    ub1              piece;
    oraub8           amt;
    OCIBind	         *bndp;
    OCILobLocator    *locp;
    char	         sqltxt[1024];
    text             errbuf[512];


    strcpy(sqltxt,
        "INSERT INTO test_clob_tab (ID, MESSAGE) values (2, EMPTY_CLOB()) RETURNING MESSAGE INTO :1");
    slen = strlen(sqltxt);

    rc = OCIStmtPrepare(smthp, errhp, (const OraText *)sqltxt, slen,
          OCI_NTV_SYNTAX, OCI_DEFAULT);

    if (rc != OCI_SUCCESS) {
        OCIErrorGet(errhp, 1, NULL, &ec, errbuf, 512, OCI_HTYPE_ERROR);
        fprintf(stderr, "OCIStmtPrepare() - [%d] %s\n", ec, errbuf);
        return (-1);
    }

    /* 分配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 = OCIBindByPos((OCIStmt *)smthp,
          (OCIBind **)&bndp,
          errhp,
          (ub4)1,
          (void *)&locp,
          (sb4)sizeof(OCILobLocator *),
          (ub2)SQLT_CLOB,
          (void *)&ind_msg,	    /* indp */
          (ub2 *)&alen_msg,	    /* alenp */
          (ub2 *)NULL,	        /* column return code pointer */
          (ub4)0,		        /* maxarr_len */
          (ub4 *)NULL,		    /* curelep */
          (ub4)OCI_DEFAULT);	/* mode */

    if (rc != OCI_SUCCESS) {
        OCIErrorGet(errhp, 1, NULL, &ec, errbuf, 512, OCI_HTYPE_ERROR);
        fprintf(stderr, "OCIBindByPos() - [%d] %s\n", ec, errbuf);
        return (-1);
    }

    ind_msg  = 0;
    alen_msg = sizeof(OCILobLocator *);

    /* 执行语句 */
    rc = OCIStmtExecute(svchp,
           smthp,		/* stmthp */
           errhp,		/* errhp */
           1,			/* iters */
           0,			/* rowoff */
           NULL,		/* snap_in */
           NULL,		/* snap_out */
           OCI_DEFAULT);	/* mode */

    if (rc != OCI_SUCCESS) {
        OCIErrorGet(errhp, 1, NULL, &ec, errbuf, 512, OCI_HTYPE_ERROR);
        fprintf(stderr, "OCIExecute() - [%d] %s\n", ec, errbuf);
        return (-1);
    }

    /* 打开LOB */
    rc = OCILobOpen(svchp, errhp, locp, OCI_LOB_READWRITE);
    if (rc != OCI_SUCCESS) {
        OCIErrorGet(errhp, 1, NULL, &ec, errbuf, 512, OCI_HTYPE_ERROR);
        fprintf(stderr, "OCILobOpen() - [%d] %s\n", ec, errbuf);
        return (-1);
    }

    for (i=0; i<20; i++) {
        if (i == 0)
            piece = OCI_FIRST_PIECE;
        else if (i == 19)
            piece = OCI_LAST_PIECE;
        else
            piece = OCI_NEXT_PIECE;

        sprintf(buf, "%02d", i);
        memset(&buf[2], 3998, 'B');

        amt = 4000;

        rc = OCILobWrite2(svchp, errhp, locp, NULL, &amt, 1,
            buf, 4000, piece, 0, SQLCS_IMPLICIT);
        if (rc != OCI_SUCCESS) {
            OCIErrorGet(errhp, 1, NULL, &ec, errbuf, 512, OCI_HTYPE_ERROR);
            fprintf(stderr, "OCILobWrite2() - [%d] %s\n", ec, errbuf);
            return (-1);
        }
    }

    /* 关闭LOB */
    rc = OCILobClose(svchp, errhp, locp);
    if (rc != OCI_SUCCESS) {
        OCIErrorGet(errhp, 1, NULL, &ec, errbuf, 512, OCI_HTYPE_ERROR);
        fprintf(stderr, "OCILobClose() - [%d] %s\n", ec, errbuf);
        return (-1);
    }

    /* 提交改变 */
    rc = OCITransCommit(svchp, errhp, OCI_DEFAULT);

    if (rc != OCI_SUCCESS) {
        OCIErrorGet(errhp, 1, NULL, &ec, errbuf, 512, OCI_HTYPE_ERROR);
        fprintf(stderr, "OCITransCommit() - [%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 SELECT操作得到LOB定位符才行。

ECN实战指南:如何用SAP系统搞定工程变更(附库存处理避坑技巧) 本文详细解析了如何在SAP系统中高效执行工程变更通知(ECN),特别聚焦PP模块的操作流程与库存处理技巧。通过实战案例和系统操作指南,帮助制造业企业避免库存混乱和生产中断,实现从创建到生效的全流程管理。 阅读详情

相关推荐

【信道编码/Channel Coding】线性分组码

这是本专栏信道编码/Channel Coding的第二站,想对信道编码有一个系统性的认识可以看本专栏的信道编码的整体框架一文。而在本篇文章中,将介绍线性分组码的基本原理。

Tomatomatodo的博客 9243

OCI编程高级篇(八) LOB写操作

介绍OCI写入LOB的步骤,从打开LOB到关闭LOB,中间的写操作可以是流模式,也可随机写入,一个完整的示例代码演示写入过程。

tomcoding的博客 834

rk3568 rockit编译测试

编译rockit不能使用SDK默认编译kernel的交叉编译,需要采用编译buildroot的,而编译buildroot的编译器SDK并没有存放,需要编译过buildroot之后才可以用。命令参数相关解析可查阅代码,这里提醒一下-l参数,这是程序运行计数,默认是100,时间很短,基本上显示画面一闪而过,一度以为是程序哪里出问题了,改用-l 1000,画面显示时间加长。此处跳过系统,单领出来编译。rockit组件包在4.10版本需要手动编译,奈何我的版本怎么都编译不了,后来改用5.10版本才编译通过。

zfenggo的博客 4195

OCI几个小问题

1、CLOG/BLOG的插入 找了很多OCI的例子以及一些PHP的例子,基本上都是同一种做法: a、OCIStmtPrepare预处理SQL语句:"insert into mytable (myimg) values (empty_blob()) returning myimg into :pImg" b、调用OCIDescriptorAlloc,用参数OCI_DTYPE_LOB,获得...

iihero@优快云 738

STRING数据库的蛋白质相互作用(PPI)网络分析

在转录调控相关的文献中,我们经常能够看到这样的蛋白质相互作用网络(protein protein interaction network,PPI network)。具体而言,这些相关的文献中首先通过RNA-seq、表达谱芯片或者蛋白质组分析等,找到了在不同分组样本间一系列的差异表达基因或蛋白。

weixin_43029125的博客 9450

实例讲解MOS管电源开关电路的软启动

1、控制电源开关的输入信号 Control 为低电平或高阻时,三极管Q2的基极被拉低到地,为低电平,Q2不导通,进而MOS管Q1的Vgs = 0,MOS管Q1不导通,+5V_OUT 无输出。此时将 Control 设为低电平,三极管Q2关闭,电容C1与G极相连端通过电阻R2放电,电压逐渐上升到5V,起到软关闭的效果。不过从作者的描述来看,只是电路参数有区别,能通过的电流、能承受的耐压等不一样,但是软启动的原理是一样的。从公式可以看出,当电容容量越大,电压越高,时间越短,电流就会越大,从而形成浪涌电流。

U_YAO的博客 2万+

Oracle8 的OCI常用函数及一部分参数说明

Oracle8的OCI常用函数 1. OCIHandleAlloc() Purpose: This call returns a pointer to anpointer to an allocated and initialized handle. 语法原型:5个参数          sword    OCIHandleAlloc(      CONST dvoid *

2491

扩展卡尔曼滤波 (EKF, Extended Kalman Filter) 算法详解及案例分析

扩展卡尔曼滤波是一种用于估计非线性动态系统状态的递归算法。其目标是通过结合非线性系统模型和观测数据,估计系统的最优状态。

闲人编程的博客 2383

OCI编程高级篇(七) LOB绑定和定义

介绍LOB定位符的绑定和定义操作,在表中插入一行空LOB数据,然后向LOB写入数据,这之间要经过复杂的操作。

tomcoding的博客 1206

在 ABAP 平台上搭建 OAuth 2.0 Server:架构、流程、权限与落地实战

摘要:本文为SAP ABAP开发人员提供将ABAP平台配置为OAuth 2.0授权服务器的实战指南。重点介绍两种授权流程(授权码和SAML Bearer)的实现方案,包括核心事务配置(SOAUTH2/SAML2)、授权对象(S_SCOPE)管理以及端点交互规范。通过具体配置清单和三类典型集成场景(第三方Web应用访问OData、企业集成平台调用、BTP应用对接)的落地示例,帮助读者快速构建安全的OAuth 2.0服务架构。文档强调SSL/TLS基础安全、scope最小授权原则以及授权与令牌端点的标准交互模式

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 307

seurat v5更新及样本整合方法

1 Seurat 对象和 Assay 类发生了变化:支持更多种类的检测和数据类型,包括磁盘上的矩阵。引入了分层结构来存储数据,例如原始计数、标准化数据和 z 得分/方差稳定数据。可以使用 $ 访问器或 LayerData 函数来访问数据。现有的 Seurat v4 函数和工作流程仍可在 v5 中使用。2 整合工作流程发生了变化:简化了整合流程,提高了速度和内存效率。整合结果与 v4 工作流程略有不同,但用户仍可在 v5 中运行 v4 整合工作流程。

hx2024的博客 2683

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

LOB操作是OCI中比较复杂的一部分,我们一步步看具体的操作,这一节先介绍LOB定位符的分配,空LOB定位符的创建。

tomcoding的博客 628

【异常】DeepSeek API HTTP 401 认证失败错误完整排查与解决方案

摘要:本文针对DeepSeek API开发中的HTTP 401认证失败错误进行深度解析,指出该错误属于不可重试的认证类问题。文章首先拆解错误日志关键字段,区分401与其他API错误的本质差异。随后提供优先级排序的全链路解决方案:1)检查API密钥有效性;2)规范请求头认证格式;3)排查账户权限状态;4)验证请求环境配置。最后建议通过新建测试密钥、使用官方示例代码或联系技术支持进行兜底处理。全文采用技术脱敏处理,为开发者提供系统性的401错误排查指南。(149字)

奶爸的编程之路,也就一周冷个三天 1521

OCI编程高级篇(九) LOB读操作

OCI对LOB的读操作介绍,通过代码演示了上一节中写入的LOB数据怎样读取出来。

tomcoding的博客 635

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

OCI编程高级篇(十一) 其他一些LOB操作函数

介绍了LOB操作的其他一些常用函数。

tomcoding的博客 562

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

IMP 导入数据报错 OCI-21500 OCI-22275

IMP导入数据报错如下: OCI-21500: internal error code, arguments: [kgepop: no error frame to pop to], [], [], [], [], [], [], [] OCI-22275: invalid LOB locator specified xExExE@@@@@@@@Errors in file

CR7 - Xyy -- For oracle 4017

用PHP操纵Oracle的LOB类型的数据

用过Oracle的人都知道,Oracle有一种数据类型叫VARCHAR2,用来表示不定长的字符串。VARCHAR2也是Oracle公司推荐使用的类型。但使用VARCHAR2有个问题:最大只能表示4000个字符,也就相当于2000个汉字。如果你的程序中某个字符的值要大于20002个汉字,用VARCHAR2就不能满足要求了。这时候,你有两个选择,一是用多个VARCHAR2来表示,二是用LOB字段。这里

phphot 1992

oracle OCI lob操作

可以有两种方式来bind lob字段 1)直接绑定lob 值 2)绑定lob locator指针 对于 直接绑定lob值的操作如下 char* sql = "insert into tab_lob(id,lob) values(:1,:2)"; OCIStmtPrepare(stmthp, errhp, sql, strlen(sql), OCI_NTY_SYNTAX, OCI_DE...

weixin_30527143的博客 949

OCI 批量入库Lob字段

最近由于项目需要开始使用OCI接口编写Lob 字段的删除 更新 插入包括批量插入! 批量插入有两种方法: 1.建立临时大对象,对每行每列的分配一个OCILobLocator,并建立相应的临时大对象,将数据通过lobWrite写入;最后邦定某一列,参数locator是数组元素;通过OCIStmtExecute执行n行. 该方法缺点 :速度慢,(释放资源和入库的时间差不多) 2.先批量入库lo

qdddyezi的专栏 763

OCI 做LOB数据读取

前段时间一直被一个问题所困扰,本来是在用OCIThread做多线程开发,老是在子线程中出错,一直找不到原因,害的我都怀疑我线程的问题,最后本着把复杂问题简单化的原则,一步一步的把在工程中的程序独立出来,从小到大的检查...

775

DBMS_LOB

1.LOB背景 在现在的系统开发中,需要存储的已不仅仅是简单的文字信息,也包括一些图片、音像资料或者超长的文本,这要求后台数据库具有存储这些数据的能力,Oracle通过提供LOB对象实现了该功能。 2.LOB 在ORACLE数据库中,LOB大对象类型是用来存储大量的二进制和文本数据的一种数据类型(一个LOB字段可存储达4GB的数据)。目前LOB分...

axing2408的博客 908

php获取oracle视图,PHP Oracle OCI8

OCI-Collection::append — Appends element to the collectionOCI-Collection::assign — Assigns a value to the collection from another existing collectionOCI-Collection::assignElem — Assigns a value to the...

weixin_39945679的博客 208

PL/SQL 查询select报错:A query with LOB‘s requires OCI8 mode, but OCI7 mode is used

使用pl/sql 利用select 查询时报错: A query with LOB's requires OCI8 mode ,but OCI7 mode is used

wanglepingwangleping的博客 2092

ocienvcreate php 失败_OCI 资料 (1)

句柄属性所有的OCI句柄都有属性,这些可以用来存放一些信息。有些OCI函数需要那些指定的句柄属性被设定以后才能被调用。例如,当OCISessionBegin()需要被调用的时候,用户名和密码需要在调用之前先设定。还有一些OCI的函数在执行完毕之后,将返回的信息直接返回给某个句柄。比如当OCIStmtExecute()执行一个sql查询后,查询的列表项信息将会返回到statement句柄。OCI描述...

weixin_39876856的博客 156

Oracle8 OCI获取多个字段值的编程步骤

Oracle8 OCI获取多个字段值的编程步骤          在使用Oracle8的OCI获取多个字段值时,编程的顺序是 1.       拼接生成SQL语句; 2.       分配语句句柄, 3.       准备SQL语句 4.       执行SQL语句 5.       分配OCIDefine句柄,根据所选字段的类型来定义输出变量,如果所选字段中有LOB字段,则需要另外分

824

oracle lob值是什么,oracle LOB介绍

发信人: oracle_mo(洗洗睡了... ..)整理人: zrsoft(2001-11-05 21:43:17), 站内信件0、LARGE OBJECTORACLE8中有4种LOB- BLOB:Binary Large Object- CLOB:Character Large Object- NCLOB:固定长度的多字节Character Large Object- BFILE:DB外部的二进...

weixin_34441120的博客 741
上一篇: OCI编程高级篇(九) LOB读操作
下一篇: OCI编程高级篇(十一) 其他一些LOB操作函数
tomcoding
博客等级 码龄9年 410粉丝 56原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值