然后预编译器对文件处理一遍,一边读输入文件,一边输出到输出文件.通常它只是把不加分析的把所有东西输出到输出文件里去.
当处理到 EXEC SQL 语句时,预编译器对之进行处理并根据语句做相应的改变.EXEC SQL 语句可以是下列之一:
定义段以
exec sql begin declare section;开头,以
exec sql end declare section;结束.在定义段里只允许变量定义.这个段里定义的每个变量同时也放到一个以变量名和对应类型为索引的变量列表里头.
特别是结构(struct)或者联合(union)的定义同样必须在定义段里面列出。否则ecpg 就不能处理这些类型,因为它不知道定义(是什么)。
定义同时也输出到文件里把这些变量作为通常的 C-变量.
特殊的类型 VARCHAR 和 VARCHAR2 的每个变量都被转换成一个命名结构.一个下面这样的定义:
VARCHAR var[180];被转换成
struct varchar_var { int len; char arr[180]; } var;
一个包含语句看起来象:
exec sql include filename;注意这个与下面这行
#include <filename.h>是不一样的。被包含的文件由 ecpg 本身分析。因此声明的头文件被包括在生成的 C 代码里。这样你也能够在一个头文件里声明 EXEC SQL 语句。
一个联接语句看起来象:
exec sql connect to connection target;它创建与指定数据库的联接。
connection target (联接目标)可以用下面的方法声明:
一个断开语句看起来象:
exec sql disconnect [connection target];它关闭与指定数据库的联接。
connection target 可以用下面方法声明:
一个打开游标语句看起来象:
exec sql open cursor;它被忽略因而不拷贝到输出文件.
一个提交语句看起来象
exec sql commit;它被转换成输出
ECPGcommit(__LINE__);
一个回卷语句看起来象
exec sql rollback;它被转换成如下输出
ECPGrollback(__LINE__);
当一个符号以冒号(:)开头时,就会发生变量替换.然后就会到前面定义段里(生成)的变量列表里找出该名称的变量,然后根据该变量是用于输入还是输出,把指向该变量的指针写到输出里供函数访问使用.
对 SQL 请求里的每个变量,函数都得到另外十个参数:
作为特殊符号的类型。 |
指向数值或指针的指针。 |
如果变量是 varchar 或者 char,变量的尺寸。 |
数组里的元素个数(对数组抓取)。 |
数组里下一个元素的偏移量(对数组抓取) |
做为特殊符号的标识器变量的类型。 |
一个指向标识器变量值或者标识器变量指针的指针。 |
0. |
标识器数组里的元素个数(对数组抓取)。 |
标识器数组里下一个元素的偏移量(对数组抓取)。 |
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"
待续:描述其他入口的位置.