Chinaunix首页 | 论坛 | 博客
  • 博客访问: 103402133
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类: DB2/Informix

2008-03-20 21:21:42

作者:nesad  出处:hi.baidu.com   

5.1 一个简单的入门例子
例1、查询customer表中所有lname的第一个字符小于C的顾客信息。
#include 
/*定义两个常量*/
EXEC SQL define FNAME_LEN 15;
EXEC SQL define LNAME_LEN 15;
main()
{
/*声明宿主变量*/
EXEC SQL BEGIN DECLARE SECTION;
char fname[ FNAME_LEN + 1 ];
char lname[ LNAME_LEN + 1 ];
EXEC SQL END DECLARE SECTION;
printf( "DEMO1 Sample ESQL Program running.\n\n");
/*出错处理,如果返回错误信息,则停止该程序*/
EXEC SQL WHENEVER ERROR STOP;
/*连接到stores7数据库*/
EXEC SQL connect to 'stores7';
/*声明一个游标*/
EXEC SQL DECLARE democursor cursor for
select fname, lname
into :fname, :lname
from customer
where lname < 'C';
/*打开游标*/
EXEC SQL open democursor;
/*如果SQLSTATE不等于“00”,那么表示到达了数据集的尾部(02),或者产生了错误(大于02)*/
for (;;)
{
EXEC SQL fetch democursor;
if (strncmp(SQLSTATE, "00", 2) != 0)
break;
printf("%s %s\n",fname, lname);
}
/*打印错误信息*/
if (strncmp(SQLSTATE, "02", 2) != 0)
printf("SQLSTATE after fetch is %s\n", SQLSTATE);
/*关闭游标*/
EXEC SQL close democursor;
/*释放游标占用的资源*/
EXEC SQL free democursor;
/*断开数据库服务器的连接*/
EXEC SQL disconnect current;
printf("\nDEMO1 Sample Program over.\n\n");
}
       从上面这个例子,我们看出嵌入SQL的基本特点是:
1、每条嵌入式SQL语句都用EXEC SQL开始,表明它是一条SQL语句。这也是告诉预编译器在EXEC SQL和“;”之间是嵌入SQL语句。
2、如果一条嵌入式SQL语句占用多行,在C程序中可以用续行符“\”,在Fortran中必须有续行符。其他语言也有相应规定。
3、每一条嵌入SQL语句都有结束符号,如:在C中是“;”。
4、嵌入SQL语句的关键字不区分大小写。
5、可以使用“/*….*/”来添加注释。
   
       从上面这个例子看出,INFORMIX数据库的嵌入SQL语句的格式同其他数据库基本相同。但是,它也有它自己本身的一些特点。本节把重点放在INFORMIX数据库所独有的一些语句或处理方式。
5.2 宿主变量
宿主变量就是在嵌入式SQL语句中引用主语言说明的程序变量。如:
EXEC SQL connect to :hostvar;  
1)、定义宿主变量
方法1:采用BEGIN DECLARE SECTION 和END DECLARE SECTION之间给主变量说明。如:
EXEC SQL BEGIN DECLARE SECTION;
char fname[ FNAME_LEN + 1 ];
char lname[ LNAME_LEN + 1 ];
EXEC SQL END DECLARE SECTION;
方法2:在每个变量的数据类型前加上“$”。如:
$int hostint;
$double hostdbl;
ESQL/C对宿主变量的大小写敏感。但是,ESQL/C的关键字、语句标志符、游标名大小写不敏感。在SQL语句中,除了使用“:”来标志宿主变量外,还可以使用“$”。当然,“:”是ANSI标准。如:EXEC SQL connect to $hostvar。对于注释,可以使用“--”,也可以使用标准的“/*…*/”。
2)、宿主变量和NULL
方法1:使用指示符变量。
方法2:使用函数risnull()和rsetnull()。
3)、指示符变量
大多数程序设计语言(如C)都不支持NULL。所以对NULL的处理,一定要在SQL中完成。我们可以使用主机指示符变量来解决这个问题。在嵌入式SQL语句中,宿主变量和指示符变量共同规定一个单独的SQL类型值。指示变量和前面宿主变量之间用一个空格相分隔。如:
EXEC SQL select lname, company
into :name INDICATOR :nameind, :comp INDICATOR :compind
      nameind是name变量的指示符,而compind是comp变量的指示符。
可以通过以下三种方法使用指示符变量:
方法1、使用INDICATOR关键字。
:hostvar INDICATOR :indvar 
方法2、
:hostvar :indvar
方法3、使用$符号。
$hostvar $indvar。
无论采用哪种方法,都是实现指示符变量的作用。即:当宿主变量hostvar应该返回NULL时,指示符变量为-1。当宿主变量hostvar应该返回不是NULL而且无需截断时,指示符变量为0。当返回值太大而需要截断时,指示符变量是截断前数据的长度。SQLSTATE会返回01004错误信息。请看下面这个例子:
EXEC SQL BEGIN DECLARE SECTION;
char name[16];
char comp[20];
short nameind;
short compind;
EXEC SQL END DECLARE SECTION;
EXEC SQL select lname, company
into :name INDICATOR :nameind, :comp INDICATOR :compind
from customer
where customer_num = 105;
       如果对应105的company为NULL,则compind小于0,如果lname的结果大于15个字节,那么name包含前15个字符。
4)、宿主变量的数据类型
      INFROMIX ESQ/C的宿主变量数据类型除了标准C的数据类型外,可以是它自己定义的数据类型。如:
lvarchar数据类型
EXEC SQL BEGIN DECLARE SECTION;
varchar varc_name[n + 1];
EXEC SQL END DECLARE SECTION;
lint8数据类型
EXEC SQL BEGIN DECLARE SECTION;
int8 int8_var1;
ifx_int8_t int8_var2;
EXEC SQL BEGIN DECLARE SECTION;
lfixchar数据类型
EXEC SQL BEGIN DECLARE SECTION;
boolean flag;
fixchar my_boolflag;
int id;
EXEC SQL END DECLARE SECTION;
lDecimal数据类型
#define DECSIZE 16
struct decimal
{
short dec_exp;
short dec_pos;
short dec_ndgts;
char dec_dgts[DECSIZE];
};
typedef struct decimal dec_t;
lDatetime数据类型
EXEC SQL include datetime;
EXEC SQL BEGIN DECLARE SECTION;
datetime year; /* will cause an error */
datetime year to day year, today; /* ambiguous */
EXEC SQL END DECLARE SECTION;
lInterval hour等数据类型
EXEC SQL BEGIN DECLARE SECTION;
interval day(3) to day accrued_leave, leave_taken;
interval hour to second race_length;
interval scheduled;
EXEC SQL END DECLARE SECTION;
l其他数据类型
EXEC SQL BEGIN DECLARE SECTION;
loc_t my_simple_lo;
EXEC SQL END DECLARE SECTION;
my_simole_lo.loc_loctype = LOCMEMORY;
l在INFORMIX数据库中,'\0'表示为NULL。如:
id = 1;
flag = '\0'; /* valid boolean assignment to FALSE */
EXEC SQL insert into table2 values (:id, :flag); /* inserts FALSE */
       在以SQL为基础的DBMS支持的数据类型与程序设计语言支持的数据类型之间有很大差别。如果你通过宿主变量从数据库取值,或者通过宿主变量向数据库插入值,都存在数据类型转换的问题。
       下表列出了C的数据类型、ESQL/C定义的数据类型和SQL数据类型的兼容关系:

SQL数据类型                 ESQL/C定义的数据类型           C的数据类型

BOOLEAN                           boolean   
BYTE                                loc_t 
CHAR(n) 
CHARACTER(n)             fixchar [n] 或string [n+1]         char [n + 1] 或 char *
DATE                                date                    4-byte integer 
DATETIME                  datetime或ordtime_t
DECIMAL                       decimal或dec_t
DEC                            decimal或dec_t
NUMERIC                       decimal或dec_t
MONEY                        decimal或dec_t 
FLOAT                                                     double
DOUBLE                                                   double
PRECISION                                                double 
INT8                       int8或ifx_int8_t 
INTEGER                                             4-byte integer
INT                                                   4-byte integer 
INTERVAL               interval or intrvl_t
LVARCHAR lvarchar                                  char [n + 1] orchar *
NCHAR(n)            fixchar [n] orstring [n+1]              char [n + 1] orchar *
NVARCHAR(m)       varchar[m+1] orstring [m+1]          char [m+1] 
SERIAL                                            4-byte integer 
SERIAL8             int8 or ifx_int8_t 
SMALLFLOAT                                               float
REAL                                                       float 
SMALLINT                                               2-byte integer 
TEXT                     loc_t 
VARCHAR(m,x)      varchar[m+1] or string [m+1]              char d[m+1] 
BLOB                   ifx_lo_t 
CLOB                   ifx_lo_t 
LIST(e)                 collection
MULTISET(e)           collection 
Opaque data type       lvarchar,fixed binary或var binary
ROW(...)                row 
SET(e)                 collection 

下表是INFORMIX数据库服务器支持的数据类型和类型代码:

SQL数据类型          类型代码         类型代码值

CHAR                SQLCHAR            0
SMALLINT            SQLSMINT           1
INTEGER             SQLINT              2
FLOAT               SQLFLOAT            3
SMALLFLOAT         SQLSMFLOAT        4
DECIMAL             SQLDECIMAL         5
SERIAL               SQLSERIAL           6
DATE                 SQLDATE             7
MONEY               SQLMONEY           8
DATETIME            SQLDTIME            10
BYTE                 SQLBYTES            11
TEXT                 SQLTEXT              12
VARCHAR             SQLVCHAR           13
INTERVAL             SQLINTERVAL        14
NCHAR               SQLNCHAR            15
NVARCHAR           SQLNVCHAR           16
INT8                 SQLINT8               17
SERIAL8             SQLSERIAL8           18
LVARCHAR            SQLLVARCHAR       43
BOOLEAN           SQLBOOL              45
SET                SQLSET                 19
MULTISET           SQLMULTISET           20
LIST                SQLLIST                 21
ROW                SQLROW                   22
Varying-length
opaqueType            SQLUDTVAR           40
Fixed-length
opaque type            SQLUDTFIXED           41
SENDRECV
(client-side only)       SQLSENDRECV           44


下表是ESQL/C定义的数据类型和类型代码,这些定义存放在各个头文件中。

ESQL/C数据类型          类型代码         类型代码值

char                     CCHARTYPE         100
short int                  CSHORTTYPE        101
int4                     CINTTYPE            102
long                     CLONGTYPE         103
float                    CFLOATTYPE         104
double                 CDOUBLETYPE        105
dec_t或decimal        CDECIMALTYPE        107
fixchar                 CFIXCHARTYPE        108
string                  CSTRINGTYPE         109
date                   CDATETYPE            110
dec_t或decimal           CMONEYTYPE        111
datetime或dtime_t         CDTIMETYPE        112
loc_t                  CLOCATORTYPE        113
varchar                   CVCHARTYPE       114
intrvl_t 或interval          CINVTYPE            115
char                      CFILETYPE           116
int8                        CINT8TYPE          117
collection (Universal
Data Option)                 CCOLTYPE           118
lvarchar                     CLVCHARTYPE       119
fixed binary                  CFIXBINTYPE        120
var binary (Universal
Data Option)              CVARBINTYPE           121
boolean                  CBOOLTYPE             122
row (Universal Data
Option)                     CROWTYPE            123

       INFORMIX的ESQL/C提供了很多函数来处理数据类型,这些函数的参数就是ESQL/C定义的数据类型。如:dectoasc()的作用是转换数据类型是decimal的值为ASCII。
5.3 嵌入SQL的处理过程
       INFORMIX的预编译器为esql。嵌入SQL包含一些组件:嵌入SQL的库文件,提供访问数据库服务器、操作各种数据类型、出错信息的处理等函数。嵌入SQL的头文件(UNIX环境:$INFORMIXDIR/incl/esql下,WINDOWS环境:%INFORMIXDIR%\incl\esql下),提供程序用的数据结构、常数和宏的定义信息。Esql是预编译器。UNIX系统下,是finderr程序获得INFORMIX的错误信息,WINDOWS平台下是find error获得错误信息。还有一些GLS locale文件,提供一些特定的locale信息。在WINDOWS平台下,还有另外一些文件,如:setnet32、ilogin、regcopy、esqlmf程序。
创建嵌入SQL/C的程序的一般步骤:程序的后缀可以是.ec或.ecp。
1、定义宿主变量。
2、访问数据库。
3、操作。
4、完成后,使用esql命令来预编译。如:esql demo1.ec。在预编译后,程序中只有C语言语句,它们都可以为C语言的编译器所识别。所以,可以按照一般的方法进行编译和连接,但在将SQL语句转换以后,在C语言程序中,又引入了许多一般的C语言系统所没有的结构、变量和函数,因此应该设置INCLUDE和LIB的设置。最后生成的可执行文件。
5.4 动态SQL语言
所谓静态SQL的编程方法,就是指在预编译时SQL语句已经基本确定,即访问的表或视图名、访问的列等信息已经确定。但是,有时整个SQL语句要到执行的时候才能确定下来,而且SQL语句所访问的对象也要到执行时才能确定。这就需要通过动态SQL语句完成。动态SQL语句的处理步骤是:
1、组合SQL语句。
2、PREPARE。PREPARE语句是动态SQL语句独有的语句。其语法为:
       PREPARE 语句名      FROM 宿主变量|字符串
该语句接收含有SQL语句串的宿主变量,并把该语句送到DBMS。DBMS编译语句并生成执行计划。在语句串中包含一个“?”表明参数,当执行语句时,DBMS需要参数来替代这些“?”。PREPRARE执行的结果是,DBMS用语句名标志编译后的语句。在执行SQL语句时,EXECUTE语句后面是这个语句名。请看下面这个例子:
       EXEC SQL prepare slct_id from 
'select company from customer where customer_num = ?';
       可以通过SQLCA检查PREPARE操作是否成功。
3、EXECUTE或OPEN。
        EXECUTE语句的语法如下:
EXECUTE 语句名 USING      宿主变量 | DEscriptOR 描述符名
它的作用是,请求DBMS执行PREPARE语句准备好的语句。当要执行的动态语句中包含一个或多个参数标志时,在EXECUTE语句必须为每一个参数提供值。这样的话,EXECUTE语句用宿主变量值逐一代替准备语句中的参数标志(“?”),从而,为动态执行语句提供了输入值。
       如果是多行查询,则使用游标,使用OPEN      USING语句传递参数;如果是单行查询,则使用SELECT INTO。如果是修改数据:则使用EXECUTE USING语句。如果知道参数个数,就可以使用宿主变量。如果不知道参数个数,则必须使用DESCRIBE语句。下表总结了动态SQL语句的处理方法:
语句类型是否有输入参数执行的方法
INSERT、DELETE、UPDATE没有EXECUTE
INSERT、DELETE、UPDATE有(数据类型和个数确定)EXECUTE …USING
INSERT、DELETE、UPDATE有(数据类型和个数不确定)EXECUTE...USINGSQL DEscriptOR或EXECUTE...USINGDEscriptOR
SELECT(返回多行)无OPEN
SELECT(返回多行)有(数据类型和个数确定)OPEN…USING
SELECT(返回多行)有(数据类型和个数不确定)OPEN...USINGSQL DEscriptOR或OPEN...USINGDEscriptOR
SELECT(返回一行)无EXECUTE...INTO
SELECT(返回一行,但是返回的数据类型和个数不确定)无EXECUTE...INTODEscriptOR或EXECUTE...INTOSQL DEscriptOR
SELECT(返回一行)有EXECUTE...INTO...USING
SELECT(返回一行,但是返回的数据类型和个数不确定)有EXECUTE...INTO...USING SQLDEscriptOR或EXECUTE...INTO...USINGDEscriptOR
阅读(1561) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~