PostgreSQL 9.4.4 中文手册
上一页 | 上一级 | 章 33. ECPG - 在C中嵌入SQL | 下一页

# 33.16. 内部

这一节解释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;

不会被拷贝到输出中。 而是在`OPEN`命令的位置使用游标的`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;

被翻译成：

    /* 通过ecpg (2.6.0)处理，通过预处理器添加2个include文件*/

    #include <ecpgtype.h>;
    #include <ecpglib.h>;

    /* exec sql开始声明段 */

    #line 1 "foo.pgc"

     int index;
     int result;

    /* exec sql结束声明段 */
    ...
    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"

(这里的凹进是为了增强可读性加的，可不是预处理器能干的事情。)

上一页 | 起始页 | 下一页
Informix兼容模式 | 上一级 | 信息模式