2025年9月25日: PostgreSQL 18 发布!
支持的版本: 当前 (18) / 17 / 16 / 15 / 14 / 13
开发版本: devel
不支持的版本: 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

34.17. 内部结构 #

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

ecpg 写入输出的前四行是固定行。其中两行是注释,两行是与库接口所需的 include 行。然后预处理器逐行读取文件并写入输出。通常它只是将所有内容回显到输出。

当它看到 EXEC SQL 语句时,它会介入并进行更改。命令以 EXEC SQL 开头,以 ; 结尾。其间的所有内容都被视为一个SQL语句,并被解析用于变量替换。

变量替换发生在符号以冒号 (:) 开头时。该名称的变量会在 EXEC SQL DECLARE 部分中先前声明的变量中查找。

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

参数是

行号 #

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

字符串 #

这是要发出的SQL命令。它会被输入变量修改,即在编译时未知但要输入到命令中的变量。变量应该去的位置,字符串包含 ?

输入变量 #

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

ECPGt_EOIT #

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

输出变量 #

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

ECPGt_EORT #

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

对于作为命令一部分的每个变量,SQL函数会获得十个参数

  1. 作为特殊符号的类型。

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

  3. 如果变量是 charvarchar,则为变量的大小。

  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"

(这里的缩进是为了提高可读性,并不是预处理器所做的。)

提交更正

如果您在文档中看到任何不正确、与您对特定功能的体验不符或需要进一步澄清的内容,请使用 此表单 报告文档问题。