↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

支持中的版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发中的版本: 19 / 20devel
已结束支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2
开发快照。 PostgreSQL 20devel 尚未正式发布,内容仍可能变化。

34.9. 预处理器指令 #

一些预处理器指令可以用来改变 ecpg 预处理器解析和处理一个文件的方式。

34.9.1. 包含文件 #

要在嵌入式 SQL 程序中包含外部文件,可使用:

EXEC SQL INCLUDE filename;
EXEC SQL INCLUDE <filename>;
EXEC SQL INCLUDE "filename";

嵌入式 SQL 预处理器会查找名为 filename.h 的文件,对它进行预处理,并将其包含在生成的 C 输出中。这样,被包含文件中的嵌入式 SQL 语句就能得到正确处理。

ecpg 预处理器将以下列顺序在几个目录中搜索一个文件:

  • 当前目录
  • /usr/local/include
  • PostgreSQL 的头文件目录,在编译时定义(例如 /usr/local/pgsql/include)
  • /usr/include

但是当使用 EXEC SQL INCLUDE "filename" 时,只有当前目录会被搜索。

在每一个目录中,预处理器将首先按给定的文件名搜索,如果没有找到将会追加.h 到文件名并且重试(除非指定的文件名已经具有该后缀)。

注意 EXEC SQL INCLUDE 不同于:

#include <filename.h>

因为这样包含的文件不会经过 SQL 命令预处理。当然,仍可使用 C 的#include 指令包含其他头文件。

注意

被包含文件的名称区分大小写,尽管 EXEC SQL INCLUDE 命令的其他部分遵循通常的 SQL 大小写规则。

34.9.2. define 和 undef 指令 #

与 C 中我们熟知的指令#define 相似,嵌入式 SQL 具有类似的概念:

EXEC SQL DEFINE name;
EXEC SQL DEFINE name value;

因此你可以定义一个名称:

EXEC SQL DEFINE HAVE_FEATURE;

并且你也可以定义常量:

EXEC SQL DEFINE MYNUMBER 12;
EXEC SQL DEFINE MYSTRING 'abc';

使用 undef 来移除一个之前的定义:

EXEC SQL UNDEF MYNUMBER;

当然在你的嵌入式 SQL 程序中你可以继续使用 C 版本的#define 和#undef。区别在于你定义的值会在哪里被计算。如果你使用 EXEC SQL DEFINE,那么 ecpg 预处理器会计算这些定义并且替换值。例如,如果你写:

EXEC SQL DEFINE MYNUMBER 12;
...
EXEC SQL UPDATE Tbl SET col = MYNUMBER;

那么 ecpg 将已经做过替换并且你的 C 编译器将永远不会看见名为 MYNUMBER 的任何名称或标识符。注意你不能把#define 用于一个将要在一个嵌入式 SQL 查询中使用的常量,因为在这种情况下嵌入式 SQL 预处理器不能看到这个声明。

如果在 ecpg 预处理器的命令行上指定了多个输入文件,EXEC SQL DEFINE 和 EXEC SQL UNDEF 的作用不会跨文件传递:每个文件开始处理时只带有命令行 -D 选项定义的符号。

34.9.3. ifdef、ifndef、elif、else 和 endif 指令 #

可以使用以下指令对代码区段进行条件编译:

EXEC SQL ifdef name; #

检查 name;如果 name 已经通过 EXEC SQL define name 定义,则处理后续各行。

EXEC SQL ifndef name; #

检查 name;如果 name 尚未通过 EXEC SQL define name 定义,则处理后续各行。

EXEC SQL elif name; #

在 EXEC SQL ifdef name 或 EXEC SQL ifndef name 指令之后,开始一个可选的备选区段。可以出现任意数量的 elif 区段。如果 name 已被定义,并且同一 ifdef/ifndef...endif 结构中前面的区段均未被处理,则处理 elif 之后的各行。

EXEC SQL else; #

在 EXEC SQL ifdef name 或 EXEC SQL ifndef name 指令之后,开始一个可选的最终备选区段。如果同一 ifdef/ifndef...endif 结构中前面的区段均未被处理,则处理后续各行。

EXEC SQL endif; #

结束一个 ifdef/ifndef...endif 结构。后续的行正常处理。

ifdef/ifndef...endif 结构可以被嵌套,最深可达 127 层。

此示例只会编译三个 SET TIMEZONE 命令中的一个:

EXEC SQL ifdef TZVAR;
EXEC SQL SET TIMEZONE TO TZVAR;
EXEC SQL elif TZNAME;
EXEC SQL SET TIMEZONE TO TZNAME;
EXEC SQL else;
EXEC SQL SET TIMEZONE TO 'GMT';
EXEC SQL endif;

报告文档问题

阅读 上游文档. 反馈更正前请先核对 当前版本手册.