1、第一章 Informix简介Informix提供了为开放系统开发和实现信息管理应用先进产品。核心产品涉及应用开发和应用工具,数据库服务器以及中间件。所有产品都基于ANSI原则SQL。INFORMIX-OnLine:迅速容错服务器,可以进行联机事务解决方面应用;INFORMIX-OnLine是Informix高性能、容错、OLTP数据库服务器。OnLine容许在数据库字段中存储和使用二进制大对象(BLOBs),从而扩展了数据解决使之可以解决多媒体信息。它还容许分布式数据库应用。INFORMIX-SE:低维护服务器,合用于中、小规模应用环境;INFORMIX-SE服务器合用于需要多顾客数据库服务器
2、环境,但是高可用性(availability)和OLTP级别性能不是核心。它合用环境是多顾客共享数据库,运营中、小规模应用。INFORMIX-SE基于事实上工业原则UNIX文献访问办法,即Informix C-ISAM。Informix产品使用双进程体系构造,它把顾客前端应用代码和后端数据库服务器隔离。应用开发工具或客户端,提供构建和运营应用程序顾客接口。数据库服务器,进行所有数据解决工作,涉及数据存储和检索。工业原则SQL用于传送从客户端应用到Informix服务器数据祈求。在双进程体系构造中,客户机和服务器可以位于同一台机器上或是通过网络相连接不同机器上。当两个进程运营于不同机器上时,称之
3、为客户机/服务器体系构造。上图表达Informix产品如何构成双进程体系构造。客户机/服务器体系构造有几种长处:l 性能隔离前端和后端进程,使得可觉得特定任务来优化软、硬件。l 灵活性使用双进程体系构造,前端开发工具可以合用于不同Informix服务器。这样做,可以使顾客选取最适合于自己应用环境服务器。从长远观点来看,开放式体系构造使得来自于不同厂商前端开发工具和服务器可以协同工作。l 节约费用可以选取适合于应用程序规模硬件,从而达到最优性能/价格比。l 可移植性应用程序易于移植到不同机器上。第二章INFORMIX-ESQL/C简介INFORMIX-ESQL/C是一种应用开发工具,它使得构建应
4、用程序C程序员拥有一种访问Informix数据库接口。开发人员使用库、头文献和预编译器来直接在C程序中嵌入SQL语句。INFORMIX-ESQL/C具备众多组织成库形式例程来协助顾客l 使用所有SQL数据类型l 解释状态消息l 使用Informix子进程INFORMIX-ESQL/C有时简称为ESQL/C在使用ESQL/C之前,必要设立好下面环境变量:INFORMIXDIRINFORMIX- ESQL/C所位于目录PATH执行程序搜索途径顾客可以在系统提示符下或在.profile( B shell )文献或 .login( C shell )文献中设立这些变量。如果是在系统提示符下设立环境变量
5、,则顾客每次登录时要重新设立它们。如果是在 .profile或 .login文献中设立,则顾客每次登录时,环境变量会自动被设立。使用Bourne shell时,设立环境变量如下:INFORMIXDIR=usr/informix/;export INFORMIXDIRPATH=$INFORMIXDIR/bin:$PATH; exportPATH使用C shell时,设立如下:setenv INFORMIXDIR /usr/informixsetenv PATH $INFORMIXDIR/bin:$PATH当顾客运营INFORMIX-OnLine时,还应当把环境变量SQLEXEC设立为$INFOR
6、MIXDIR/lib/sqlturbo,把环境变量TBCONFIG设立为适当值。运营INFORMIX-NET、INFORMIX-STAR或INFORMIX-OnLine时,也许尚有其他环境变量需要设立。ESQL/C预解决器ESQL/C一种重要部件就是它预解决器。预解决器在把C源代码送给C编译器解决之前,把ESQL/C代码转换成C代码。预解决命令从命令行启动,启动时可以有各种不同参数来阐明源文献、预期成果文献,等等。ESQL/C预解决器将在其他章节里详细讨论。在本培训手册中,预解决器名字为esql。ESQL/C带了一种示例数据库stores5,该数据库中存储是一种虚构运动器材批发商关于信息。当示
7、例数据库被创立时,使用ESQL/C示例源代码也随之被创立。在练习使用ESQL/C之前,顾客应当建立自己stores5数据库拷贝。1.创立一种子目录,用来存储ESQL/C例子源文献,输入如下:%mkdir demo%cd demo确信DbName是唯一。2.当前,输入下面命令(输入时,把DbName替代成你所使用stores5数据库名):%esqldemo5 DbName当顾客使用自己stores5数据库拷贝时,可以进行任意修改。如果顾客想刷新数据库拷贝,只要再次运营esqldemo5,将删除既有数据库拷贝,并按初始情形下创立一种新数据库拷贝。Informix产品提供了一种示例数据库stores
8、5,顾客可以在系统提示符下输入dbaccessdemo5来创立该数据库。附注顾客可以输入dbaccessdemo5 name,以其他名字来创立stores5数据库系统提供几种数据类型如下:CHAR存储字母、数字和符号任意组合。NUMBER存储五种数值数据类型中某种数值。SERIAL存储由INFORMIX-SQL赋值持续整数。DATE存储日期。MONEY存储钞票数额。DATE-TIME存储日期和时间。INTERVAL存储表达一段时间值。VARCHAR存储可变长度字符数据,仅使用必要磁盘空间。TEXT一种二进制大对象(BLOB),事实上它可以存储任何种类文本数据。TEXT字段普通存储备忘录、手稿、
9、商业文档,等等。BYTE一种二进制大对象(BLOB),它以一种无区别字节流形式来存储任意种类二进制数据,普通是保存电子表格、程序装载模块、数字化声音模板,等等。附注:VARCHAR、TEXT和BYTE数据类型仅在使用INFORMIX-OnLine时才有。要获取同数据类型关于更多信息,请查阅The Informix Guide to SQL:Reference。第三章在INFORMIX-ESQL/C程序中嵌入SQL语句在C程序中嵌入SQL语句时,要记住下面规则:l 为预编译器指明SQL语句在SQL语句之前用美元符号($)或ANSI原则核心字EXEC SQL来标明。尽管顾客可以在C代码中混用这两种
10、标注办法,但是,为了便于维护,普通不推荐这样做。此外,不要忘掉在SQL语句最后加上分号( ;)。l SQL语句可以有变量,变量可以出当前交互式SQL语句中常数可以浮现任何位置。这种在可执行SQL语句中变量称为宿主变量(host variable),将在背面讨论它。l 可以在可以使用C可执行语句任何地方使用可执行SQL语句。宿主变量,即是C语言中普通变量,它们可以出当前交互式SQL语句中常数所在任何位置上。当在SQL语句中使用宿主变量时,必要把它们同SQL语句中名称相区别,这样做使得预编译器可以辨认出哪些标记符是宿主变量。为从嵌入式SQL语句中区别出宿主变量,给宿主变量加上美元符号($)作前缀。
11、如果顾客乐意话,也可以使用ANSI原则中规定分号( :)来作前缀。(在本手册中,咱们将使用美元符号来作标记。)这里是某些例子:l UPDATE语句中SET子句,如$update stock set unit_price = $NewPriceLd;l INSERT语句中VALUES子句,如$insert into stock values( $StockG_t );l UPDATE、DELETE和SELECT语句中WHERE子句,例如:$update stock .where manu_code = $MfcodeLc;$delete from orders where order_num =
12、 $OrdNoLl;宿主变量是普通C变量。既然它们是普通C变量,必要把它们阐明和定义成某种类型,就象任何别C变量同样。宿主变量可以定义为这些类型中任何一种l 简朴类型象integer,double,等等。l 构造l 数组象其他C变量同样,可以在定义宿主变量时候初始化它们。但是,由于ESQL/C预编译器要在编译SQL语句之前懂得宿主变量存在和类型,因此必要为预编译器标明宿主变量定义。可以使用美元符号($)作为定义前缀来为预编译器标明宿主变量定义,或者,把定义某些用下面这对语句括起来EXEC SQL BEGIN DECLARE SECTIONEXEC SQL END DECLARE SECTION
13、关于宿主变量和它们引用有几点其他因素需要考虑。宿主变量和SQL数据库对象(数据库、表、字段、约束、过程,等等)可以同名,虽然是在同一种SQL语句中。例如,下面语句是对的$update customer set zipcode = $zipcodewhere customer_num = $customer_num;esql预编译器区别字母大小写,即对字母大小写敏感。例如,下面两个宿主变量是不同,它们访问是不同内存$char manuCodeC44;$char manucodec44最后,任何使用$为前缀来定义变量都可以在原则C表达式中使用。例如,下面gets()对宿主变量引用是合法$char
14、DBNameC1111;gets(DBNameC11);$database $DBNameC11;当SQL语句之外使用宿主变量时,不能以$为前缀来引用,否则,C编译器编译时报错。当数据从数据库中取出,送到一种ESQL/C应用程序时,获得数据应存储到与SQL数据类型兼容数据类型中。同样,当数据从应用程序存储到数据库中时,数据类型也应当兼容。如果顾客没有阐明兼容宿主变量类型,有些情形可以进行自动类型转换;如果无法转换,则返回一种错误信息。当接受数据区太小时,如果丢失是有效数字,则返回错误,如果是字符,则返回警告信息。检测和解决这些错误和警告将在其他章节中讨论。上图列出了SQL数据类型和它们相应C宿
15、主变量类型。CHAR、SMALLINT、INTEGER、SMALLFLOAT、FLOAT、SERIAL和DATE这些SQL数据类型均有相相应C数据类型。但是,DECIMAL、MONEY、DATETIME、INTERVAL和VARCHAR必要定义特别ESQL/C数据类型来与之相相应。后续章节将全面地描述这些数据类型。ESQL/C在宿主变量定义时支持类似Ctypedef表达式,如上面所示。但是,它们必要以$符号为前缀,ESQL/C不解决没有$符号为前缀typedef语句。在上面例子中,$typedef创立了一种SMALLINT类型来作为短整型(short int)使用,然后再定义一种StockNu
16、mLs变量,类型为SMALLINT。本例用同样办法定义了长整型(long int)等价SQL数据类型DATE。不能使用$typedef来把多维数组或联合(union)定义成宿主变量类型。使用Ctypedef表达式时要小心,由于esql不会展开它们。可以把构造定义为INFORMIX-ESQL/C宿主对象。上例把stock_t定义为一种构造模板,然后,使用该模板定义了两个构造变量StockG_t和ItemG_t。可以使用嵌套构造。在可执行SQL语句中,可以把构造作为一种整体来使用或引用它任一某些。当把构造作为整体来使用时,INFORMIX ESQL/C预编译器把构造引用展开成对它各个某些引用列表。
17、例如:$insert into stock(stock_num,manu_code)values($StockG_t);等价于$insert into stock(stock_num,manu_code)values($StockG_t.StockNumS,$StockG_t.ManuCodeC);可以把数组定义为INFORMIX-ESQL/C宿主对象。上例把BufLapc定义为一种字符指针数组,并且,它还把UnitSal定义为一种长整型数组。在定义数组时,必要使用一种整形值来阐明数组大小。在可执行SQL语句中,可以l 引用数组任何一种元素。l 对于CHAR类型数组,可以仅引用数组名。l 对于
18、其他类型数组,不能仅引用数组名。在定义宿主变量时,可以使用普通C初始化表达式来进行初始化。但是,对于字符类型表达式有一种例外:字符串不能有l 分号INFORMIX-ESQL/C核心字预编译器不检查C语法对的性;它只是把初始化表达式传递给C编译器,由C编译器来检查此类错误。关于宿主变量作用域范畴规定同普通C变量同样。l 宿主变量是automatic(局部),除非显式地定义为external或static。l 在一种函数中定义宿主变量对于该函数来说是局部。l 函数中局部宿主变量使得定义在函数外部同名变量不可见。l 在同一种模块中不能多次定义同一种宿主变量。为保证局部宿主变量对于它所定义块(bloc
19、k)来说是局部,使用一对组合符号 $ 和 $ 来开始和结束块。ANSI原则不支持 $ 和 $ ,在5.0版中可以使用简朴括弧对, 和 。块最多可以嵌套16层。INFORMIX-ESQL/C提供了许多头文献。(参见上面列表。)这些文献中定义了许多对象,顾客程序也许会用到它们。这些文献位于$INFORMIXDIR目录子目录incl/esql下。每一种头文献将在后续适当章节讨论。可以在程序中包括进一种或各种头文献来简化编程,例如,下面这条语句包括进sqlca头文献不要使用include$include sqlca;在程序中包括进sqlca头文献,可以发现诸如数据库服务器执行SQL语句与否成功,等等。
20、当预编译器看到$include,它将读入文献sqlca.h,并把它插入到顾客代码中。在后续某章中,你将看到如何使用该头文献中某些构造来检测SQL语句执行状态。$include在其他章节中讨论。在访问数据库表和给表添加记录之前,必要激活表所在数据库。为激活一种数据库使它成为当前打开数据库,使用DATABASE语句DATABASE必须核心字DatabaseName想要选取数据库名字DatabaseName可以是一种指明数据库标记符、一种存有数据库名字字符串或指向这样一种字符串指针。当为INFORMIX-SE阐明数据库时,如果该数据库既不在当前目录也不在DBPATH环境变量所阐明目录,则必要在DAT
21、ABASE核心字之后跟上一种字符串常数或一种宿主变量,该变量存储是数据库完整途径名(不涉及.dbs后缀)。使用CLOSE DATABASE语句来关闭当前数据库。CLOSE DATABASE是必须核心字在头一种例子中stores是数据库名。如果使用是INFORMIX-OnLine,则该数据库在由环境变量TBCONFIG指明OnLine当前实例中。如果使用是INFORMIX-SE,则该数据库位于当前目录或DBPATH环境变量中存储目录。在第二个例子中,stores5是数据库名。该数据库既不在当前目录也无法通过DBPATH环境变量来访问。宿主变量DbNameLc80中存储是数据库完整途径,途径由st
22、copy函数拷贝到变量中。尽管可以这样做,但是,在程序中通过编程来获取一种完整途径名并不是一种好作法。-第四章编译INFORMIX-ESQL/C程序当使用INFORMIX-ESQL/C预编译器来预解决源文献时,它把所标明SQL语句转换成C代码。固然,要使用$符号作前缀或用EXEC SQL核心字把SQL语句涉及起来,给预编译器指明SQL语句存在。INFORMIX-ESQL/C仅当源文献具备“.ec”后缀时才作此类转换。INFORMIX-ESQL/C把编译成果存储到与源文献同名但后缀是“.c”一种文献中。例如,预编译myfile.ec产生文献myfile.c,源文献内容myfile.ec不变。IN
23、FORMIX-ESQL/C有取舍地把新产生C代码送给C编译器解决。-顾客可以在自己程序中包括进其他源文献。例如,你或许想把所有全局变量定义放到一种源文献中,然后,通过一种预编译指令把它们自动包括进来。如果该源文献不包具有SQL语句,则可以使用原则C预编译语句#include。INFORMIX-ESQL/C预编译器忽视所有#include语句。但是,如果要包括文献中有SQL语句,必要使用下面INFORMIX-ESQL/C预编译语句之一,把filename替代成要包括文献名字$include filename;exec sql include filename;在上图中,INFORMIX-ESQL
24、/C预编译器在当前目录中查找,并读入pgm_global包括文献。使用这种方式来包括文献最多可达八层。在$INFORMIXDIR/incl/esql目录中有九个头文献,可以在INFORMIX-ESQL/C源文献中使用它们-预编译器查找$include语句中文献名时,按下面顺序来查找目录:1. 当前目录2. $INFORMIXDIR/incl/esql目录3. /usr/include目录如果找到文献话,就把文献内容插入到当前文献include语句处。如果filename是途径名,则必要把途径名用双引号括起来。-可以在INFORMIX-ESQL/C代码中使用下面条件编译语句$define把编译时某个值赋予一种名字。$undef取消定义名字。$ifdef检测名字与否存在,如果存在话,解决后续语句。$ifndef检测名字与否存在,如果不存在话,解决后续语句。$elseif进入$ifdef或$ifndef条件else某些,并检测另一种$ifdef。$else进入$ifdef或$ifndef条件else某些。$endif结束$ifdef或$ifndef条件。在上例中,可以看到有一条SQL语句被嵌入到$ifdef语句。如果使用原则C预编译指令#ifdef,则无法完毕这项工作。$define语句仅能定义符号或整常数,不支持字符串常数或参数宏定义-