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

背景介绍

为了方便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+ test
                                      Table "public.test"
 Column |     Type     | Collation | Nullable | Default | Storage  | Stats target | Description 
--------+--------------+-----------+----------+---------+----------+--------------+-------------
 name   | character(5) |           |          |         | extended |              | 
Access method: heap

lightdb@oracle_test=# 
lightdb@oracle_test=# select * from test2;
 name  
-------
 ABC  
 DEF  
(2 rows)

lightdb@oracle_test=# \d+ test2
                                      Table "public.test2"
 Column |     Type     | Collation | Nullable | Default | Storage  | Stats target | Description 
--------+--------------+-----------+----------+---------+----------+--------------+-------------
 name   | character(5) |           |          |         | extended |              | 
Access method: heap

lightdb@oracle_test=# select * from test_struct;
 c1 |  c2   
----+-------
 H  | ABCDE
(1 row)

lightdb@oracle_test=# \d+ test_struct
                                   Table "public.test_struct"
 Column |     Type     | Collation | Nullable | Default | Storage  | Stats target | Description 
--------+--------------+-----------+----------+---------+----------+--------------+-------------
 c1     | character(1) |           |          |         | extended |              | 
 c2     | character(5) |           |          |         | extended |              | 
Access method: heap

lightdb@oracle_test=# 
lightdb@oracle_test=# select * from test_struct2;
 c1 |  c2   
----+-------
 H  | ABCDE
 I  | FGHIJ
(2 rows)

lightdb@oracle_test=# 
lightdb@oracle_test=# \d+ test_struct2
                                  Table "public.test_struct2"
 Column |     Type     | Collation | Nullable | Default | Storage  | Stats target | Description 
--------+--------------+-----------+----------+---------+----------+--------------+-------------
 c1     | character(1) |           |          |         | extended |              | 
 c2     | character(5) |           |          |         | extended |              | 
Access method: heap

lightdb@oracle_test=# 
  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值