pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
本节解释 ecpg 的内部 工作原理。这些信息偶尔能帮助 用户理解如何使用 ecpg。
ecpg写入输出的前四行是固定的:其中两行是注释,另外两行是与库接口所必需的包含行。随后预处理器会通读整个文件并写出输出,通常它只是把所有内容原样回显到输出中。
当它看到 EXEC SQL 语句时,会 介入并改写它。命令以 exec sql 开始,以 ; 结束。中间的 一切都被当作 SQL 语句 并解析变量替换。
当符号以冒号(:)开头时发生 变量替换。具有该名称的变量会在先前在 EXEC SQL DECLARE 区中声明的变量里查找。 根据该变量用于输入还是输出, 会输出一个指向该变量的指针供 函数访问。
对于作为 SQL 查询一部分的每个变量,函数还会得到其他参数:
用特殊符号表示的类型。
一个值的指针或者一个指针的指针。
如果变量是一个char或者varchar,这是它的尺寸。
数组中元素的数量(用于数组获取)。
数组中下一个元素的偏移量(用于数组获取)。
作为一个特殊符号的指示符变量的类型。
指向指示符变量值的指针,或指向指示符 变量指针的指针。
0
指示符数组中的元素个数(用于数组抓取)。
到指示符数组中下一个元素的偏移量(用于数组取数)。
注意并非所有 SQL 命令都这样处理。例如, 像
EXEC SQL OPEN cursor;
这样的 open cursor 语句不会复制到输出中。相反,会使用游标的 DECLARE 命令,因为它也会打开 游标。
下面是一个完整的例子,描述预处理器对文件 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"
(本手册中的缩进是为了可读性而加的, 并不是预处理器所做的。)
库中最重要的函数是 ECPGdo。它接受数量可变的 参数。但愿没有计算机会限制 varargs() 函数可接受的 变量数。这很容易累积到 50 个左右的参数。
参数有:
这是原语句的行号;只用于 错误消息。
这是要发出的 SQL 查询。它被输入 变量修改,即那些编译时未知但要输入 查询的变量。在变量应出现的 位置,字符串中包含 ?。
如关于预处理器的 一节所述,每个输入变量得到十个参数。
ECPGt_EOIT一个表明后面没有更多输入变量的enum值。
如关于预处理器的 一节所述,每个输入变量得到十个参数。这些变量由该函数 填充。
ECPGt_EORT一个表明后面没有更多变量的enum值。
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。