LightDB24.1 pro*c 支持EXEC ORACLE OPTION (CHAR_MAP=STRING)

server/2024/10/18 14:37:45/

背景介绍

为了方便ORACLE数据库迁移到LightDB数据库,兼容Pro*C的语法规则。从LightDB24.1版本开始ECPG支持EXEC ORACLE OPTION(CHAR_MAP=STRING)。设置该选项后,将保证字符数组以null结尾。
LightDB ECPG官网
使用约束:

  • 仅支持一维字符数组,保证一维字符数组以null结尾。
  • 仅支持select into到本地数组,保证本地数组null结尾。

使用示例

  1. ecpg源文件
#include <stdio.h>
#include <stdlib.h>EXEC ORACLE OPTION (RELEASE_cursor = No);
EXEC ORACLE OPTION (char_map=String);
exec sql type string is char[5];
typedef char string[5];EXEC SQL BEGIN DECLARE SECTION;
struct TBempl
{char	a;char b[5];
};union StateMachine
{
char c1[5];
int c2;
};
EXEC SQL END DECLARE SECTION;int main()
{EXEC SQL BEGIN DECLARE SECTION;struct TBempl v1;struct TBempl v2;int i = 0;int j = 0;string s1;string s2[2];char arr[2][5];struct TBempl v3[2];union StateMachine u1;EXEC SQL END DECLARE SECTION;EXEC SQL WHENEVER SQLWARNING SQLPRINT;EXEC SQL WHENEVER SQLERROR SQLPRINT;char cc[5];EXEC SQL CONNECT TO oracle_test AS main;EXEC SQL SELECT c1,c2 INTO :v1 from test_struct;EXEC SQL SELECT c2 INTO :v2.b from test_struct;EXEC SQL SELECT name INTO :s1 from test;EXEC SQL SELECT name INTO :s2 from test2;EXEC SQL SELECT name INTO :arr from test2;EXEC SQL SELECT name INTO :u1.c1 from test;EXEC SQL SELECT name INTO :cc from test;EXEC SQL SELECT c1,c2 INTO :v3 from test_struct2;printf("===============struct v1================\n");printf("Print ASCII:%x\n",(unsigned char)v1.a);printf("======================================\n");for(i=0;i<5;i++) {printf("Print ASCII:%x\n",(unsigned char)v1.b[i]);}printf("===============struct v2================\n");//printf("Print ASCII:%x\n",(unsigned char)v1.a);printf("======================================\n");for(i=0;i<5;i++) {printf("Print ASCII:%x\n",(unsigned char)v2.b[i]);}printf("================string s1===================\n");for(i=0;i<5;i++) {printf("Print ASCII:%x\n",(unsigned char)s1[i]);}printf("================string s2[2]===================\n");for(i=0;i<5;i++) {printf("Print ASCII:%x\n",(unsigned char)s2[0][i]);}printf("======================================\n");for(i=0;i<5;i++) {printf("Print ASCII:%x\n",(unsigned char)s2[1][i]);}printf("================union u1.c1===================\n");for(i=0;i<5;i++) {printf("Print ASCII:%x\n",(unsigned char)u1.c1[i]);}printf("================arr[2][5]===================\n");for (i=0;i<5;i++){printf("Print ASCII:%x\n",(unsigned char)arr[0][i]);}for (i=0;i<5;i++){printf("Print ASCII:%x\n",(unsigned char)arr[1][i]);}printf("================cc[5]===================\n");for (i=0;i<5;i++){printf("Print ASCII:%x\n",(unsigned char)cc[i]);}printf("================v3[2]===================\n");printf("Print ASCII:%x\n",(unsigned char)v3[0].a);printf("======================================\n");for(i=0;i<5;i++) {printf("Print ASCII:%x\n",(unsigned char)v3[0].b[i]);}printf("======================================\n");printf("Print ASCII:%x\n",(unsigned char)v3[1].a);printf("======================================\n");for(i=0;i<5;i++) {printf("Print ASCII:%x\n",(unsigned char)v3[1].b[i]);}EXEC SQL SELECT c1,c2 INTO :v3[1] from test_struct;printf("================v3[1]===================\n");printf("Print ASCII:%x\n",(unsigned char)v3[1].a);printf("======================================\n");for(i=0;i<5;i++) {printf("Print ASCII:%x\n",(unsigned char)v3[1].b[i]);}EXEC SQL DISCONNECT;
}
  1. 编译pgc文件生成c文件,ecpg ecpg_struct.pgc -o ecpg_struct.c
/* Processed by ecpg (13.8) */
/* These include files are added by the preprocessor */
#include <ecpglib.h>
#include <ecpgerrno.h>
#include <sqlca.h>
/* End of automatic include section */#line 1 "ecpg_struct.pgc"
#include <stdio.h>
#include <stdlib.h>/* exec oracle option (RELEASE_cursor=No) */
/* exec oracle option (char_map=String) *//* exec sql type string is char [ 5 ] */
#line 7 "ecpg_struct.pgc"typedef char  string [ 5 ];#line 8 "ecpg_struct.pgc"#line 8 "ecpg_struct.pgc"/* exec sql begin declare section */struct TBempl { 
#line 13 "ecpg_struct.pgc"char a ;#line 14 "ecpg_struct.pgc"char b [ 5 ] ;} ; union StateMachine { 
#line 19 "ecpg_struct.pgc"char c1 [ 5 ] ;#line 20 "ecpg_struct.pgc"int c2 ;} ;/* exec sql end declare section */
#line 22 "ecpg_struct.pgc"int  main ( )
#line 24 "ecpg_struct.pgc"{/* exec sql begin declare section */#line 27 "ecpg_struct.pgc"struct TBempl v1 ;#line 28 "ecpg_struct.pgc"struct TBempl v2 ;#line 29 "ecpg_struct.pgc"int i = 0 ;#line 30 "ecpg_struct.pgc"int j = 0 ;#line 31 "ecpg_struct.pgc"string s1 ;#line 32 "ecpg_struct.pgc"string s2 [ 2 ] ;#line 33 "ecpg_struct.pgc"char arr [ 2 ] [ 5 ] ;#line 34 "ecpg_struct.pgc"struct TBempl v3 [ 2 ] ;#line 35 "ecpg_struct.pgc"union StateMachine u1 ;
/* exec sql end declare section */
#line 36 "ecpg_struct.pgc"/* exec sql whenever sql_warning  sqlprint ; */
#line 37 "ecpg_struct.pgc"/* exec sql whenever sqlerror  sqlprint ; */
#line 38 "ecpg_struct.pgc"#line 40 "ecpg_struct.pgc"char cc [ 5 ] ;#line 40 "ecpg_struct.pgc"{ ECPGconnect(__LINE__, 0, "oracle_test", NULL, NULL, "main", 0); 
#line 41 "ecpg_struct.pgc"if (sqlca.sqlwarn[0] == 'W') sqlprint();
#line 41 "ecpg_struct.pgc"if (sqlca.sqlcode < 0) sqlprint();}
#line 41 "ecpg_struct.pgc"{ struct lt_ecpg_config lt_conf;lt_conf.ecpg_version_num=LT_ECPG_CONFIG_VERSION;lt_conf.oracle_char_map=1;ECPGdo(__LINE__, 0, 1, NULL, 0, &lt_conf, ECPGst_normal, "select c1, c2 from test_struct", ECPGt_EOIT, ECPGt_char,&(v1.a),(long)1,(long)1,sizeof( struct TBempl ),0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_char,&(v1.b),(long)5,(long)1,sizeof( struct TBempl ),1L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
#line 44 "ecpg_struct.pgc"if (sqlca.sqlwarn[0] == 'W') sqlprint();
#line 44 "ecpg_struct.pgc"if (sqlca.sqlcode < 0) sqlprint();}
#line 44 "ecpg_struct.pgc"{ struct lt_ecpg_config lt_conf;lt_conf.ecpg_version_num=LT_ECPG_CONFIG_VERSION;lt_conf.oracle_char_map=1;ECPGdo(__LINE__, 0, 1, NULL, 0, &lt_conf, ECPGst_normal, "select c2 from test_struct", ECPGt_EOIT, ECPGt_char,(v2.b),(long)5,(long)1,(5)*sizeof(char),1L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
#line 45 "ecpg_struct.pgc"if (sqlca.sqlwarn[0] == 'W') sqlprint();
#line 45 "ecpg_struct.pgc"if (sqlca.sqlcode < 0) sqlprint();}
#line 45 "ecpg_struct.pgc"{ struct lt_ecpg_config lt_conf;lt_conf.ecpg_version_num=LT_ECPG_CONFIG_VERSION;lt_conf.oracle_char_map=1;ECPGdo(__LINE__, 0, 1, NULL, 0, &lt_conf, ECPGst_normal, "select name from test", ECPGt_EOIT, ECPGt_char,(s1),(long)5,(long)1,(5)*sizeof(char),1L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
#line 46 "ecpg_struct.pgc"if (sqlca.sqlwarn[0] == 'W') sqlprint();
#line 46 "ecpg_struct.pgc"if (sqlca.sqlcode < 0) sqlprint();}
#line 46 "ecpg_struct.pgc"{ struct lt_ecpg_config lt_conf;lt_conf.ecpg_version_num=LT_ECPG_CONFIG_VERSION;lt_conf.oracle_char_map=1;ECPGdo(__LINE__, 0, 1, NULL, 0, &lt_conf, ECPGst_normal, "select name from test2", ECPGt_EOIT, ECPGt_char,(s2),(long)5,(long)2,(5)*sizeof(char),0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
#line 47 "ecpg_struct.pgc"if (sqlca.sqlwarn[0] == 'W') sqlprint();
#line 47 "ecpg_struct.pgc"if (sqlca.sqlcode < 0) sqlprint();}
#line 47 "ecpg_struct.pgc"{ struct lt_ecpg_config lt_conf;lt_conf.ecpg_version_num=LT_ECPG_CONFIG_VERSION;lt_conf.oracle_char_map=1;ECPGdo(__LINE__, 0, 1, NULL, 0, &lt_conf, ECPGst_normal, "select name from test2", ECPGt_EOIT, ECPGt_char,(arr),(long)5,(long)2,(5)*sizeof(char),0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
#line 48 "ecpg_struct.pgc"if (sqlca.sqlwarn[0] == 'W') sqlprint();
#line 48 "ecpg_struct.pgc"if (sqlca.sqlcode < 0) sqlprint();}
#line 48 "ecpg_struct.pgc"{ struct lt_ecpg_config lt_conf;lt_conf.ecpg_version_num=LT_ECPG_CONFIG_VERSION;lt_conf.oracle_char_map=1;ECPGdo(__LINE__, 0, 1, NULL, 0, &lt_conf, ECPGst_normal, "select name from test", ECPGt_EOIT, ECPGt_char,(u1.c1),(long)5,(long)1,(5)*sizeof(char),1L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
#line 49 "ecpg_struct.pgc"if (sqlca.sqlwarn[0] == 'W') sqlprint();
#line 49 "ecpg_struct.pgc"if (sqlca.sqlcode < 0) sqlprint();}
#line 49 "ecpg_struct.pgc"{ struct lt_ecpg_config lt_conf;lt_conf.ecpg_version_num=LT_ECPG_CONFIG_VERSION;lt_conf.oracle_char_map=1;ECPGdo(__LINE__, 0, 1, NULL, 0, &lt_conf, ECPGst_normal, "select name from test", ECPGt_EOIT, ECPGt_char,(cc),(long)5,(long)1,(5)*sizeof(char),0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
#line 50 "ecpg_struct.pgc"if (sqlca.sqlwarn[0] == 'W') sqlprint();
#line 50 "ecpg_struct.pgc"if (sqlca.sqlcode < 0) sqlprint();}
#line 50 "ecpg_struct.pgc"{ struct lt_ecpg_config lt_conf;lt_conf.ecpg_version_num=LT_ECPG_CONFIG_VERSION;lt_conf.oracle_char_map=1;ECPGdo(__LINE__, 0, 1, NULL, 0, &lt_conf, ECPGst_normal, "select c1, c2 from test_struct2", ECPGt_EOIT, ECPGt_char,&(v3->a),(long)1,(long)2,sizeof( struct TBempl ),0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_char,&(v3->b),(long)5,(long)2,sizeof( struct TBempl ),0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
#line 51 "ecpg_struct.pgc"if (sqlca.sqlwarn[0] == 'W') sqlprint();
#line 51 "ecpg_struct.pgc"if (sqlca.sqlcode < 0) sqlprint();}
#line 51 "ecpg_struct.pgc"printf("===============struct v1================\n");printf("Print ASCII:%x\n",( unsigned char)v1.a);printf("======================================\n");for(i=0;i<5;i++) {printf("Print ASCII:%x\n",( unsigned char)v1.b[i]);}printf("===============struct v2================\n");//printf("Print ASCII:%x\n",(unsigned char)v1.a);printf("======================================\n");for(i=0;i<5;i++) {printf("Print ASCII:%x\n",( unsigned char)v2.b[i]);}printf("================string s1===================\n");for(i=0;i<5;i++) {printf("Print ASCII:%x\n",( unsigned char)s1[i]);}printf("================string s2[2]===================\n");for(i=0;i<5;i++) {printf("Print ASCII:%x\n",( unsigned char)s2[0][i]);}printf("======================================\n");for(i=0;i<5;i++) {printf("Print ASCII:%x\n",( unsigned char)s2[1][i]);}printf("================union u1.c1===================\n");for(i=0;i<5;i++) {printf("Print ASCII:%x\n",( unsigned char)u1.c1[i]);}printf("================arr[2][5]===================\n");for(i=0;i<5;i++){printf("Print ASCII:%x\n",( unsigned char)arr[0][i]);}for(i=0;i<5;i++){printf("Print ASCII:%x\n",( unsigned char)arr[1][i]);}printf("================cc[5]===================\n");for(i=0;i<5;i++){printf("Print ASCII:%x\n",( unsigned char)cc[i]);}printf("================v3[2]===================\n");printf("Print ASCII:%x\n",( unsigned char)v3[0].a);printf("======================================\n");for(i=0;i<5;i++) {printf("Print ASCII:%x\n",( unsigned char)v3[0].b[i]);}printf("======================================\n");printf("Print ASCII:%x\n",( unsigned char)v3[1].a);printf("======================================\n");for(i=0;i<5;i++) {printf("Print ASCII:%x\n",( unsigned char)v3[1].b[i]);}{ struct lt_ecpg_config lt_conf;lt_conf.ecpg_version_num=LT_ECPG_CONFIG_VERSION;lt_conf.oracle_char_map=1;ECPGdo(__LINE__, 0, 1, NULL, 0, &lt_conf, ECPGst_normal, "select c1, c2 from test_struct", ECPGt_EOIT, ECPGt_char,&(v3[1].a),(long)1,(long)1,sizeof( struct TBempl ),0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_char,&(v3[1].b),(long)5,(long)1,sizeof( struct TBempl ),1L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
#line 108 "ecpg_struct.pgc"if (sqlca.sqlwarn[0] == 'W') sqlprint();
#line 108 "ecpg_struct.pgc"if (sqlca.sqlcode < 0) sqlprint();}
#line 108 "ecpg_struct.pgc"printf("================v3[1]===================\n");printf("Print ASCII:%x\n",( unsigned char)v3[1].a);printf("======================================\n");for(i=0;i<5;i++) {printf("Print ASCII:%x\n",( unsigned char)v3[1].b[i]);}{ ECPGdisconnect(__LINE__, "CURRENT");
#line 116 "ecpg_struct.pgc"if (sqlca.sqlwarn[0] == 'W') sqlprint();
#line 116 "ecpg_struct.pgc"if (sqlca.sqlcode < 0) sqlprint();}
#line 116 "ecpg_struct.pgc"}
  1. 编译c文件生成bin文件,运行得到结果,会发现只有一维数组添加了null结尾
gcc ecpg_struct.c -lecpg -lpgtypes -o ecpg_charmap -I /home/lightdb/stage/lightdb-x/include/ -L/home/lightdb/stage/lightdb-x/lib
[lightdb@192 ~]$ ./ecpg_charmap
===============struct v1================
Print ASCII:48
======================================
Print ASCII:41
Print ASCII:42
Print ASCII:43
Print ASCII:44
Print ASCII:0
===============struct v2================
======================================
Print ASCII:41
Print ASCII:42
Print ASCII:43
Print ASCII:44
Print ASCII:0
================string s1===================
Print ASCII:41
Print ASCII:42
Print ASCII:43
Print ASCII:20
Print ASCII:0
================string s2[2]===================
Print ASCII:41
Print ASCII:42
Print ASCII:43
Print ASCII:20
Print ASCII:20
======================================
Print ASCII:44
Print ASCII:45
Print ASCII:46
Print ASCII:20
Print ASCII:20
================union u1.c1===================
Print ASCII:41
Print ASCII:42
Print ASCII:43
Print ASCII:20
Print ASCII:0
================arr[2][5]===================
Print ASCII:41
Print ASCII:42
Print ASCII:43
Print ASCII:20
Print ASCII:20
Print ASCII:44
Print ASCII:45
Print ASCII:46
Print ASCII:20
Print ASCII:20
================cc[5]===================
Print ASCII:41
Print ASCII:42
Print ASCII:43
Print ASCII:20
Print ASCII:20
================v3[2]===================
Print ASCII:48
======================================
Print ASCII:41
Print ASCII:42
Print ASCII:43
Print ASCII:44
Print ASCII:45
======================================
Print ASCII:49
======================================
Print ASCII:46
Print ASCII:47
Print ASCII:48
Print ASCII:49
Print ASCII:4a
================v3[1]===================
Print ASCII:48
======================================
Print ASCII:41
Print ASCII:42
Print ASCII:43
Print ASCII:44
Print ASCII:0
[lightdb@192 ~]$ 
  1. 样例代码中使用的相关表数据
lightdb@oracle_test=# select * from test;name  
-------ABC  
(1 row)lightdb@oracle_test=# \d+ testTable "public.test"Column |     Type     | Collation | Nullable | Default | Storage  | Stats target | Description 
--------+--------------+-----------+----------+---------+----------+--------------+-------------name   | character(5) |           |          |         | extended |              | 
Access method: heaplightdb@oracle_test=# 
lightdb@oracle_test=# select * from test2;name  
-------ABC  DEF  
(2 rows)lightdb@oracle_test=# \d+ test2Table "public.test2"Column |     Type     | Collation | Nullable | Default | Storage  | Stats target | Description 
--------+--------------+-----------+----------+---------+----------+--------------+-------------name   | character(5) |           |          |         | extended |              | 
Access method: heaplightdb@oracle_test=# select * from test_struct;c1 |  c2   
----+-------H  | ABCDE
(1 row)lightdb@oracle_test=# \d+ test_structTable "public.test_struct"Column |     Type     | Collation | Nullable | Default | Storage  | Stats target | Description 
--------+--------------+-----------+----------+---------+----------+--------------+-------------c1     | character(1) |           |          |         | extended |              | c2     | character(5) |           |          |         | extended |              | 
Access method: heaplightdb@oracle_test=# 
lightdb@oracle_test=# select * from test_struct2;c1 |  c2   
----+-------H  | ABCDEI  | FGHIJ
(2 rows)lightdb@oracle_test=# 
lightdb@oracle_test=# \d+ test_struct2Table "public.test_struct2"Column |     Type     | Collation | Nullable | Default | Storage  | Stats target | Description 
--------+--------------+-----------+----------+---------+----------+--------------+-------------c1     | character(1) |           |          |         | extended |              | c2     | character(5) |           |          |         | extended |              | 
Access method: heaplightdb@oracle_test=# 

http://www.ppmy.cn/server/19228.html

相关文章

星融元加入超以太网联盟(UEC),推动智算网络创新实践

近日&#xff0c;星融元正式加入超以太网联盟(Ultra Ethernet Consortium,UEC)&#xff0c;该联盟是在 Linux 基金会的牵头下由多家全球头部科技企业联合成立&#xff0c;目标是突破传统以太网性能瓶颈&#xff0c;使其适用于人工智能&#xff08;AI&#xff09;和高性能计算&a…

行为型设计模式(下)

命令模式 命令模式是一种行为设计模式&#xff0c;它将一个请求封装为一个对象&#xff0c;从而允许用户使用不同的请求、队列或日志请求&#xff0c;并支持可撤销的操作。它主要涉及三个角色&#xff1a;发送者&#xff08;Invoker&#xff09;、接收者&#xff08;Receiver&…

【机器学习】机器学习学习笔记 - 监督学习 - KNN线性回归岭回归 - 02

监督学习 KNN (k-nearest neighbors) KNN 是用 k 个最近邻的训练数据集来寻找未知对象分类的一种算法 from sklearn import neighbors# 分类 # 创建KNN分类器模型并进行训练 classifier neighbors.KNeighborsClassifier(num_neighbors, weightsdistance) classifier.fit(X,…

【数据结构(邓俊辉)学习笔记】向量03——无序向量

文章目录 0.概述1.元素访问2.置乱器3.判等器与比较器4.无序查找4.1 判等器4.2 顺序查找4.3 实现4.4 复杂度 5. 插入5.1 算法实现5.2 复杂度分析 6. 删除6.1 区间删除6.2 单元删除6.3 复杂度 7. 唯一化7.1 实现7.2 正确性7.3 复杂度 8. 遍历8.1 实现8.2 复杂度 9. 总结 0.概述 …

Ubuntu: 自留小技巧

#!/bin/bash# 指定要检查的文件夹 folder"/path/to/your/directory"# 遍历文件夹中的每一个文件 for file in "$folder"/* do# 检查文件中的每一行是否都包含"#"if awk !/#/ "$file" | read -r _then# 如果有一行不包含"#"&…

【Linux学习】​​学习Linux的准备工作和Linux的基本指令

˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如…

DreamFusion:探索深度学习驱动的3D内容生成

DreamFusion&#xff1a;探索深度学习驱动的3D内容生成 摘要&#xff1a; 本文将深入探讨DreamFusion&#xff0c;这是一种利用深度学习技术生成逼真的3D内容的创新框架。我们将详细介绍DreamFusion的技术原理、实现过程以及其在各个领域的潜在应用。 关键词&#xff1a;深度学…

【Pytorch】PytorchCPU版或GPU报错异常处理(10X~4090D)

Pytorch为CPU版或GPU使用报错异常处理 文章目录 Pytorch为CPU版或GPU使用报错异常处理0.检查阶段1. 在conda虚拟环境中安装了torch2.卸载cpuonly3.从tsinghua清华源安装不完善误为cpu版本4.用tsinghua清华源安装成cpu错误版本5.conda中torch/vision/cudatoolkit版本与本机cuda版…