Postgresql 中文操作指南

36.9. Preprocessor Directives #

有些可用的预处理器指令会改变 ecpg 预处理器如何解析和处理文件。

Several preprocessor directives are available that modify how the ecpg preprocessor parses and processes a file.

36.9.1. Including Files #

要将外部文件包含到嵌入式 SQL 程序中,请使用:

To include an external file into your embedded SQL program, use:

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

嵌入式 SQL 预处理器会查找名为 _filename .h_ 的文件,对它进行预处理并将其包含到生成的 C 输出中。因此,在所包含的文件中的嵌入式 SQL 语句得到正确处理。

The embedded SQL preprocessor will look for a file named _filename.h_, preprocess it, and include it in the resulting C output. Thus, embedded SQL statements in the included file are handled correctly.

ecpg 预处理器将按照如下顺序搜索几个目录中的文件:

The ecpg preprocessor will search a file at several directories in following order:

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

But when EXEC SQL INCLUDE "_filename"_ is used, only the current directory is searched.

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

In each directory, the preprocessor will first look for the file name as given, and if not found will append .h to the file name and try again (unless the specified file name already has that suffix).

请注意,EXEC SQL INCLUDEnot 相同:

Note that EXEC SQL INCLUDE is not the same as:

#include <filename.h>

因为该文件不会受到 SQL 命令预处理。自然地,你可以继续使用 C #include 指令来包含其他头文件。

because this file would not be subject to SQL command preprocessing. Naturally, you can continue to use the C #include directive to include other header files.

Note

包含的文件名区分大小写,即使_EXEC SQL INCLUDE_命令的其他部分遵循正常的 SQL 大小写规则。

The include file name is case-sensitive, even though the rest of the EXEC SQL INCLUDE command follows the normal SQL case-sensitivity rules.

36.9.2. The define and undef Directives #

类似于 C 中已知的 #define 指令,嵌入式 SQL 有一个类似的概念:

Similar to the directive #define that is known from C, embedded SQL has a similar concept:

EXEC SQL DEFINE name;
EXEC SQL DEFINE name value;

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

So you can define a name:

EXEC SQL DEFINE HAVE_FEATURE;

并且也可以定义常量:

And you can also define constants:

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

使用 undef 以删除上一个定义:

Use undef to remove a previous definition:

EXEC SQL UNDEF MYNUMBER;

当然,你可以在嵌入式 SQL 程序中继续使用 C 版本 #define#undef。不同的是定义的值在哪里得到评估。如果你使用 EXEC SQL DEFINE,那么 ecpg 预处理器会评估定义并替换值。例如,如果你输入:

Of course you can continue to use the C versions #define and #undef in your embedded SQL program. The difference is where your defined values get evaluated. If you use EXEC SQL DEFINE then the ecpg preprocessor evaluates the defines and substitutes the values. For example if you write:

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

那么 ecpg 将已经进行替换,并且 C 编译器永远不会看到任何名称或标识符 MYNUMBER。请注意,你不能对打算在嵌入式 SQL 查询中使用的常量使用 #define,因为在这种情况下,嵌入式 SQL 预编译器无法看到此声明。

then ecpg will already do the substitution and your C compiler will never see any name or identifier MYNUMBER. Note that you cannot use #define for a constant that you are going to use in an embedded SQL query because in this case the embedded SQL precompiler is not able to see this declaration.

如果在 ecpg 预处理器的命令行上命名了多个输入文件,EXEC SQL DEFINEEXEC SQL UNDEF 的影响将不会跨文件传递:每个文件都仅从 -D 交换机在命令行上定义的符号开始。

If multiple input files are named on the ecpg preprocessor’s command line, the effects of EXEC SQL DEFINE and EXEC SQL UNDEF do not carry across files: each file starts with only the symbols defined by -D switches on the command line.

36.9.3. ifdef, ifndef, elif, else, and endif Directives #

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

You can use the following directives to compile code sections conditionally:

  • EXEC SQL ifdef _name;_ #

    • Checks a name and processes subsequent lines if name has been defined via EXEC SQL define _name_.

  • EXEC SQL ifndef _name;_ #

    • Checks a name and processes subsequent lines if name has not been defined via EXEC SQL define _name_.

  • EXEC SQL elif _name;_ #

    • Begins an optional alternative section after an EXEC SQL ifdef _name or _EXEC SQL ifndef _name directive. Any number of _elif sections can appear. Lines following an elif will be processed if name has been defined and no previous section of the same ifdef/ifndef…​_endif_ construct has been processed.

  • EXEC SQL else; #

    • Begins an optional, final alternative section after an EXEC SQL ifdef _name or _EXEC SQL ifndef _name directive. Subsequent lines will be processed if no previous section of the same _ifdef/ifndef…​_endif_ construct has been processed.

  • EXEC SQL endif; #

    • Ends an ifdef/ifndef…​_endif_ construct. Subsequent lines are processed normally.

ifdef/ifndef…​endif 结构可以嵌套,深度最高可达 127 级。

ifdef/ifndef…​endif constructs can be nested, up to 127 levels deep.

此示例将编译三个 SET TIMEZONE 命令中的正好一个:

This example will compile exactly one of the three SET TIMEZONE commands:

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;