Postgresql 中文操作指南
36.6. pgtypes Library #
pgtypes 库将 PostgreSQL 数据库类型映射到可以用于 C 程序的 C 等效项。它还提供在 C 中使用这些类型进行基本计算的函数,即不需要 PostgreSQL 服务器帮助。请看以下示例:
EXEC SQL BEGIN DECLARE SECTION;
date date1;
timestamp ts1, tsout;
interval iv1;
char *out;
EXEC SQL END DECLARE SECTION;
PGTYPESdate_today(&date1);
EXEC SQL SELECT started, duration INTO :ts1, :iv1 FROM datetbl WHERE d=:date1;
PGTYPEStimestamp_add_interval(&ts1, &iv1, &tsout);
out = PGTYPEStimestamp_to_asc(&tsout);
printf("Started + duration: %s\n", out);
PGTYPESchar_free(out);
36.6.1. Character Strings #
诸如 PGTYPESnumeric_to_asc 之类的一些函数返回一个指向新分配的字符字符串的指针。这些结果应该用 PGTYPESchar_free 代替 free 释放。(这仅在 Windows 中很重要,其中内存分配和释放有时需要由同一个库完成。)
36.6.2. The numeric Type #
数字类型提供使用任意精度进行计算。请参见 Section 8.1中的 PostgreSQL 服务器中对应的类型。由于精度是任意的,因此这个变量需要能够动态地扩展和缩小。这就是为什么您只能通过 _PGTYPESnumeric_new_和 _PGTYPESnumeric_free_函数在堆上创建数字变量。十进制类型与之类似,但精度有限,可以在堆上和栈上创建。
可以使用以下函数使用 numeric 类型:
-
PGTYPESnumeric_new #
-
请求一个指向新分配的 numeric 变量的指针。
-
numeric *PGTYPESnumeric_new(void);
-
PGTYPESnumeric_free #
-
释放 numeric 类型,释放其所有内存。
-
void PGTYPESnumeric_free(numeric *var);
-
PGTYPESnumeric_from_asc #
-
从其字符串表示形式解析 numeric 类型。
-
numeric *PGTYPESnumeric_from_asc(char *str, char **endptr);
-
有效格式例如:-2、.794、+3.44、592.49E07 或 -32.84e-4。如果能够成功解析该值,则返回一个有效的指针,否则返回 NULL 指针。目前,ECPG 始终解析完整的字符串,因此目前不支持将第一个无效字符的地址存储在 *endptr 中。你可以放心地将 endptr 设置为 NULL。
-
PGTYPESnumeric_to_asc #
-
-
返回一个由 malloc 分配的字符串的指针,其中包含 numeric 类型 num 的字符串表示形式。
char *PGTYPESnumeric_to_asc(numeric *num, int dscale);
-
numeric 值将使用 dscale 个小数位打印,必要时使用舍入。结果必须使用 PGTYPESchar_free() 释放。
-
PGTYPESnumeric_add #
-
-
将两个 numeric 变量添加到第三个变量中。
int PGTYPESnumeric_add(numeric *var1, numeric *var2, numeric *result);
-
该函数将变量 var1 和 var2 添加到结果变量 result 中。该函数在成功时返回 0,在错误时返回 -1。
-
PGTYPESnumeric_sub #
-
-
减去两个 numeric 变量,并在第三个变量中返回结果。
int PGTYPESnumeric_sub(numeric *var1, numeric *var2, numeric *result);
-
该函数从变量 var2 中减去变量 var1。操作结果存储在变量 result 中。该函数在成功时返回 0,在错误时返回 -1。
-
PGTYPESnumeric_mul #
-
-
乘以两个 numeric 变量,并在第三个变量中返回结果。
int PGTYPESnumeric_mul(numeric *var1, numeric *var2, numeric *result);
-
该函数乘以变量 var1 和 var2。操作结果存储在变量 result 中。该函数在成功时返回 0,在错误时返回 -1。
-
PGTYPESnumeric_div #
-
-
除以两个 numeric 变量,并在第三个变量中返回结果。
int PGTYPESnumeric_div(numeric *var1, numeric *var2, numeric *result);
-
该函数将变量 var1 除以 var2。操作结果存储在变量 result 中。该函数在成功时返回 0,在错误时返回 -1。
-
PGTYPESnumeric_cmp #
-
-
Compare two numeric variables.
int PGTYPESnumeric_cmp(numeric *var1, numeric *var2)
-
此函数比较两个数值变量。发生错误时,返回 INT_MAX。成功时,函数返回三个可能结果之一:
-
PGTYPESnumeric_from_int #
-
-
将 int 变量转换为数值变量。
int PGTYPESnumeric_from_int(signed int int_val, numeric *var);
-
此函数接受有符号 int 类型变量,并将其存储在 var 数值变量中。成功时,返回 0,失败时返回 -1。
-
PGTYPESnumeric_from_long #
-
-
将 long int 变量转换为数值变量。
int PGTYPESnumeric_from_long(signed long int long_val, numeric *var);
-
此函数接受有符号 long int 类型变量,并将其存储在 var 数值变量中。成功时,返回 0,失败时返回 -1。
-
PGTYPESnumeric_copy #
-
-
将一个数值变量复制到另一个。
int PGTYPESnumeric_copy(numeric *src, numeric *dst);
-
此函数将 src 指向的变量值复制到 dst 指向的变量中。成功时,返回 0,发生错误时返回 -1。
-
PGTYPESnumeric_from_double #
-
-
将 double 类型变量转换为数值。
int PGTYPESnumeric_from_double(double d, numeric *dst);
-
此函数接受 double 类型变量,并将结果存储在 dst 指向的变量中。成功时,返回 0,发生错误时返回 -1。
-
PGTYPESnumeric_to_double #
-
-
将数值类型变量转换为 double。
int PGTYPESnumeric_to_double(numeric *nv, double *dp)
-
函数将 nv 指向的变量中的数值转换为 dp 指向的 double 变量中。成功时,返回 0,发生错误时返回 -1,包括溢出。在溢出时,全局变量 errno 将另外设置为 PGTYPES_NUM_OVERFLOW。
-
PGTYPESnumeric_to_int #
-
-
将数值类型变量转换为 int。
int PGTYPESnumeric_to_int(numeric *nv, int *ip);
-
函数将 nv 指向的变量中的数值转换为 ip 指向的整数变量中。成功时,返回 0,发生错误时返回 -1,包括溢出。在溢出时,全局变量 errno 将另外设置为 PGTYPES_NUM_OVERFLOW。
-
PGTYPESnumeric_to_long #
-
-
将数值类型变量转换为 long。
int PGTYPESnumeric_to_long(numeric *nv, long *lp);
-
函数将 nv 指向的变量中的数值转换为 lp 指向的长整数变量中。成功时,返回 0,发生错误时返回 -1,包括溢出。在溢出时,全局变量 errno 将另外设置为 PGTYPES_NUM_OVERFLOW。
-
PGTYPESnumeric_to_decimal #
-
-
将数值类型变量转换为 decimal。
int PGTYPESnumeric_to_decimal(numeric *src, decimal *dst);
-
函数将 src 指向的变量中的数值转换为 dst 指向的 decimal 变量中。成功时,返回 0,发生错误时返回 -1,包括溢出。在溢出时,全局变量 errno 将另外设置为 PGTYPES_NUM_OVERFLOW。
-
PGTYPESnumeric_from_decimal #
-
-
将 decimal 类型变量转换为数值。
int PGTYPESnumeric_from_decimal(decimal *src, numeric *dst);
-
函数将 src 指向的变量中的 decimal 值转换为 dst 指向的数值变量中。成功时,返回 0,发生错误时返回 -1。由于 decimal 类型实现为数值类型的限制版本,因此此转换不会发生溢出。
36.6.3. The date Type #
C 语言中的 date 类型允许您的程序处理 SQL 类型 date 的数据。请参见 Section 8.5中的 PostgreSQL 服务器中对应的类型。
下列函数可用于处理数据类型:
-
PGTYPESdate_from_timestamp #
-
从时间戳中提取日期部分。
-
date PGTYPESdate_from_timestamp(timestamp dt);
-
此函数将时间戳作为其唯一参数接收,并从此时间戳返回提取的日期部分。
-
PGTYPESdate_from_asc #
-
-
从其文本表示形式中解析日期。
date PGTYPESdate_from_asc(char *str, char **endptr);
-
此函数接收 C char* 字符串 str 和 C char* 字符串 endptr 的指针。目前 ECPG 始终解析完整字符串,因此目前不支持将第一个无效字符的地址存储在 *endptr 中。您可以安全地将 endptr 设置为 NULL。
-
请注意,此函数始终假定 MDY 格式化日期,ECPG 中目前没有变量可以更改该日期。
-
Table 36.2显示允许的输入格式。
-
PGTYPESdate_to_asc #
-
-
返回日期变量的文本表示形式。
char *PGTYPESdate_to_asc(date dDate);
-
此函数接收日期 dDate 作为其唯一参数。它将以 1999-01-18 格式输出日期,即采用 YYYY-MM-DD 格式。结果必须用 PGTYPESchar_free() 释放。
-
PGTYPESdate_julmdy #
-
-
从 date 类型的变量中提取天、月和年的值。
void PGTYPESdate_julmdy(date d, int *mdy);
-
该函数接收日期_d_和指向包含3个整数值的数组的指针_mdy_。变量名称表示顺序:_mdy[0]_将被设置为包含月份数, _mdy[1]_将被设置为日的数值,_mdy[2]_将包含年。
-
PGTYPESdate_mdyjul #
-
-
从指定日期的天、月和年的 3 个整数的数组中创建一个日期值。
void PGTYPESdate_mdyjul(int *mdy, date *jdate);
-
此函数接收 3 个整数 (mdy) 的数组作为其第一个参数,接收指向应该存储操作结果的 date 类型变量的指针作为其第二个参数。
-
PGTYPESdate_dayofweek #
-
-
返回一个数字,表示日期值的星期几。
int PGTYPESdate_dayofweek(date d);
-
此函数接收日期变量 d 作为其唯一参数,并返回一个整数,表示此日期的星期几。
-
PGTYPESdate_today #
-
-
Get the current date.
void PGTYPESdate_today(date *d);
-
此函数接收一个指向 date 变量 (d) 的指针,该变量设置为当前日期。
-
PGTYPESdate_fmt_asc #
-
-
利用格式掩码将日期类型变量转化为它的文本表示。
int PGTYPESdate_fmt_asc(date dDate, char *fmtstring, char *outbuf);
-
此函数接收要转换的日期(dDate)、格式掩码(fmtstring),以及将保存日期文本表示的字符串(outbuf)。
-
成功时返回 0,出错时返回负值。
-
下列文字是你可以使用的字段限定符:
-
所有其他字符都将 1:1 复制到输出字符串中。
-
Table 36.3表示一些可能格式。这将让你了解如何使用此函数。所有输出行均基于同一天:1959年11月23日。
-
PGTYPESdate_defmt_asc #
-
-
使用格式掩码将 C char* 字符串转换为日期类型的变量。
int PGTYPESdate_defmt_asc(date *d, char *fmt, char *str);
-
此函数接收以下内容的指针:日期值(应保存操作结果)(d)、用于解析日期的格式掩码(fmt)、以及包含日期文本表示的 C char* 字符串(str)。文本表示应匹配格式掩码。但是你不需要将字符串与格式掩码进行 1:1 映射。此函数仅分析顺序,并查找指示年份位置的文字 yy 或 yyyy、指示月份位置的 mm,以及指示日期位置的 dd。
-
Table 36.4表示一些可能格式。这将让你了解如何使用此函数。
Table 36.2. Valid Input Formats for PGTYPESdate_from_asc
Input |
Result |
January 8, 1999 |
January 8, 1999 |
1999-01-08 |
January 8, 1999 |
1/8/1999 |
January 8, 1999 |
1/18/1999 |
January 18, 1999 |
01/02/03 |
February 1, 2003 |
1999-Jan-08 |
January 8, 1999 |
Jan-08-1999 |
January 8, 1999 |
08-Jan-1999 |
January 8, 1999 |
99-Jan-08 |
January 8, 1999 |
08-Jan-99 |
January 8, 1999 |
08-Jan-06 |
January 8, 2006 |
Jan-08-99 |
January 8, 1999 |
19990108 |
ISO 8601; January 8, 1999 |
990108 |
ISO 8601; January 8, 1999 |
1999.008 |
year and day of year |
J2451187 |
Julian day |
January 8, 99 BC |
year 99 before the Common Era |
Table 36.3. Valid Input Formats for PGTYPESdate_fmt_asc
Format |
Result |
mmddyy |
112359 |
ddmmyy |
231159 |
yymmdd |
591123 |
yy/mm/dd |
59/11/23 |
yy mm dd |
59 11 23 |
yy.mm.dd |
59.11.23 |
.mm.yyyy.dd. |
.11.1959.23. |
mmm. dd, yyyy |
Nov. 23, 1959 |
mmm dd yyyy |
Nov 23 1959 |
yyyy dd mm |
1959 23 11 |
ddd, mmm. dd, yyyy |
Mon, Nov. 23, 1959 |
(ddd) mmm. dd, yyyy |
(Mon) Nov. 23, 1959 |
Table 36.4. Valid Input Formats for rdefmtdate
Format |
String |
Result |
ddmmyy |
21-2-54 |
1954-02-21 |
ddmmyy |
2-12-54 |
1954-12-02 |
ddmmyy |
20111954 |
1954-11-20 |
ddmmyy |
130464 |
1964-04-13 |
mmm.dd.yyyy |
MAR-12-1967 |
1967-03-12 |
yy/mm/dd |
1954, February 3rd |
1954-02-03 |
mmm.dd.yyyy |
041269 |
1969-04-12 |
yy/mm/dd |
In the year 2525, in the month of July, mankind will be alive on the 28th day |
2525-07-28 |
dd-mm-yy |
I said on the 28th of July in the year 2525 |
2525-07-28 |
mmm.dd.yyyy |
9/14/58 |
1958-09-14 |
yy/mm/dd |
47/03/29 |
1947-03-29 |
mmm.dd.yyyy |
oct 28 1975 |
1975-10-28 |
mmddyy |
Nov 14th, 1985 |
1985-11-14 |
36.6.4. The timestamp Type #
C中的时间戳类型使你的程序能够处理 SQL 类型时间戳的数据。参见 Section 8.5以了解 PostgreSQL 服务器中的等效类型。
可以使用以下函数处理时间戳类型:
-
PGTYPEStimestamp_from_asc #
-
从其文本表示解析时间戳到时间戳变量中。
-
timestamp PGTYPEStimestamp_from_asc(char *str, char **endptr);
-
此函数接收要解析的字符串(str)和 C char* 的指针(endptr)。目前,ECPG 始终解析整个字符串,因此它当前不支持将第一个无效字符的地址存储在 *endptr 中。你可以将 endptr 安全地设置为 NULL。
-
如果成功,该函数将返回解析的时间戳。如果发生错误, PGTYPESInvalidTimestamp 将返回, errno 将设置为 PGTYPES_TS_BAD_TIMESTAMP 。请参阅 PGTYPESInvalidTimestamp 了解该值的注意事项。
-
通常,输入字符串可以包含允许的日期规范、空格字符和允许的时间规范的任意组合。请注意,ECPG 不支持时区。它可以解析时区,但不会执行任何计算,例如 PostgreSQL 服务器所做的计算。时区限定符将被默默丢弃。
-
Table 36.5包含输入字符串的一些示例。
-
PGTYPEStimestamp_to_asc #
-
-
将日期转换为 C char* 字符串。
char *PGTYPEStimestamp_to_asc(timestamp tstamp);
-
此函数仅接收时间戳 tstamp 作为其唯一参数,并返回一个已分配的字符串,其中包含时间戳的文本表示形式。使用 PGTYPESchar_free() 必须释放结果。
-
PGTYPEStimestamp_current #
-
-
Retrieve the current timestamp.
void PGTYPEStimestamp_current(timestamp *ts);
-
此函数检索当前时间戳并将其保存到 ts 指向的时间戳变量中。
-
PGTYPEStimestamp_fmt_asc #
-
-
使用格式掩码将时间戳变量转换为一个 C char*。
int PGTYPEStimestamp_fmt_asc(timestamp *ts, char *output, int str_len, char *fmtstr);
-
此函数接收指向要转换的时间戳的指针作为其第一个参数 (ts), 一个指向输出缓冲区的指针 (output), 为输出缓冲区已分配的最大长度 (str_len), 以及用于转换的格式掩码 (fmtstr)。
-
如果成功,则此函数返回 0,如果发生错误,则返回一个负值。
-
你可以对格式掩码使用以下格式说明符。格式说明符与 strftime 中 libc 函数中使用的说明符相同。任何非格式说明符都将复制到输出缓冲区。
-
PGTYPEStimestamp_sub #
-
-
从一个时间戳中减去另一个时间戳,并将结果保存到类型为 interval 的变量中。
int PGTYPEStimestamp_sub(timestamp *ts1, timestamp *ts2, interval *iv);
-
此函数将从 ts1 指向的时间戳变量中减去 ts2 指向的时间戳变量,并将结果存储到 iv 指向的 interval 变量中。
-
如果成功,则此函数返回 0,如果发生错误,则返回一个负值。
-
PGTYPEStimestamp_defmt_asc #
-
-
使用格式化掩码从其文本表示形式解析时间戳值。
int PGTYPEStimestamp_defmt_asc(char *str, char *fmt, timestamp *d);
-
此函数接收 str 中变量中的时间戳文本表示形式,以及 fmt 中变量中使用的格式化掩码。结果将存储到 d 指向的变量中。
-
如果格式化掩码 fmt 为 NULL, 则此函数将使用默认格式化掩码 %Y-%m-%d %H:%M:%S。
-
这是 PGTYPEStimestamp_fmt_asc 的反向函数。请参阅其中的文档,了解有关可能的格式掩码条目的信息。
-
PGTYPEStimestamp_add_interval #
-
-
将一个 interval 变量添加到一个时间戳变量。
int PGTYPEStimestamp_add_interval(timestamp *tin, interval *span, timestamp *tout);
-
此函数接收指向时间戳变量 tin 的指针和指向 interval 变量 span 的指针。它将 interval 添加到时间戳,并将结果时间戳保存到 tout 指向的变量中。
-
如果成功,则此函数返回 0,如果发生错误,则返回一个负值。
-
PGTYPEStimestamp_sub_interval #
-
-
从一个时间戳变量中减去一个 interval 变量。
int PGTYPEStimestamp_sub_interval(timestamp *tin, interval *span, timestamp *tout);
-
此函数从 tin 指向的时间戳变量中减去 span 指向的 interval 变量,并将结果保存到 tout 指向的变量中。
-
如果成功,则此函数返回 0,如果发生错误,则返回一个负值。
Table 36.5. Valid Input Formats for PGTYPEStimestamp_from_asc
Input |
Result |
1999-01-08 04:05:06 |
1999-01-08 04:05:06 |
January 8 04:05:06 1999 PST |
1999-01-08 04:05:06 |
1999-Jan-08 04:05:06.789-8 |
1999-01-08 04:05:06.789 (time zone specifier ignored) |
J2451187 04:05-08:00 |
1999-01-08 04:05:00 (time zone specifier ignored) |
36.6.5. The interval Type #
C中的间隔类型使你的程序能够处理 SQL 类型间隔的数据。参见 Section 8.5以了解 PostgreSQL 服务器中的等效类型。
以下功能可用于使用间隔类型:
-
PGTYPESinterval_new #
-
返回指向新分配的间隔变量的指针。
-
interval *PGTYPESinterval_new(void);
-
PGTYPESinterval_free #
-
释放之前分配的间隔变量的内存。
-
void PGTYPESinterval_free(interval *intvl);
-
PGTYPESinterval_from_asc #
-
从文本表示形式分析间隔。
-
interval *PGTYPESinterval_from_asc(char *str, char **endptr);
-
函数分析输入字符串 str 并返回指向已分配间隔变量的指针。目前,ECPG 始终分析完成的字符串,因此目前不支持在 *endptr 中存储第一个无效字符的地址。您可以安全地将 endptr 设置为 NULL。
-
PGTYPESinterval_to_asc #
-
-
将类型为间隔的变量转换为其文本表示形式。
char *PGTYPESinterval_to_asc(interval *span);
-
函数将 span 指向的间隔变量转换为 C char*。输出看上去像此示例:@ 1 day 12 hours 59 mins 10 secs。必须使用 PGTYPESchar_free() 释放结果。
-
PGTYPESinterval_copy #
-
-
复制类型为间隔的变量。
int PGTYPESinterval_copy(interval *intvlsrc, interval *intvldest);
-
函数将 intvlsrc 指向的间隔变量复制到 intvldest 指向的变量中。请注意,您需要提前为目标变量分配内存。
36.6.6. The decimal Type #
十进制度类似于数值类型。然而,它被限制为最高精度30个有效数字。与只能在堆上创建的数字类型相比,十进制度可以在堆栈或堆上创建(通过函数_PGTYPESdecimal_new_和_PGTYPESdecimal_free_)。在 Section 36.15中描述的信息工兼容模式中有许多其他处理十进制度的函数。
以下函数可用于处理 decimal 类型,不只包含在 libcompat 库中。
-
PGTYPESdecimal_new #
-
请求指向新分配的 decimal 变量的指针。
-
decimal *PGTYPESdecimal_new(void);
-
PGTYPESdecimal_free #
-
释放 decimal 类型,释放其所有内存。
-
void PGTYPESdecimal_free(decimal *var);
36.6.7. errno Values of pgtypeslib #
-
PGTYPES_NUM_BAD_NUMERIC #
-
自变量应包含一个数字变量(或指向一个数字变量),但实际上其内存表示形式无效。
-
-
PGTYPES_NUM_OVERFLOW #
-
发生了溢出。由于数字类型可以处理几乎任意精度,将数字变量转换为其他类型可能导致溢出。
-
-
PGTYPES_NUM_UNDERFLOW #
-
发生了下溢。由于数字类型可以处理几乎任意精度,将数字变量转换为其他类型可能导致下溢。
-
-
PGTYPES_NUM_DIVIDE_ZERO #
-
尝试除以零。
-
-
PGTYPES_DATE_BAD_DATE #
-
将无效的日期字符串传递给 PGTYPESdate_from_asc 函数。
-
-
PGTYPES_DATE_ERR_EARGS #
-
将无效的自变量传递给 PGTYPESdate_defmt_asc 函数。
-
-
PGTYPES_DATE_ERR_ENOSHORTDATE #
-
PGTYPESdate_defmt_asc 函数中发现输入字符串中令牌无效。
-
-
PGTYPES_INTVL_BAD_INTERVAL #
-
PGTYPESinterval_from_asc 函数中传递无效间隔字符串,或向 PGTYPESinterval_to_asc 函数传递无效间隔值。
-
-
PGTYPES_DATE_ERR_ENOTDMY #
-
PGTYPESdate_defmt_asc 函数中的日期/月份/年份分配不匹配。
-
-
PGTYPES_DATE_BAD_DAY #
-
PGTYPESdate_defmt_asc 函数中发现无效的月份日期值。
-
-
PGTYPES_DATE_BAD_MONTH #
-
PGTYPESdate_defmt_asc 函数中发现无效的月份值。
-
-
PGTYPES_TS_BAD_TIMESTAMP #
-
向 PGTYPEStimestamp_from_asc 函数传递无效时间戳字符串,或向 PGTYPEStimestamp_to_asc 函数传递无效时间戳值。
-
-
PGTYPES_TS_ERR_EINFTIME #
-
在无法处理的上下文中遇到无限时间戳值。
-
36.6.8. Special Constants of pgtypeslib #
-
PGTYPESInvalidTimestamp #
-
表示无效时间戳的时间戳类型的某个值。这是 function PGTYPEStimestamp_from_asc 在出现解析错误时返回的值。请注意,由于 timestamp 数据类型的内部表示,PGTYPESInvalidTimestamp 同时也是有效时间戳。它被设置为 1899-12-31 23:59:59。为了检测到错误,请确保您的应用程序在每次调用 PGTYPEStimestamp_from_asc 后,不仅会测试 PGTYPESInvalidTimestamp,还会测试 errno != 0。
-