一些预处理器指令可以用来改变ecpg
预处理器解析和处理一个文件的方式。
要包括一个外部文件到你的嵌入式 SQL 程序中,可以用:
EXEC SQL INCLUDEfilename
; EXEC SQL INCLUDE <filename
>; EXEC SQL INCLUDE "filename
";
嵌入式 SQL 预处理器将查找一个名为
的文件,处理它并且把它包括在结果 C 输出中。这样,被包括文件中的嵌入式 SQL 语句会被正确地处理。
filename
.h
ecpg
预处理器将以下列顺序在几个目录中搜索一个文件:
/usr/local/include
/usr/local/pgsql/include
)/usr/include
但是当使用EXEC SQL INCLUDE "
时,只有当前目录会被搜索。
filename
"
在每一个目录中,预处理器将首先按给定的文件名搜索,如果没有找到将会追加.h
到文件名并且重试(除非指定的文件名已经具有该后缀)。
注意EXEC SQL INCLUDE
不同于:
#include <filename
.h>
因为这个文件不服从 SQL 命令预处理。自然地,你可以继续使用 C 的#include
指令来包括其他头文件。
包括文件名是大小写敏感的,即使EXEC SQL INCLUDE
命令的剩余部分遵守通常的 SQL 大小写敏感规则。
与 C 中我们熟知的指令#define
相似,嵌入式 SQL 具有类似的概念:
EXEC SQL DEFINEname
; EXEC SQL DEFINEname
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
开关定义的符号。
你可以使用下列指定来有条件地编译代码小节:
EXEC SQL ifdef name
;
检查一个name
,如果已经用EXEC SQL define
定义了name
name
就处理接下来的行。
EXEC SQL ifndef name
;
检查一个name
,如果没有用EXEC SQL define
定义name
name
就处理接下来的行。
EXEC SQL elif name
;
在EXEC SQL ifdef
或者name
EXEC SQL ifndef
命令之后开始一个可选的备选小节。
可以出现任意数量的name
elif
小节。
跟在elif
后面的行将被处理,如果name
已经被定义并且
在相同的ifdef
/ifndef
...endif
结构中前面的小节没有被处理。
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;