LightDB pro*c迁移指南(游标模块)

文章目录

  • 一、不使用SQLDA描述符范围的游标操作
    • 1.1 oracle 案例
      • 1.1.1 使用游标获取数据
      • 1.1.2 对于fetch结果集怎么去利用
    • 1.2 LightDB 案例
      • 1.2.1 使用游标获取数据
      • 1.2.2 对于fetch结果集怎么去利用
    • 3 总结:不同项
  • 二、使用SQLDA描述符范围的游标操作
    • 2.1 Oracle样例
      • 2.1.1 使用SQLDA描述符范围的游标获取数据
    • 2.2 LightDB样例
      • 2.2.1 使用SQLDA描述符范围的游标获取数据
    • 3 总结:不同项
  • 三、总结

今天我们讲解的是关于pro*c迁移指南中的游标模块;这个模块我们分为两部分来讲:
(一)、不使用SQLDA描述符范围的游标操作
(二)、使用SQLDA描述符范围的游标操作
讲解方法主要为:oracle案例分析和LightDB案例分析,对比,列出不同点

一、不使用SQLDA描述符范围的游标操作

1.1 oracle 案例

1.1.1 使用游标获取数据

#include <stdio.h>
#include <stdlib.h>
#include <string.h>typedef struct fetch_results
{
int a;
char b[10];
int c;
}fr;int main() {EXEC SQL BEGIN DECLARE SECTION;char *uid ; //连接串信息自己补充int tmp;static fr arr[6];EXEC SQL END DECLARE SECTION;EXEC SQL CONNECT :uid;//连接是否成功if (sqlca.sqlcode == 0)printf("是否成功连接:%d\n",sqlca.sqlcode);else{printf("是否成功连接:%d\n",sqlca.sqlcode);return -1;}//声明游标exec sql declare cur cursor for select * from test;fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc);//打开游标exec sql open cur;fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc);//获取数据exec sql fetch cur into :arr;fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc);printf("获取行数:%d\n", sqlca.sqlerrd[2]);//关闭游标exec sql fetch cur into :arr;fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc);//断开连接EXEC SQL COMMIT WORK RELEASEexit(0);
}

上面给出的列子中,fetch获取结果集的行数,我们可以通过sqlca.sqlerrd[2]来确定,oracle中sqlca.sqlerrd[2]被用来记录获取的结果集的行数
我们发现sqlca.sqlerrd[2]的值刚好与arr数组的大小是相等,随着arr数组的大小的变动sqlca.sqlerrd[2]也会变动。

1.1.2 对于fetch结果集怎么去利用

这里我们用打印的方式进行显示

    while (1){exec sql fetch cur into :arr;  Rows = sqlca.sqlerrd[2] - DealRows;for (i=0;i<Rows;i++)  { printf("a:%d,b:%s,c:%d", arr[i].a,arr[i].b,arr[i].c);}	     	    DealRows = sqlca.sqlerrd[2];  if (sqlca.sqlcode==1403){iFetchCount=sqlca.sqlerrd[2];break;}}

上述程序需要稍加解析:我们添加了三个变量去完成这个算法;分别为Rows、DealRows、iFetchCount。它们代表的意思如下:
Rows:这次fetch获取的行数;
DealRows:已经获取的行数
iFetchCount:获取总行数;
为什么我们会多此一举在这里使用三个变量进行运算哪?
这是有使用场景决定的,当我们查询的结果集的长度超出了我们目标的数组大小(获取的实际长度为目标数组的大小),就需要用到上面这段代码了。还需要再强调一次,oracle中sqlca.sqlerrd[2]被用来记录获取的结果集的行数。
好的,知道了这些我们再来看代码
Rows = sqlca.sqlerrd[2] - DealRows; Rows等于总行数 - 已经获取过的结果集行数;
DealRows = sqlca.sqlerrd[2]; 已经获取过的结果集行数;
**iFetchCount=sqlca.sqlerrd[2];**最后判断no_data_found,获得fetch总行数。

1.2 LightDB 案例

1.2.1 使用游标获取数据

#include <stdio.h>
#include <stdlib.h>
#include <string.h>typedef struct fetch_results
{
int a;
char b[10];
int c;
}fr;int main() {Test_cf cf ;EXEC SQL BEGIN DECLARE SECTION;char *uid ; //连接串信息自己补充int tmp;static aa1_a arr[6];EXEC SQL END DECLARE SECTION;EXEC SQL CONNECT :uid;//连接是否成功if (sqlca.sqlcode == 0)printf("是否成功连接:%d\n",sqlca.sqlcode);else{printf("是否成功连接:%d\n",sqlca.sqlcode);return -1;}//声明游标exec sql declare cur cursor for select * from test;fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc);//打开游标exec sql open cur;fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc);//获取数据exec sql fetch cur into :arr;fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc);printf("获取行数:%d\n", sqlca.sqlerrd[2]);//关闭游标exec sql fetch cur into :arr;fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc);//断开连接EXEC SQLdisconnect;exit(0);
}

对比发现,与oracle存在两个不同点:
(1)断开连接不同;
(2)LightDB fetch into 语法只能获取一行,不是由目标数组的大小决定的
因此我们在对于fetch结果集怎么去利用的方法肯定不一致

1.2.2 对于fetch结果集怎么去利用

这里我们用打印的方式进行显示

  while (1){exec sql fetch 6 cur into :arr;  iFetchCount += sqlca.sqlerrd[2];Rows = sqlca.sqlerrd[2];for (i=0;i<Rows;i++){printf("a:%d,b:%s,c:%d", arr[i].a,arr[i].b,arr[i].c);}DealRows =  iFetchCount;if ( sqlca.sqlcode==ECPG_NOT_FOUND){break;}}

我们发现虽然代码看起来差不多,但是却存在3个细节上的差异:
(1)fetch into变成了fetch count into,为了兼容oracle其长度设置成oraclearr数组的长度,即可;
(2)添加的变量一样,但是算法发生了变化:
Rows = sqlca.sqlerrd[2]; 当前获取的行数;
DealRows = iFetchCount; 已经获取的行数;
iFetchCount += sqlca.sqlerrd[2]; 获取的总行数;
(3)no_data_found的错误码不一致了,LightDB返回的错误码为100,oracle返回的错误码为1403

3 总结:不同项

(1)fetch into获取的长度不一样;导致获取字段结果的算法不一致;
(2)错误码不一样
(3)断开连接的方式不一样(关于连接有空再单独介绍)

二、使用SQLDA描述符范围的游标操作

这一章我们会在不使用SQLDA描述符范围的游标操作的基础上进行讲解。
我们需要对于使用SQLDA描述符范围的游标操作,给一个总体的介绍
test
在使用SQLDA描述符范围游标的过主要分为两部分。查询的目标列表和绑定两部分。

2.1 Oracle样例

2.1.1 使用SQLDA描述符范围的游标获取数据

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlca.h>
#include <sqlda.h>int main() {
{ char sqlstr[1000] = "select * from test";EXEC SQL PREPARE DYSQLSA FROM :sqlstr;EXEC SQL DECLARE Cursorbase CURSOR FOR DYSQLSA;EXEC SQL DESCRIBE BIND VARIABLES for DYSQLSA INTO BindUnit;for (i = 0 ; i < BindUnit->N; i++){ //这里设置L、V、I、T等类型}EXEC SQL OPEN Cursorbase USING DESCRIPTOR BindUnit;EXEC SQL DESCRIBE SELECT LIST for DYSQLSA INTO SelectUnit;for (i=0; i < SelectUnit->F; i++){//这里设置L、V、I、T等switch (type){ //类型处理}      }for(;;){ EXEC SQL FOR :array_size FETCH Cursorbase USING DESCRIPTOR SelectUnit;for (j = 0 ;j < sqlca.sqlerrd[2] - iRowCount; j ++){for (i=0; i < SelectUnit->F; i++){ //对每个字段进行处理}  }iRowCount = sqlca.sqlerrd[2];if (sqlca.sqlcode == 1403) break;   } EXEC SQL commit;EXEC SQL CLOSE cur; 
}

我们需要说明一下几点:
(1)EXEC SQL DESCRIBE BIND VARIABLES for DYSQLSA INTO BindUnit; DESCRIBE 已将 F 设置为已处理 SQL 语句中找到的占位符的实际数量。
这个BindUnit主要针对需要绑定的变量:
举个例:
select * from test;这个查询语句就不存在需要绑定的变量,因此不需要对BindUnit进行设置;
select * from test where a := :var;这就涉及到对描述符进行赋值部分oracle 官方sqlda
(2)相较于不使用SQLDA描述符范围的游标操作,在打开游标时我们会使用到SQLDA描述符范围:
EXEC SQL OPEN Cursorbase USING DESCRIPTOR BindUnit;
(3) EXEC SQL DESCRIBE SELECT LIST for DYSQLSA INTO SelectUnit; DESCRIBE 已将 F 设置为查询选择列表中的实际项数。如果 SQL 语句不是查询,则 F 设置为零。
(4) EXEC SQL FOR :array_size FETCH Cursorbase USING DESCRIPTOR SelectUnit; for :arrary_size指定获取的行数;
(5)释放游标的过程为:

    EXEC SQL commit;EXEC SQL CLOSE cur; (commit提交之后并不影响close游标)。

2.2 LightDB样例

2.2.1 使用SQLDA描述符范围的游标获取数据

针对上面的程序,LightDB目前采用的方案主要是改写。
改写的主要内容分为:
(1) SQLDA类型不支持,需要替换成sqlda_t

sqlda_t *SelectUnit ; 
sqlda_t *BindUnit; 

(2)EXEC SQL OPEN Cursorbase USING DESCRIPTOR BindUnit; 部分改写;

            if (是否有绑定参数)EXEC SQL EXECUTE ExecSQLs USING SQL DESCRIPTOR indesc;elseEXEC SQL EXECUTE ExecSQLs;  

原因:LightDB不支持没有绑定参数的使用SQLDA描述符范围
(3)EXEC SQL DESCRIBE BIND VARIABLES for DYSQLSA INTO BindUnit;

            for ( j = 0 ; j < sqlpkg->paramcount; j ++){BindUnit->sqlvar[j].sqldata = (char *)malloc(sqlpkg->params[j].val.data_size+1);  memcpy(BindUnit->sqlvar[j].sqldata, sqlpkg->params[j].val.data, sqlpkg->params[j].val.data_size );BindUnit->sqlvar[j].sqldata[sqlpkg->params[j].val.data_size] = '\0';BindUnit->sqlvar[j].sqltype = 1; BindUnit->sqlvar[j].sqllen  = val.data_size;BindUnit->sqln = sqlpkg->paramcount;}

(4) EXEC SQL DESCRIBE SELECT LIST for DYSQLSA INTO SelectUnit; 语法是不支持的,这部分在LightDB中是由内核完成的

(5) EXEC SQL FOR :array_size FETCH Cursorbase USING DESCRIPTOR SelectUnit; 语法是不支持的,但是可以通过fetch into解决获取行数的问题

 EXEC SQL FETCH :array_size CursorbaseSuper INTO DESCRIPTOR SelectUnit;

(6) commit和close执行位置问题,LightDB只支持先close后commit

    EXEC SQL CLOSE cur; EXEC SQL commit;

3 总结:不同项

(1)SQLDA类型不支持
(2)EXEC SQL OPEN Cursorbase USING DESCRIPTOR BindUnit使用时有条件限制
(3)EXEC SQL DESCRIBE BIND VARIABLES for DYSQLSA INTO BindUnit;语法不支持
(4)EXEC SQL DESCRIBE SELECT LIST for DYSQLSA INTO SelectUnit;语法不支持
(5)EXEC SQL FOR :array_size FETCH Cursorbase USING DESCRIPTOR SelectUnit;不支持
(6)commit和close执行位置问题
隐藏不支持项,在于对各个绑定或者获取字段时其类型的转化是有差别的,以及在第一部分出现的不支持项,在这部分依旧是不支持项。

三、总结

针对所列举的不支持项,LightDB目前正在全力适配中,相信不久之后上述问题就能解决。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/19581.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

KMPlayer v2024.4.25.13 官方版 (万能播放器)

前言 KMPlaye通过各种插件扩展KMP可以支持层出不穷的新格式。KMPlaye强大的插件功能&#xff0c;直接从Winamp继承的插件功能&#xff0c;能够直接使用Winamp的音频&#xff0c;输入&#xff0c;视觉效果插件&#xff0c;而通过独有的扩展能力&#xff0c;只要你喜欢&#xff…

webman-admin多图上传预览和删除

前言 在webmen文档和论坛中都没找到多图上传的示例&#xff0c;自己找了一个&#xff0c;整合了一下凑合用 insert页面 引入css <link rel"stylesheet" href"/app/admin/admin/css/muti-upload.css" />muti-upload.css内容如下 .uploader-list .ha…

微信小程序学习

04.认识小程序项目的基本组成结构 把allow改成disallow,表示所有的页面不被微信进行索引。 比如修改首页的上面栏颜色

自制数据#国家2000投影带划分范围shp(高斯克吕格 3°/6°分带)

国家2000投影分带范围&#xff08;3&#xff09; https://www.123pan.com/s/lqEljv-xvCHA.html 国家2000投影分带范围&#xff08;6&#xff09; https://www.123pan.com/s/lqEljv-xvCHA.html 声明&#xff1a;转载此文不为商业用途。文字和图片版权归原作者所有&#xff0c;…

网络安全基础技术扫盲篇名词解释之“证书“

用通俗易懂的话说&#xff1a; 证书就好比是一张身份证&#xff08;类似&#xff0c;但不完全相同&#xff09;&#xff0c;用来证明一个网站的身份是否可信。就像你要确认一个陌生人的身份需要看他的身份证一样&#xff0c;电脑在连接一个网站时&#xff0c;也会查看网站的证…

延时性(过期/超时)和周期性的定时任务的实现方式

延时性&#xff08;过期/超时&#xff09;和周期性的定时任务的实现方式 一、延时性的定时任务&#xff08;例如订单超时30分钟后自动取消该订单&#xff09;1.使用DelayQueue实现任务即将到期提醒功能&#xff08;非分布式&#xff09;2.使用Redis实现任务即将到期提醒功能&am…

探索Web3工具:正确使用区块链平台工具的秘诀

在当今日新月异的数字时代&#xff0c;区块链技术正以惊人的速度改变着我们的生活和工作方式。尤其对于那些想要踏入区块链世界的人来说&#xff0c;正确使用区块链平台工具至关重要。本文将向您介绍一些关键的Web3工具&#xff0c;并以TestnetX.com为例&#xff0c;展示如何利…

数字化转型推动生物技术企业增长—纷享销客与集萃药康共探新动力

上周&#xff0c;在南京锦创书城&#xff0c;一场主题为“生物技术企业增长新动力&#xff1a;以客户为中心的数字化转型与创新”的研讨会圆满落幕。此次活动由纷享销客江苏分公司联合江苏集萃药康生物科技股份有限公司共同举办&#xff0c;吸引了众多生物技术领域企业的负责人…

斑消宝六周年大动作,斑小将将再迎高光时刻

如今&#xff0c;周年庆典已经成为众多品牌展示自身实力与影响力的重要舞台。这不仅仅是一个简单的庆祝活动&#xff0c;更是一次向外界展示品牌发展历程、未来规划以及团结合作伙伴的绝佳机会。在这样的背景下&#xff0c;广州斑消宝化妆品有限公司将打造别具一格的盛典&#…

npm安装依赖报错npm ERR! code ENOTFOUNDnpm ERR! syscall getaddrinfo

npm安装依赖报错 今天在学习vue的时候&#xff0c;在使用npm install vue -g来安装一个局部的vue时候&#xff0c;报出如下错误&#xff1a; npm ERR! code CERT_HAS_EXPIRED npm ERR! errno CERT_HAS_EXPIRED npm ERR! request to https://registry.npm.taobao.org/vue faile…

iphone内存满了开不了机怎么办?白苹果解决办法分享!

虽然苹果手机在使用时比较顺畅&#xff0c;但是手机用久了&#xff0c;照片、视频等资料累积过多&#xff0c;也难免会导致内存不足&#xff0c;出现无法开机卡在开机界面白苹果的情况。 内存不足导致iPhone白苹果的问题很常见&#xff0c;可以说是苹果最常见的故障之一。接下来…

【学习笔记】Windows GDI绘图(九)Graphics详解(上)

文章目录 Graphics 定义创建Graphics对象的方法通过Graphics绘制不同的形状、线条、图像和文字等通过Graphics操作对象坐标 Graphics属性Clip(裁切/绘制区域)ClipBounds获取裁切区域矩形范围CompositiongMode合成方式CompositingQuality渲染质量DpiX和DpiY 水平、垂直分辨率Int…

C++ 逻辑运算

一 逻辑运算 2 逻辑运算符 逻辑表达式 四 逻辑表达式 五 逻辑运算符的优先级 六 注意事项 注意 总结

JVM学习-字节码指令集(四)

异常处理指令 抛出异常指令 athrow指令&#xff1a;在Java程序中显示抛出异常的操作(throw语句)都是由athrow指令来实现除了throw语句显示抛出异常情况之外&#xff0c;JVM规范还规定了许多运行时异常会在其他Java虚拟机指令检测到异常状况时自动抛出&#xff0c;在之前介绍的…

vcruntime140_1.dll在哪个文件夹?详细修复vcruntime140_1.dll缺失的方法

vcruntime140_1.dll文件是什么&#xff1f;相信很多人都对它很陌生吧&#xff1f;毕竟大部分人对于dll文件还是了解得太少了&#xff0c;当突发情况出现vcruntime140_1.dll文件丢失&#xff1f;你要怎么办&#xff1f;不要担心&#xff0c;下面我们就来给大家详细的讲解一下修复…

GPT-4o:人工智能技术的新巅峰

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

Maven简介和快速入门

1.1Maven介绍 Maven – Introduction (apache.org) Maven就是一个软件&#xff0c;掌握软件安装、配置、以及基本功能&#xff08;项目构建、依赖管理&#xff09;。 1.2Maven主要作用 1.依赖管理&#xff1a; Maven 可以管理项目的依赖&#xff0c;包括自动下载所需依赖库、…

AI图书推荐:使用GitHub Copilot和ChatGPT辅助的Python编程

使用Python编写计算机程序变得更加简单了&#xff01;使用像GitHub Copilot和ChatGPT这样的AI辅助编码工具&#xff0c;将你的想法快速转化为应用程序。人工智能已经改变了我们编写计算机程序的方式。有了像Copilot和ChatGPT这样的工具&#xff0c;你可以用简单的英语描述你想要…

Windows环境安装redis

1、下载redis https://github.com/tporadowski/redis/releases 2、解压 .zip 3、更改文件名 更改文件名称为&#xff1a;redis 4、将本地解压后的redis&#xff0c;作为本地服务器下的应用服务 从redis文件路径下&#xff0c;执行cmd .\redis-server --service-install re…

设计模式——工厂三兄弟之抽象工厂

1.业务需求 ​ 大家好&#xff0c;我是菠菜啊。今天给大家介绍工厂三兄弟最后一个兄弟——抽象工厂。老规矩&#xff0c;在介绍这期抽象工厂模式前&#xff0c;我们先来看看这样的需求&#xff1a;现在有俩个制造工厂&#xff0c;都要生产冰箱产品&#xff0c;并且客户在使用冰…