↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

支持中的版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发中的版本: 19 / 20devel
已结束支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1
历史版本。 PostgreSQL 12 已结束支持。 2024-11-21. 请参阅 当前版本手册.

35.17. 内部 #

这一节解释 ECPG 在内部如何工作。这些信息有时有助于用户理解如何使用 ECPG。

ecpg 写入输出的前四行是固定的:其中两行是注释,另外两行是与库接口所必需的包含行。随后预处理器会通读整个文件并写出输出,通常它只是把所有内容原样回显到输出中。

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

当某个符号以冒号(:)开头时,就会发生变量替换。系统会在此前于 EXEC SQL DECLARE 声明节中声明的变量里查找同名变量。

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

参数是:

一个行号

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

一个字符串

这是将要发出的 SQL 命令。输入变量会对它进行修改,也就是那些在编译时尚未知晓、但要填入命令中的变量。字符串中的?表示变量应当放置的位置。

输入变量

每个输入变量都会生成十个参数(见下文)。

ECPGt_EOIT

一个表明后面没有更多输入变量的 enum 值。

输出变量

每个输出变量都会生成十个参数(见下文)。这些变量将由该函数填充。

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;

会被转换成:

/* 由 ecpg (2.6.0) 处理 */
/* 这两个头文件由预处理器增加 */
#include <ecpgtype.h>;
#include <ecpglib.h>;

/* 声明节开始 */

#line 1 "foo.pgc"

 int index;
 int result;
/* 声明节结束 */
...
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"

(这里的缩进是为了可读性而添加的,并非是预处理器做的处理)。

报告文档问题

阅读 上游文档. 反馈更正前请先核对 当前版本手册.