访问特殊数据类型
ecpg支持numeric、decimal、date、timestamp和interval数据类型。由于这些数据类型的内部结构较为复杂,无法被映射到初级数据类型的宿主变量,因此应用程序通过声明特殊类型的宿主变量,以及使用pgtypes库中的函数来处理这些特殊类型。pgtypes库中的接口函数请参见ecpg接口参考章节。
- timestamp、date 在声明部分中声明类型为timestamp的宿主变量:
EXEC SQL BEGIN DECLARE SECTION; timestamp ts; EXEC SQL END DECLARE SECTION;读取值到宿主变量之后,使用pgtypes库函数进行处理。如下示例中,使用PGTYPEStimestamp_to_asc()函数将timestamp值转换成文本形式:EXEC SQL SELECT now()::timestamp INTO :ts; printf("ts = %s\n", PGTYPEStimestamp_to_asc(ts));示例输出如下:ts = 2022-06-27 18:03:56.949343
date类型可以用相同的方式处理。程序必须包括<pgtypes_date.h>头文件,声明一个date类型的宿主变量并用PGTYPESdate_to_asc()函数将其转换成文本形式。
- interval
interval用于存储时间间隔数据(如1 min)。interval类型的处理与timestamp和date类型类似,由于其内部包含多个时间维度的复合结构,必须声明为指针,并在使用前调用PGTYPESinterval_new()在堆上分配空间。
示例如下:#include <stdio.h> #include <stdlib.h> #include <pgtypes_interval.h> int main(void) { EXEC SQL BEGIN DECLARE SECTION; interval *in; EXEC SQL END DECLARE SECTION; /* 需提前创建testdb库 */ EXEC SQL CONNECT TO testdb; /* 在堆内存中申请动态空间 */ in = PGTYPESinterval_new(); EXEC SQL SELECT '1 min'::interval INTO :in; printf("interval = %s\n", PGTYPESinterval_to_asc(in)); /* 使用完毕必须显式释放堆内存 */ PGTYPESinterval_free(in); EXEC SQL COMMIT; EXEC SQL DISCONNECT ALL; return 0; }运行结果如下:
interval = @ 1 min
- numeric、decimal
numeric和decimal类型的处理类似于interval类型,需要定义一个指针,在堆上分配一些内存空间并且使用pgtypes库函数访问该变量。
示例如下:#include <stdio.h> #include <stdlib.h> #include <pgtypes_numeric.h> EXEC SQL WHENEVER SQLERROR STOP; int main(void) { EXEC SQL BEGIN DECLARE SECTION; numeric *num; numeric *num2; decimal *dec; EXEC SQL END DECLARE SECTION; /* 需提前创建testdb库 */ EXEC SQL CONNECT TO testdb; /* 显式申请堆内存 */ num = PGTYPESnumeric_new(); dec = PGTYPESdecimal_new(); EXEC SQL SELECT 12.345::numeric(4,2), 23.456::decimal(4,2) INTO :num, :dec; /* 第二个参数控制输出格式与保留的小数位数 */ printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 0)); printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 1)); printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 2)); /* 转换十进制到数值型以显示十进制值 */ num2 = PGTYPESnumeric_new(); PGTYPESnumeric_from_decimal(dec, num2); printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 0)); printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 1)); printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 2)); /* 安全释放所有在堆上分配的资源 */ PGTYPESnumeric_free(num2); PGTYPESdecimal_free(dec); PGTYPESnumeric_free(num); EXEC SQL COMMIT; EXEC SQL DISCONNECT ALL; return 0; }运行结果如下:
numeric = 12 numeric = 12.4 numeric = 12.35 decimal = 23 decimal = 23.5 decimal = 23.46