Skip to content

36.9. 预处理器指令#

36.9.1. 包含文件
36.9.2. define 和 undef 指令
36.9.3. ifdef、ifndef、elif、else 和 endif 指令

有若干预处理器指令可用于修改ecpg预处理器如何解析和处理文件。

36.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 大小写敏感性规则。

36.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 预编译器无法看到此声明。

36.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 nameEXEC SQL ifndef name 指令后开始一个可选的备选部分。可以出现任意数量的 elif 部分。如果 name 已定义 同一个 ifdef/ifndef...endif 构造的先前部分未被处理,则将处理 elif 后面的行。

EXEC SQL else; #

EXEC SQL ifdef nameEXEC 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;