Oracle 批量提交,批量绑定 OCIBindByName 和OCIBindObject 的使用

2023-11-02

穷遍所有OCI文档找不出一个能绑定多行数据的说明和示例,自己尝试快两周解决了Oracle Spatial 批量绑定将Oracle的写入效率提升到了5000行左右,以下是一点心得

Oracle OCI  基本操作 本文不多说,假设你会用基本的OCI操作数据,但是不知道怎么用OCIBindByName  一次可以绑定级别上千行数据, 本文将对你有点用

 从Statement 说起,分以下三步

1: 准备sql:  

 OCIStmtPrepare (m_h,   //OCIStmt 指针

                             m_ErrorHandle,   //OCIError指针

                            (text *)sql, //sql 语句
                            (ub4)strlen((const char *)sql),  //SQL语句长度

                         OCI_NTV_SYNTAX, 
                         OCI_DEFAULT))),

2: 绑定写入的数据,  可以是一行数据,也可以是多行数据

2.1非对象绑定:

一行数据:

OCIBindByName(stmt, &m_h, err, (const OraText*)name, strlen(name),
            BufferPtr(), BufferSize() , dty, indp, 0,0,0,0, (ub4)bindtyp))

单行数据BufferPtr 就是数据的指针,Oracle 可操作的就只有OCINumber,OCIDate,OCI*** 等oci自定义类型

BufferPtr的实际分配长度要比实际数据多1字节,

字符串的BufferSize() 需要比strlen求出来的长度大一,并且最后一位的值为'\0'

一个示意图: 

多行数据:

   OCIBindByName(stmt, &m_h, err, (const OraText*)name, strlen(name),
            (void*)Ptr(), maxLength, dty, (void*)(&m_indicator[0]), 0, 0, 0, 0, (ub4)bindtyp)))

  OCIBindArrayOfStruct(m_h, err, (ub4)maxLength,  sizeof(sb2),0, 0);    //  PS (这里要感谢大神https://blog.csdn.net/sl8023dxf 的研究  不仅要设置元素大小 maxLength还要设置 m_indicator ,不然默认值的写入存在覆盖或者无效问题)

Ptr() 指向的内存结构:

如果是字符串;内存结构如下, 当然这里是一元数组, 图中只是为了对于关系:

上图是将原始数据映射为可给OCIBindbyName输入的数据,

如果是绑定数值,OCIDate,OCINumber , 则这个Ptr数据内存就是OCIDate,OCINumber对象数组, maxlength 用sizeof(OCIDate)sizeof(OCINumber)表示. 不用特别处理.

maxLength 代码每行元素中一个元素的最大长度, 不是Ptr() 这个指针内存的所有长度

m_indicator 是一个数组,代表Ptr()这个指针内存中每个对象的实际长度,  如果设置为-1,  Oracle 将绑定NULL

设置其他>=0的值为有效,(PS:这里有个大坑误区, 这里没有指明 这个实际数组的长度, Oracle如何知道我们数组的长度,我们一般API都要指明, 而OCI的数组长度都由 OCIStmtExecute的第四个参数指定)

        

2.2 对象绑定

先调用OCIBindByName  获得OCIBInd 对象,再调用OCIBindObject  绑定一个对象或者多个对象

OCIBindByName 初始化的时候, dty参数为SQLT_NTY,其他参数全为0都可以, 因为oci会忽略其他参数, 不管单个绑定还是多个,

单个Object 绑定        

简单介绍下SDOGeometry这个对象是Oracle 自定义对象, 表示几何对象, 里面两个数组存不固定的坐标,以及固定长度的数据头描述, 这种网上很多不过多介绍了.

OCIBindObject(bind->m_h, stmt->ErrorHandle(),
        m_pMetaTable->SDO_GEOMETRY_TYPE()->Type(), 
       (void**)sdogeometry.SDOGeometryPtrAdd(), 0,
         (void**)sdogeometry.SDOGeometryIndPtrAdd(), 0);

没有任何可说明的, 传对象和类型可搞定.

多个Object绑定

先包装数组指针,   并且m_indszp参数必须是ub4数组(PS:OCI官网说是sb2, 我看Oracle写文档的真是sb, ),这个数组直接存每个对象的描述长度,这里描述长度是倒数第二个参数里面元素的sizeof长度, 我这是写入Oracle Spatial 空间数据,所以每个m_indszp元素其实就是一个固定描述长度18.

 for (int i = 0; i < nCount; i++)
    {
        m_pGeomCache.push_back(sdoBuilder[i]->SDOGeometryPtr());
        m_pGeom_inCache.push_back(*sdoBuilder[i]->SDOGeometryIndPtrAdd());
        m_indszp.push_back(sizeof(sdo_geometry_ind));
    }

OCIBindObject(bind->m_h, stmt->ErrorHandle(),
        m_pMetaTable->SDO_GEOMETRY_TYPE()->Type(), 
        (void**)(&(m_pGeomCache[0])), 0,
        (void**)&m_pGeom_inCache[0], &m_indszp[0]);

这里没有研究blob 绑定, 这里没尝试,简单猜想跟普通blob 绑定应该类似

普通blob 绑定是在OCIStmtExecute后执行OCILobWrite完成的, 

OCILobWrite(pConn->m_h, err, 
        m_LobDesc.m_h, &len, 1, 
        PtrT<dvoid*>(), len, 
        OCI_ONE_PIECE, NULL, 0, 0, 0 )

这里很可能是多次调用这个函数, 因为OCI_ONE_PIECE 这个就是跟游标类似的写法.

 

3: 执行绑定

这里只有一个参数需要注意, nArrayCount 这就是我们每个OCIBindByName绑定的数据条数了.

OCIStmtExecute(*pConn,
            m_h,
            m_ErrorHandle,
            (ub4)nArrayCount,
            (ub4)0,
            (CONST OCISnapshot *) 0,
            (OCISnapshot *)0,
            (ub4)OCI_BATCH_ERRORS)

 

另外想获得那条出错, 可以使用以下代码:

        ub4   num_errs; 
    
        COCIErrorHandle  errhp2(m_EnvHandle);
        OCIAttrGet(m_h, OCI_HTYPE_STMT, &num_errs, 0, OCI_ATTR_NUM_DML_ERRORS, errhp2);
        if (num_errs) {
            GsString str;
            for (int i = 0; i < num_errs; i++)
            {
                OCIError* errortmp;
                sword h = OCIHandleAlloc((void *)m_EnvHandle, (void **)&errortmp,
                    (ub4)OCI_HTYPE_ERROR, 0, (void **)0);
            
                OCIParamGet(m_ErrorHandle.ErrorHandle(), OCI_HTYPE_ERROR, errhp2.ErrorHandle(), (void**)(&errortmp), i);
                sword errorcode = 0;
                int rowoffset = 0;
                OCIAttrGet(errortmp, OCI_HTYPE_ERROR, &rowoffset, 0, OCI_ATTR_DML_ROW_OFFSET, errhp2.ErrorHandle());
                text errbuf[512];
                (void)OCIErrorGet((dvoid *)errortmp, (ub4)1, (text *)NULL, &errorcode,
                    errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR);
                 str = GsEncoding::ToLocal((const char*)errbuf);
                 OCIHandleFree((dvoid *)errortmp, (ub4)OCI_HTYPE_ERROR);
            }
        }

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Oracle 批量提交,批量绑定 OCIBindByName 和OCIBindObject 的使用 的相关文章

  • 如何找到与日期范围最重叠的时间段

    假设您有一个包含标识符 开始时间和结束时间的表 这些开始和结束时间可以是任意时间长度 开始时间始终早于结束时间 假设没有空值 什么样的查询会告诉我最 流行 的时间 即每行中的两个范围与大多数其他行重叠的位置 它的实际应用是它是一个记录用户登
  • ora-00972 标识符太长 oracle 10g

    我收到标题中提到的错误 我使用的是 36 个字符的 ID 此错误仅在我的 asp net web 表单中的 sqldatasource 中抛出 当我执行更新时这不是问题Oracle sql developer 我怎样才能解决这个问题 Ora
  • 处理ORACLE异常

    我需要处理ORA 01400 错误 http www techonthenet com oracle errors ora01400 php 无法使用异常句柄将 NULL 插入 SCHEMA TABLE NAME COLUMN NAME O
  • Java - oracle.jdbc.dcn.DatabaseChangeEvent - 获取更改的行

    我正在使用 oracle jdbc dcn DatabaseChangeEvent 来从 Oracle DB 获取事件通知 public class TListener implements DatabaseChangeListener p
  • PL/SQL 中是否有方法将文本转换/编码为 XML 兼容文本?

    我的一位同事需要将 PL SQL 方法中的文本转换为符合 XML 的文本 因为他正在通过更新文本模板来构建 Excel 电子表格 PL SQL 中是否有方法将文本转换 编码为 XML 兼容文本 好吧 如果您只想转换 XML 字符 您需要执行
  • BI Publisher 和 Excel 模板预览错误

    我正在使用 Excel 2013 并添加了 BI 发布器 我加载示例数据 并进行预览 我得到以下内容 请指教 谢谢詹姆斯 启动 Excel 预览 仅开放 false mTemplate C Users AJCENTROID AppData
  • Oracle:在更新具有多列的表的一个字段时复制行

    有没有一种方法可以一般复制一行 特别是在不指定所有列的情况下 在我的情况下 我有一个大表 我想在其中复制除 ID 和另一列之外的所有列 事实上 数据是在年初复制的 该表有 50 多列 因此如果我不必指定所有列 则更改架构会更加灵活和稳健 这
  • 超时后如何重新建立 JDBC 连接?

    我有一个长时间运行的方法 它通过 EntityManager TopLink Essentials 执行大量本机 SQL 查询 每个查询只需要几毫秒即可运行 但查询数量却有数千个 这发生在单个 EJB 事务内 15 分钟后 数据库关闭连接
  • 如何使用过程填充数据库

    我有大约 15 个不同的表 其中填充了不同的数据和不同的实体关系 我需要创建一个脚本 用这些表的内容填充我的数据库 脚本完成后 我使用 sqlplus 在 cmd 中运行它 然后使用 START文件路径 我有两个不同的 sql 文件 一个名
  • 从 Oracle Forms 调用 Microsoft Word 拼写检查时出现 Vista 焦点问题

    朋友们 在 Vista 上测试我们的 Oracle Forms 应用程序时 我发现了一个有趣的 挑战 应用程序可以调用 Microsoft Word 拼写检查器对字段执行拼写检查 调用时 用户将看到标准的 Microsoft Word 拼写
  • 无法在 JDBCPreparedStatement 中使用 LIKE 查询吗?

    查询代码及查询方式 ps conn prepareStatement select instance id from eam measurement where resource id in select RESOURCE ID from
  • oracle 计算两个字符串中连续匹配的单词

    我想要一个返回两个字符串中单词的顺序匹配数的查询 例子 Table Id column1 column2 result 1 foo bar live foo bar 2 2 foo live tele foo tele 1 3 bar fo
  • Oracle ODP.Net 与实体框架 6 - 从表视图中选择时出现 ORA-00955

    我创建了两个应用程序 第一个使用 ODP Net 另一个没有实体 效果很好 static void Main string args OracleConnection con new OracleConnection using conne
  • PL/SQL:如何声明会话变量?

    如何在 PL SQL 中声明一个会话变量 该变量仅在会话期间持续存在 而无需将其存储在数据库本身中 您可以使用 用户创建的上下文 来存储会话中多个单元共享的数据 首先 创建一个上下文 CREATE CONTEXT SYS CONTEXT u
  • 获取 Oracle JDBC 连接上的 MySQL 错误堆栈跟踪

    我在使用连接字符串进行 Oracle JDBC 连接时遇到非常奇怪的错误 我将用户名指定为 sys 应该是 sys as sysdba 理想情况下 它应该来自 ojdbc6 jar 但就我而言 它来自 mysql connector jav
  • 为什么我的层次结构查询显示重复记录?

    我的要求是找到一个月中所有过去的天数 以下是我的示例查询 CREATE TABLE custom date full sno NUMBER curr date DATE INSERT INTO custom date full VALUES
  • java.library.path 中没有 ocijdbc12

    我正在尝试使用 OCI 驱动程序通过 java 程序连接到 oracle 以下是配置 Windows 7 32 位 JDK 1 7 Oracle 客户端 11g R2 ojdbc7 jar在我的独立应用程序的类路径中 但我收到以下异常 Ex
  • 具有多个数据源的 Tomcat 6/7 JNDI

    当有多个时
  • oracle 数据透视表中的列

    示例选择 select from select 1 cnt 2 sm 55 name 12 month 2011 year 12 2011 mnth txt from dual union all select 1 cnt 2 sm 54
  • 从 oracle 中为每个组选择最新行

    我在留言簿中有一张包含用户评论的表格 列有 id user id 标题 评论 时间戳 我需要为每个用户选择最新行 我尝试使用 group by 执行此操作 但没有管理它 因为我无法在按 user id 分组的同一查询中选择任何其他内容 SE

随机推荐

  • 使用scrapy框架进行爬虫时,报出异常:NotImplementedError: Test1Spider.parse callback is not defined

    这种错误类型今天第一次使用Scrapy框架 就出现了 找了很多博客中的解决方法 还是不能访问 改了一下execute py文件的位置就ok了 如图 书上说这三个位置放置execute py文件都可以 我把文件放在第二个目录下 就不会抛出异常
  • 从辩证的角度看待chatGPT,我们该如何对待?

    从辩证的角度 看待chatGPT 0 什么是ChatGPT 客观阐述 1 通过唯物辩证法的五对基本范畴进行分析 1 0 内容与形式 1 1 现象和本质 1 2 原因与结果 1 3 必然与偶然 1 4 现实与可能 2 使用ChatGPT会给我
  • SPADE(GauGAN)代码运行方法

    SPADE运行方法 写在前面 为什么Pix2PixHD和SPADE都不用RGB作为输入 如何运行SPADE 可能遇到的问题 2022 04 28更 如何控制合成风格 2022 07 30更 contain dontcare label参数
  • 暗影精灵5怎么调风扇转速_遗憾与真香并存的性价比产品——暗影精灵6 AMD

    惠普暗影精灵6 AMD作为一台正面与联想拯救者R7000P对线的游戏本 自有消息以来就被玩家们寄托了很高的希望 纵然随着暗影精灵6 AMD的发布 大家对其期待值有所降低 但在如今游戏本集体无货的情况下它也是一个不错的选择 本文基于目前拿到的
  • 数据结构 算法大全 入门篇

    说到数据结构是什么 我们得先来谈谈什么叫数据 正所谓 巧妇难为无米之炊 再强大的计算机 也是要有 米 下锅才可以干活的 否则就是一堆破铜烂铁 这个 米 就是数据 数据 是描述客观事物的符号 是计算机中可以操作的对象 是能被计算机识别 并输入
  • vscode配置remote ssh

    1 安装插件 vscode配置remote ssh Hello wshuo的博客 CSDN博客 remote ssh vscode 设置界面 右键最左边tab栏 主体 vscode 插件 Remote SSH Linux主体 vscode
  • 【Complex-YOLO: 点云实时目标检测】

    Complex YOLO 点云实时目标检测 前言 要点分析 具体算法分析 点云转化鸟瞰图 提取特征 B Box损失回归 前言 Complex YOLO 论文中介绍是一种仅在点云上进行的最先进的实时3D目标检测网络 借鉴了yolo v2的主干
  • Java语言实现word转PDF(10分钟解决)

    前言 经常做OA办公项目的同学一定和我一样被各种线上的office操作整疯了 基本上涉及到Java操作office的时候就会想到POI和openoffice 这两种方案都是需要找各种jar包 然后用里面繁杂的api 关键是做出来的文件格式有
  • ORA-28002 & PASSWORD_LIFE_TIME & PASSWORD_GRACE_TIME

    Normal 0 7 8 磅 0 2 false false false EN US ZH CN X NONE PASSWORD LIFE TIME 设置的是数据库开始报告ORA 28002密码要过期的时间 PASSWORD GRACE T
  • 【华为OD统一考试A卷

    华为OD统一考试A卷 B卷 新题库说明 2023年5月份 华为官方已经将的 2022 0223Q 1 2 3 4 统一修改为OD统一考试 A卷 和OD统一考试 B卷 你收到的链接上面会标注A卷还是B卷 请注意 根据反馈 目前大部分收到的都是
  • 【转载】odoo技术开发白皮书 第一部分 第九章 权限

    转载 http book odoomommy com chapter1 README8 html 第九章 权限 Odoo的权限管理 从粗到细可以大概分为四个等级 对象级 视图级 字段级 记录级 什么意思呢 总结起来大概如下面的描述 对象级
  • 大家的毕业设计怎么做的?跟我一样吗?无极低码说你:只管建库建表,剩下的交给我

    首先呢 介绍一下无敌低代码平台 无极低代码平台是作者自己搭建的一个框架 刚开始由3行代码写服务升级而来 3行代码写服务当然也是作者自己写的 目的就是为了减少基础的开发工作 让不会后端开发的人员能够通过简单的步骤实现服务接口的编写 后面觉得3
  • 对比 Exception 和 Error,运行时异常与一般异常有什么区别?

    相同点 Exception 和 Error 都是继承了 Throwable 类 在 Java 中只有 Throwable 类型的实例才可以被抛出 throw 或者捕获 catch 它是异常处理机制的基本组成类型 Exception 和 Er
  • vue5种方式实现页面“刷新“

    vue中五种方式实现页面 刷新 1 使用window location reload 强制刷新 都会使页面有短暂的空白 体验效果不是特别好 home vue
  • 提高生活、学习、工作效率的方法——时间管理Vs个人管理

    首先 我想对于大家来说 时间管理这个词应该并不陌生 不过 在开会之前 又有几个知道呢 反正我当时并不知道 这就需要反思了 不过这里 先不做反思 先说说时间管理 初次接触到这个词 我想的是 为什么要管理 怎样进行时间管理 该怎么管理 随后 米
  • 12. 集群调度

    文章目录 简介 调度过程 自定义调度器 调度亲和性 Node亲和性 preferredDuringSchedulingIgnoredDuringExecution requiredDuringSchedulingIgnoredDuringE
  • 针对于MLE和MLP的代码例子实现

    背景 首先该例子来源于CSDN 详解最大似然估计 MLE 最大后验概率估计 MAP 以及贝叶斯公式的理解 nebulaf91的博客 这里的代码作为对上述内容的补充和实现 代码 import numpy as np import matplo
  • SSD接口种类

    转自微信公众号 存储随笔 随着SSD价格的不断下降以及SSD性能的不断提升 越来越多的朋友开始考虑给自己的电脑升级SSD固态硬盘 但是市面上现在SSD的根据不同的大小与尺寸 有多种多样的接口的SSD 本篇文章就当下主流的一些SSD接口进行简
  • OpenStack核心组件-horizon web 界面管理

    1 horizon 介绍 Horizon Horizon 为 Openstack 提供一个 WEB 前端的管理界面 UI 服务 通过 Horizone 所提供的 DashBoard 服务 管理员可以使用通过 WEB UI 对 Opensta
  • Oracle 批量提交,批量绑定 OCIBindByName 和OCIBindObject 的使用

    穷遍所有OCI文档找不出一个能绑定多行数据的说明和示例 自己尝试快两周解决了Oracle Spatial 批量绑定将Oracle的写入效率提升到了5000行左右 以下是一点心得 Oracle OCI 基本操作 本文不多说 假设你会用基本的O