当前位置: 首页 > news >正文

OTL调用存储过程/函数及注意事项

OTL 是 Oracle, Odbc and DB2-CLI Template Library 的缩写,是一个 C++ 编译中操控关系数据库的模板库,它目前几乎支持所有的当前各种主流数据库。 OTL 使用起来比较方便,其官方网站也提供了详细的文档和例子( http://otl.sourceforge.net/otl3.htmhttp://otl.sourceforge.net/otl3_examples.htm )。

最近在项目中需要使用 OTL 调用 Oracle 存储过程,并且需要返回游标,在网上查了一下,相关的中文资料比较少,经过一番辛苦的查找和摸索,最后终于如愿达到目的。在这里把相关的经验分享给大家,如有不对的地方,欢迎拍砖。

OTL 调用 Oracle 存储过程,其官方文档中给出了相应的例子,地址是 http://otl.sourceforge.net/otl4_ex149.htm 。现节选关键部分如下:

otl_stream i(1,

              "begin "

              " my_pkg.my_proc(:f1<int,in>,:f2<int,in>, "

              "         :str1<char[100],out>, "

              "         :cur1<refcur,out[50]>, "

              "         :cur2<refcur,out[50]>); "

              "end;",

              db // connect object

             );

 

  i.set_commit(0); // set stream "auto-commit" to OFF.

 

  char str1[101];

  float f1;

  char f2[31];

  otl_refcur_stream s1, s2; // reference cursor streams for reading rows.

 

  i<<8<<4;

  i>>str1;

  i>>s1;

  i>>s2;

 

  cout<<"STR1="<<str1<<endl;

  cout<<"=====> Reading :cur1..."<<endl;

  while(!s1.eof()){ // while not end-of-data

  s1>>f1>>f2;

  cout<<"f1="<<f1<<", f2="<<f2<<endl;

  }

 

  cout<<"=====> Reading :cur2..."<<endl;

  while(!s2.eof()){ // while not end-of-data

  s2>>f1>>f2;

  cout<<"f1="<<f1<<", f2="<<f2<<endl;

  }

 

  s1.close(); // closing the reference cursor

  s2.close(); // closing the reference cursor

可以看出,调用存储过程和执行普通的 sql 大同小异,也是通过 otl_stream 对象绑定相关参数,不同之处有以下几点:

1 .调用存储过程 / 函数时,缓冲大小必须设置为 1 。

2 . Sql 声明时语句必须采用 ”begin …… end;” 的形式。存储过程如果位于包内,还必须带上包名。绑定参数除了声明类型、大小以外,还必须指明参数的输入输出标志。返回游标的大小代表了游标内的记录数。

3 .返回游标绑定的数据类型是 otl_refcur_stream ,就像普通的 otl_stream 一样,可以使用 while 循环读取其中的数据。游标对象使用完毕后,别忘了使用 close 方法将其关闭。

在这个过程中,有两个需要注意的地方:

1 . OTL 在输入输出参数的方向标志方面稍微有点不人性化,即要求所有的 in 、 out 与前面的逗号“ , ”之间不允许有空格、制表符等空白字符,否则就会无法识别方向标志而发生 ORA-01008 错误,并提示“并非所有变量都已绑定”。

       2 .如果存储过程内存在多条执行路径,并且某些执行路径并不返回游标的情况下,就需要程序员自己判断在当前情况下是否需要接收游标。如果当前存储过程并未返回游标,而在 c++ 程序中执行了提取( >> )操作,就会发生 ORA-24338 错误 ,并提示“未执行语句句柄”。此时,如果允许的话可以通过存储过程返回的其他变量判断是否需要进行接收操作,如:

if(“00” == ret_code)      // 其中 ret_code 是存接收了储过程执行状态的变量

{

    o >> first_cur;

    o >> detail_cur;

}

OTL 调用存储函数和存储过程基本相似,只不过是多了一个返回值而以。格式大致如下:

otl_stream i(1,

"begin "

"   :rc<int,out> :=my_pkg. my_func(:f1<int,in>,:f2<int,in>, "

             "         :str1<char[100],out>, "

            "         :cur1<refcur,out[50]>, "

"         :cur2<refcur,out[50]> "

"                          );  "

" end; ",

db // connect object

);

int res = 0;

char str1[101];

float f1;

char f2[31];

otl_refcur_stream s1, s2; // reference cursor streams for reading rows.

 

  i<<8<<4;

i >> res;

  i>>str1;

  i>>s1;

  i>>s2;

这里也有两个需要注意的地方,一是 sql 声明时存储函数名前面的等号要用“ := ”;再就是接收输出时,首先接收函数返回值,再依次接收其他输出。其他操作同存储过程一致。关于调用存储过程 / 函数时, sql 声明的具体格式, OTL 提供了一个专门的函数create_stored_proc_call ,可以生成相应的绑定 sql 。其具体使用方法参见 http://otl.sourceforge.net/otl4_ex153.htm 。

补充一下:笔者的环境是 otl v4.0.218 OraClient11g vs2008sp1 winxp sp3 。

相关文章:

  • Yahoo的流计算引擎基准测试
  • Js基本方法
  • 【Java集合源代码剖析】TreeMap源代码剖析
  • Transient修饰符的使用
  • 【算法】 算法和数据结构绪论
  • 【转】Servlet 生命周期、工作原理
  • Openssl源代码整理学习---含P7/P10/P12说明
  • LeetCode OJ 之 Ugly Number II (丑数-二)
  • [计算机术语]缺省
  • (一)Thymeleaf用法——Thymeleaf简介
  • 【Python】 命名空间与LEGB规则
  • 通用的进程监控脚本process_monitor.sh使用方法
  • Spark on Yarn集群搭建详细过程
  • MySQL学习笔记-数据类型与操作数据表
  • sklearn包学习
  • 【跃迁之路】【699天】程序员高效学习方法论探索系列(实验阶段456-2019.1.19)...
  • ABAP的include关键字,Java的import, C的include和C4C ABSL 的import比较
  • JS 面试题总结
  • leetcode386. Lexicographical Numbers
  • Material Design
  • oldjun 检测网站的经验
  • vue从入门到进阶:计算属性computed与侦听器watch(三)
  • vue数据传递--我有特殊的实现技巧
  • vue--为什么data属性必须是一个函数
  • 解析带emoji和链接的聊天系统消息
  • 前端设计模式
  • 前端性能优化——回流与重绘
  • 我的面试准备过程--容器(更新中)
  • Java总结 - String - 这篇请使劲喷我
  • 带你开发类似Pokemon Go的AR游戏
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • ### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException
  • #ubuntu# #git# repository git config --global --add safe.directory
  • (0)Nginx 功能特性
  • (附源码)springboot金融新闻信息服务系统 毕业设计651450
  • (附源码)springboot太原学院贫困生申请管理系统 毕业设计 101517
  • (附源码)ssm高校升本考试管理系统 毕业设计 201631
  • (亲测有效)解决windows11无法使用1500000波特率的问题
  • (十)T检验-第一部分
  • (转载)从 Java 代码到 Java 堆
  • .bat批处理(九):替换带有等号=的字符串的子串
  • .form文件_SSM框架文件上传篇
  • .NET Core Web APi类库如何内嵌运行?
  • /etc/sudoer文件配置简析
  • @font-face 用字体画图标
  • @JSONField或@JsonProperty注解使用
  • [ JavaScript ] JSON方法
  • [ 隧道技术 ] 反弹shell的集中常见方式(四)python反弹shell
  • [] 与 [[]], -gt 与 > 的比较
  • [2009][note]构成理想导体超材料的有源THz欺骗表面等离子激元开关——
  • [AutoSar]BSW_OS 01 priority ceiling protocol(PCP)
  • [Avalon] Avalon中的Conditional Formatting.
  • [Bugku]密码???[writeup]
  • [BZOJ1053][HAOI2007]反素数ant
  • [datastore@cyberfear.com].Elbie、[thekeyishere@cock.li].Elbie勒索病毒数据怎么处理|数据解密恢复