codecamp

PostgreSQL 内部

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

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

PostgreSQL Informix兼容模式
PostgreSQL 信息模式
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

PostgreSQL SQL语言

PostgreSQL 服务器管理

PostgreSQL 客户端接口

PostgreSQL 服务器编程

PostgreSQL 参考

PostgreSQL 内部

PostgreSQL 附录

PostgreSQL 参考书目

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }