36.17. 内部#
本节说明ECPG的内部工作原理。此信息偶尔可帮助用户了解如何使用ECPG。
ecpg
向输出写入的前四行是固定行。两行是注释,两行是与库接口所需的包含行。然后,预处理器通读文件并写入输出。通常,它只是将所有内容回显到输出。
当它看到EXEC SQL
语句时,它会介入并更改它。该命令以EXEC SQL
开头,以;
结尾。中间的所有内容都将视为SQL语句,并进行解析以进行变量替换。
当符号以冒号 (:
) 开头时,将发生变量替换。在EXEC SQL DECLARE
部分中先前声明的变量中查找具有该名称的变量。
库中最重要的函数是ECPGdo
,它负责执行大多数命令。它采用可变数量的参数。这很容易增加到 50 个左右的参数,我们希望这在任何平台上都不会成为问题。
参数为
- 行号 #
这是原始行的行号;仅用于错误消息。
- 字符串 #
这是要发出的 命令。它由输入变量修改,即在编译时未知但在命令中输入的变量。字符串中包含
?
的位置是变量应该放置的位置。- 输入变量 #
每个输入变量都会导致创建十个参数。(见下文。)
ECPGt_EOIT
#一个
enum
,表示没有更多输入变量。- 输出变量 #
每个输出变量都会导致创建十个参数。(见下文。)这些变量由函数填充。
ECPGt_EORT
#一个
enum
,表示没有更多变量。
对于SQL命令中包含的每个变量,该函数获取十个参数
类型为特殊符号。
指向值或指向指针的指针。
如果变量是
char
或varchar
,则为变量的大小。数组中的元素数量(用于数组获取)。
数组中下一个元素的偏移量(用于数组获取)。
指示器变量的类型作为特殊符号。
指向指示器变量的指针。
0
指示器数组中的元素数量(用于数组获取)。
指示器数组中下一个元素的偏移量(用于数组获取)。
请注意,并非所有 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"
(此处添加缩进是为了可读性,而不是预处理器所做的事情。)