Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16 / 17

34.9. 预处理器指令 #

34.9.1. 包含文件
34.9.2. define 和 undef 指令
34.9.3. ifdef、ifndef、elif、else 和 endif 指令

有许多预处理器指令可用,可修改 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。请注意,你不能对将用于嵌入式 SQL 查询的常量使用 #define,因为在这种情况下,嵌入式 SQL 预编译器无法看到此声明。

如果在 ecpg 预处理器的命令行中指定了多个输入文件,EXEC SQL DEFINEEXEC SQL UNDEF 的效果不会跨文件传递:每个文件仅以命令行上 -D 开关定义的符号开头。

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

您可以使用以下指令有条件地编译代码部分

EXEC SQL ifdef 名称; #

检查 名称,如果 名称 已通过 EXEC SQL define 名称 定义,则处理后续行。

EXEC SQL ifndef 名称; #

检查 名称,如果 名称 通过 EXEC SQL define 名称 定义,则处理后续行。

EXEC SQL elif 名称; #

EXEC SQL ifdef 名称EXEC SQL ifndef 名称 指令后开始可选的替代部分。可显示任意数量的 elif 部分。如果 名称 已定义 并且 同一 ifdef/ifndef...endif 构造的先前部分未处理,则处理 elif 后面的行。

EXEC SQL else; #

EXEC SQL ifdef 名称EXEC SQL ifndef 名称 指令后开始可选的最终替代部分。如果同 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;