PostgreSQL 中文参考文档
🌐 英文原版 官方 ↗

34.17. 底层内部机制 #

本节说明 ECPG 的工作原理。这些信息偶尔有助于用户理解如何使用 ECPG。

ecpg 写到输出的前四行是固定的行。 两行是注释,两行是与库交互所必需的 include 行。随后, 预处理器通读整个文件并写出输出。通常它只是把所有内容原样 回显到输出。

当它看到一条 EXEC SQL 语句时,它会介入并 改写它。该命令以 EXEC SQL 开始,以 ; 结束。介于其间的 所有内容都被当作一条 SQL 语句处理,并被解析以进行变量替换。

当一个符号以冒号(:)开始时会发生变量 替换。该名称的变量会在此前于 EXEC SQL DECLARE 段中声明的变量中查找。

库中最重要的函数是 ECPGdo,它负责执行大多数命令。它接受 数量可变的参数。参数很容易累积到 50 个左右,我们希望这在任何 平台上都不会成为问题。

这些参数是:

行号 #

这是原始行的行号;只用于错误消息中。

A string #

这是要发出的 SQL 命令。它会被输入变量 改写,输入变量就是编译时未知、但将在命令执行时输入的变量。 在变量应当出现的位置,字符串中包含 ?。

Input variables #

每个输入变量都会导致创建十个参数。(见下文。)

ECPGt_EOIT #

一个 enum,表示没有更多的输入变量了。

Output variables #

每个输出变量都会导致创建十个参数。(见下文。) 这些变量由该函数填充。

ECPGt_EORT #

一个 enum,表示没有更多的变量了。

对于作为 SQL 命令一部分的每个变量,该函数 接收十个参数:

  1. 以特殊符号表示的类型。

  2. 指向值的指针,或指向指针的指针。

  3. 如果变量是 char 或 varchar, 则为变量的大小。

  4. 数组中元素的数量(用于数组取回)。

  5. 数组中下一个元素的偏移量(用于数组取回)。

  6. 以特殊符号表示的指示符变量的类型。

  7. 指向指示符变量的指针。

  8. 0

  9. 指示符数组中元素的数量(用于数组取回)。

  10. 指示符数组中下一个元素的偏移量(用于数组取回)。

注意,并非所有 SQL 命令都以这种方式处理。 例如,像下面这样一条打开游标的语句:

EXEC SQL OPEN cursor;

不会被复制到输出中。相反,游标的 DECLARE 命令会被用在 OPEN 命令的位置,因为它确实会打开该游标。

下面是一个完整的例子,描述对文件 foo.pgc 进行预处理后的输出(细节可能随预处理器的具体版本而变化):

EXEC SQL BEGIN DECLARE SECTION;
int index;
int result;
EXEC SQL END DECLARE SECTION;
...
EXEC SQL SELECT res INTO :result FROM mytable WHERE index = :index;

会被翻译为:

/* Processed by ecpg (2.6.0) */
/* These two include files are added by the preprocessor */
#include <ecpgtype.h>;
#include <ecpglib.h>;

/* exec sql begin declare section */

#line 1 "foo.pgc"

 int index;
 int result;
/* exec sql end declare section */
...
ECPGdo(__LINE__, NULL, "SELECT res FROM mytable WHERE index = ?     ",
        ECPGt_int,&(index),1L,1L,sizeof(int),
        ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
        ECPGt_int,&(result),1L,1L,sizeof(int),
        ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
#line 147 "foo.pgc"

(这里的缩进是为了便于阅读而添加的,预处理器本身并不这样做。)