pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
本节解释 ecpg 的内部工作原理。它包含有助于 用户理解如何使用 ecpg 的 宝贵信息。
ecpg 写入输出的前四行是固定的: 其中两行是注释,另外两行是与库接口所必需的 包含行。
随后预处理器通读整个文件并写出输出。 通常它只是把所有内容原样回显到输出。
当它遇到 EXEC SQL 语句时,会 介入并改变它。EXEC SQL 语句可以是下列之一:
Declare 节以:
exec sql begin declare section;
开始,以:
exec sql end declare section;
结束。此节内只允许变量声明。此节内 声明的每个变量都按名称索引连同其对应 类型存储在一个变量列表中。
特别是结构或联合的定义也必须 列在 declare 区内。否则 ecpg 无法处理这些类型,因为 它不知道定义。
声明也会被回显到文件中,使其成为普通的 C 变量。
特殊类型 VARCHAR 和 VARCHAR2 会为每个变量 转换成一个命名的结构。像这样的声明:
VARCHAR var[180];
会被转换为:
struct varchar_var { int len; char arr[180]; } var;
include 语句的形式是:
exec sql include filename;
注意这不同于:
#include <filename.h>
Instead the file specified is parsed by ecpg so the contents of the file are included in the resulting C code. This way you are able to specify EXEC SQL commands in an include file.
connect 语句的形式是:
exec sql connect to connection target;
它创建到指定数据库的一个连接。
connection target 可以用下列 方式指定:
dbname[@server][:port][as connection name][user user name]tcp:postgresql://server[:port][/dbname][as connection name][user user name]unix:postgresql://server[:port][/dbname][as connection name][user user name]character variable[as connection name][user user name]character string[as connection name][user]defaultuser还有几种指定用户名的方式:
useriduserid/passworduserid identified by passworduserid using password最后,userid 和 password 可以是常量文本、 字符变量或字符串。
disconnect 语句的形式是:
exec sql disconnect [connection target];
它关闭到指定数据库的连接。
connection target 可以用下列 方式指定:
connection namedefaultcurrentallopen cursor 语句的形式是:
exec sql open cursor;
并且不被复制到输出中。相反,会使用游标的 DECLARE 命令,因为它也会打开 游标。
commit 语句的形式是:
exec sql commit;
rollback 语句的形式是:
exec sql rollback;
其他 SQL 语句以 exec sql 开始、以 ; 结束的方式使用。中间的 一切都被当作 SQL 语句 并解析变量替换。
当符号以冒号 (:)开头时发生变量替换。此时会在先前 于 declare 节中声明的变量里查找具有该名字的 变量。根据该变量用于输入还是输出, 指向该变量的指针会被写到输出中 以允许函数访问。
对于作为 SQL 查询一部分的每个变量,函数会得到其他参数:
The type as a special symbol.
指向值的指针,或指向指针的指针。
如果变量是 char 或 varchar,则为变量的大小。
数组中的元素个数(用于数组抓取)。
到数组中下一个元素的偏移(用于数组抓取)。
作为特殊符号的指示符变量的类型。
指向指示符变量值的指针,或指向指示符变量指针的指针。
0.
指示符数组中的元素个数(用于数组抓取)。
到指示符数组中下一个元素的偏移(用于 数组抓取)。
下面是一个完整的例子,描述预处理器对文件 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;
is translated into:
/* 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"
(The indentation in this manual is added for readability and not something the preprocessor does.)
库中最重要的函数是 ECPGdo。它接受数量可变的 参数。但愿没有计算机会限制 varargs() 函数可接受的 变量数。这很容易累积到 50 个左右的参数。
参数有:
这是原语句的行号;只用于错误消息。
这是要发出的 SQL 查询。它被输入 变量修改,即那些编译时未知但要输入 查询的变量。在变量应出现的 位置,字符串中包含 ?。
如关于预处理器的 一节所述,每个输入变量得到十个参数。
ECPGt_EOIT一个枚举,表示不再有输入变量。
如关于预处理器的 一节所述,每个输入变量得到十个参数。 These variables are filled by the function.
一个枚举,表示不再有变量。
在默认模式下,只有在发出 exec sql commit 时查询才被提交。Ecpg 还通过 -t 命令行选项或 exec sql set autocommit to on 语句支持事务的自动提交。在 autocommit 模式下,除非处于显式的事务块中,每条 查询都会自动提交。这个 模式可以用 exec sql set autocommit to off 显式关闭。
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。