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
    评论
这段代码实现了一个行星运动的模拟。其中,x、v、m 分别表示行星的位置、速度和质量,dt 表示时间步长,t 表示时间向量,N 表示行星数量,X 和 V 分别是行星的位置和速度随时间的变化。gravity 函数计算行星之间的万有引力加速度。我注意到这段代码有一些问题,需要进行修改: 1. G 的值未定义,需要添加常量 G 定义,如 G = 6.6743e-11; 2. 在循环中,X 和 V 应该是三维数组,需要修改为 X(i,:,:) 和 V(i,:,:); 3. 在循环中,a 的计算式应该是 a(i,:) = a(i,:) + G * m(j) / norm(r_ij)^3 * r_ij;,因为 a(i,:) 已经被初始化为 [0,0]。 修改后的代码如下: clc;clear; G = 6.6743e-11; x = [0, 0; 69.8e9, 0; 108.9e9, 0; 152.1e9, 0; 249.2e9, 0; 778.5e9, 0; 1.429e12, 0; 2.871e12, 0]; % 行星初始位置(单位:米) v = [0, 0; 0, 47.9e3; 0, 35.0e3; 0, 29.8e3; 0, 24.1e3; 0, 13.1e3; 0, 9.7e3; 0, 6.8e3]; m = [1.9891e30, 3.302e23, 4.869e24, 5.972e24, 6.39e23, 1.898e27, 5.683e26, 8.681e25]; % 行星质量(单位:千克) dt = 86400/2; t = 0:dt:365*50*86400; N = 8; X = zeros(length(t), N, 2); V = zeros(length(t), N, 2); lt=length(t); for i = 2:length(t) a = gravity(X(i-1,:,:), m); V(i,:,:)=V(i-1,:,:)+a*dt; X(i,:,:)= X(i-1,:,:)+V(i-1,:,:).*dt+0.5*a*(dt^2); end function a = gravity(x, m) N = size(x, 1); a = zeros(N, 2); for i = 1:N for j = 1:N if j ~= i r_ij = x(j,:,:) - x(i,:,:); a(i,:) = a(i,:) + G * m(j) / norm(r_ij)^3 * r_ij; end end end end

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值