嵌入式SQL语言imp文档格式.docx
《嵌入式SQL语言imp文档格式.docx》由会员分享,可在线阅读,更多相关《嵌入式SQL语言imp文档格式.docx(184页珍藏版)》请在冰豆网上搜索。
![嵌入式SQL语言imp文档格式.docx](https://file1.bdocx.com/fileroot1/2022-11/23/e473115f-4d59-48d1-b961-45724d3bb5d3/e473115f-4d59-48d1-b961-45724d3bb5d31.gif)
3.4.2动态游标55
3.4.3SQLDA55
第四节ORACLE数据库的嵌入SQL语言66
4.1基本的SQL语句66
4.1.1宿主变量和指示符66
4.1.2查询68
4.1.3修改数据68
4.1.4游标68
4.2嵌入PL/SQL71
4.3动态SQL语句72
4.3.1ORACLE动态SQL语句的一些特点72
4.3.2使用动态SQL的四种方法72
4.3.3SQLDA75
第五节INFORMIX的嵌入SQL/C语言89
5.1一个简单的入门例子89
5.2宿主变量91
5.3嵌入SQL的处理过程96
5.4动态SQL语言96
5.4.1SQLDA97
第六节MicrosoftSQLServer7嵌入式SQL语言105
6.1一个嵌入SQL语言的简单例子105
6.2嵌入SQL的处理过程106
6.3嵌入SQL语句112
6.3.1声明嵌入SQL语句中使用的C变量112
6.3.2连接数据库115
6.3.3数据的查询和修改115
6.3.4游标的使用116
6.3.5SQLCA117
6.3.6WHENEVER118
6.4动态SQL语句119
6.4
.1动态修改119
6.4.2动态游标120
6.4.3SQLDA122
6.4.4DESCRIBE语句130
6.5API130
第六章嵌入式SQL(E-SQL)简介
SQL是一种双重式语言,它既是一种用于查询和更新的交互式数据库语言,又是一种应用程序进行数据库访问时所采取的编程式数据库语言。
SQL语言在这两种方式中的大部分语法是相同的。
在编写访问数据库的程序时,必须从普通的编程语言开始(如C语言),再把SQL加入到程序中。
所以,嵌入式SQL语言就是将SQL语句直接嵌入到程序的源代码中,与其他程序设计语言语句混合。
专用的SQL预编译程序将嵌入的SQL语句转换为能被程序设计语言(如C语言)的编译器识别的函数调用。
然后,C编译器编译源代码为可执行程序。
各个数据库厂商都采用嵌入SQL语言,并且都符合ANSI/ISO的标准。
所以,如果采用合适的嵌入SQL语言,那么可以使得你的程序能够在各个数据库平台上执行(即:
源程序不用做修改,只需要用相应数据库产品的预编译器编译即可)。
当然,每个数据库厂商又扩展了ANSI/ISO的标准,提供了一些附加的功能。
这样,也使得每个数据库产品在嵌入SQL方面有一些区别。
本章的目标是,对所有的数据库产品的嵌入SQL做一个简单、实用的介绍。
当然,嵌入SQL语句完成的功能也可以通过应用程序接口(API)实现。
通过API的调用,可以将SQL语句传递到DBMS,并用API调用返回查询结果。
这个方法不需要专用的预编译程序。
1.1嵌入SQL程序的组成元素
我们以IBM的DB2嵌入SQL为例,来看看嵌入SQL语句的组成元素。
例1、连接到SAMPLE数据库,查询LASTNAME为JOHNSON的FIRSTNAME信息。
#include<
stdio.h>
stdlib.h>
string.h>
#include"
util.h"
sqlca.h>
EXECSQLINCLUDESQLCA;
(1)
main()
{
EXECSQLBEGINDECLARESECTION;
(2)
charfirstname[13];
charuserid[9];
charpasswd[19];
EXECSQLENDDECLARESECTION;
EXECSQLCONNECTTOsample;
(3)
EXECSQLSELECTFIRSTNMEINTO:
firstname(4)
FROMemployee
WHERELASTNAME='
JOHNSON'
;
(4)
printf("
Firstname=%s\n"
firstname);
EXECSQLCONNECTRESET;
(5)
return0;
}
上面是一个简单的静态嵌入SQL语句的应用程序。
它包括了嵌入SQL的主要部分:
(1)中的includeSQLCA语句定义并描述了SQLCA的结构。
SQLCA用于应用程序和数据库之间的通讯,其中的SQLCODE返回SQL语句执行后的结果状态。
(2)在BEGINDECLARESECTION和ENDDECLARESECTION之间定义了宿主变量。
宿主变量可被SQL语句引用,也可以被C语言语句引用。
它用于将程序中的数据通过SQL语句传给数据库管理器,或从数据库管理器接收查询的结果。
在SQL语句中,主变量前均有“:
”标志以示区别。
(3)在每次访问数据库之前必须做CONNECT操作,以连接到某一个数据库上。
这时,应该保证数据库实例已经启动。
(4)是一条选择语句。
它将表employee中的LASTNAME为“JOHNSON”的行数据的FIRSTNAME查出,并将它放在firstname变量中。
该语句返回一个结果。
可以通过游标返回多个结果。
当然,也可以包含update、insert和delete语句。
(5)最后断开数据库的连接。
从上例看出,每条嵌入式SQL语句都用EXECSQL开始,表明它是一条SQL语句。
这也是告诉预编译器在EXECSQL和“;
”之间是嵌入SQL语句。
如果一条嵌入式SQL语句占用多行,在C程序中可以用续行符“\”。
嵌入SQL语言,分为静态SQL语言和动态语言两类。
静态SQL语言,就是在编译时已经确定了引用的表和列。
宿主变量不改变表和列信息。
可以使用主变量改变查询参数值,但是不能用主变量代替表名或列名。
动态SQL语言就是:
不在编译时确定SQL的表和列,而是让程序在运行时提供,并将SQL语句文本传给DBMS执行。
静态SQL语句在编译时已经生成执行计划。
而动态SQL语句,只有在执行时才产生执行计划。
动态SQL语句首先执行PREPARE语句要求DBMS分析、确认和优化语句,并为其生成执行计划。
DBMS还设置SQLCODE以表明语句中发现的错误。
当程序执行完“PREPARE”语句后,就可以用EXECUTE语句执行执行计划,并设置SQLCODE,以表明完成状态。
应用程序执行时,每执行一条SQL语句,就返回一个状态符和一些附加信息。
这些信息反映了SQL语句的执行情况,它有助于用户分析应用程序的错误所在。
这些信息都存放在sqlca.h的sqlca结构中。
如果一个源文件中包含SQL语句,则必须要在源程序中定义一个SQLCA结构,而且名为SQLCA。
最简单的定义方法是在源文件中加入一些语句:
EXECSQLINCLUDEsqlca.h。
每个数据库产品都提供了SQLCA结构。
我们知道,动态SQL语句在编译时可能不知道有多少列信息。
在嵌入SQL语句中,这些不确定的数据是通过SQLDA完成的。
SQLDA的结构非常灵活,在该结构的固定部分,指明了多少列等信息,在该结构的后面有一个可变长的结构,说明每列的信息。
在从数据库获得数据时,就可以采用SQLDA来获得每行的数据。
各个数据库产品的SQLDA结构都不完全相同。
第二节SYBASESQLServer嵌入式SQL语言
2.1一个嵌入SQL语言的简单例子
我们首先来看一个简单的嵌入式SQL语言的程序(C语言):
用sa(口令为password)连接数据库服务器,并将所有书的价格增加10%。
这个例子程序如下:
例1、
/*建立通讯区域*/
Execsqlincludesqlca;
{
/*声明宿主变量*/
charuser[30],passwd[30];
EXECSQLENDDECLARESECTION;
/*错误处理*/
EXECSQLWHENEVERSQLERRORCALLerr_p();
/*连接到SQLSERVER服务器*/
printf("
\npleaseenteryouruserid"
);
gets(user);
\npassword"
gets(passwd);
execsqlconnect:
useridentifiedby:
passwd;
execsqlusepubs2;
EXECSQLupdatetitlessetprice=price*1.10;
EXECSQLcommitwork;
/*断开数据库服务器的连接*/
Execsqldisconnectall;
return(0);
/*错误处理程序*/
err_p()
\nErroroccurred:
code%d.\n%s"
\
sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
从上面这个例子,我们看出嵌入SQL的基本特点是:
1、每条嵌入式SQL语句都用EXECSQL开始,表明它是一条SQL语句。
2、如果一条嵌入式SQL语句占用多行,在C程序中可以用续行符“\”,在Fortran中必须有续行符。
其他语言也有相应规定。
3、每一条嵌入SQL语句都有结束符号,如:
在C中是“;
”。
4、嵌入SQL语句的关键字不区分大小写。
5、可以使用“/*….*/”来添加注释。
也可以使用“--”来添加注释。
2.2嵌入SQL的处理过程
嵌入SQL的处理过程如下图所示:
宿主语言程序
OpenClient嵌入SQL预编译器
嵌入SQL源程序
Openclient
Client-library
C编译器
可执行程序
连接器
目标代码
图6-1SYBASESQLSERVER嵌入SQL程序处理过程
嵌入SQL程序的后缀为.cp。
嵌入SQL处理的第一步是预编译。
预编译器(cpre.exe)处理过程分为两个小步:
第一小步:
语法分析。
检查嵌入SQL语句的语法正确性。
第二小步:
增加一些预编译器变量,并注释了所有的嵌入的SQL语句,将嵌入SQL语句转换为对client-library中函数的调用(注意:
在连接时,编译后的代码需要使用client-library中的库文件)。
如果在编译时,设置一些选项,则生成存储过程。
预编译后可能产生3个文件:
一个C文件(肯定产生),一个列表文件(需要在编译时设置选项,才能产生)和一个isql脚本文件(需要在编译时设置选项,才能产生)。
列表文件包含了输入文件的源语句和一些警告信息和错误信息。
Isql脚本文件包含了预编译器产生的存储过程脚本文件。
这个存储过程是用T-SQL写的。
总之,预编译器的处理方法是,注释了嵌入的SQL语句,用一些特定的函数代替。
第二步是C源程序的编译和链接。
cl是编译和链接命令的集成命令,编译的结果是产生.obj,在链接时,将C的系统库和SQLServer提供的库文件同目标文件连接在一起。
最后生成.exe。
也可以使用SETLIB语句设置库文件的环境信息。
2.3嵌入SQL语句总览
除了print、readtext和writetext外,大多数的Transact-SQL语句都可以在嵌入SQL中使用。
嵌入SQL语句的语法为:
“execsql[atconnection_name]sql_statement;
”。
那么,你可以用Transact-SQL语句来替代sql_statement就可以完成嵌入SQL的编写。
(同T-SQL相比,嵌入SQL提供了:
自动数据类型转换、动态SQL、SQLCA数据结构等功能。
)
但是,也有一些嵌入式SQL所特有的语句,有些嵌入式SQL语句的名字同Transact-SQL语句相同,但是语句的语法有所不同。
嵌入SQL语句应该包含五个步骤:
1)、通过SQLCA建立应用程序和SQLSERVER的SQL通信区域。
2)、声明宿主变量。
3)、连接到SQLSERVER。
4)、通过SQL语句操作数据。
5)、处理错误和结果信息。
嵌入式SQL语句分为静态SQL语句和动态SQL语句两类。
下面我们按照功能讲解这些语句。
本节讲解静态SQL语句的作用。
动态SQL语句将在下一节讲解。
同动态SQL相关的一些语句也在下一节中讲解。
2.3.1宿主变量
1)、声明方法
宿主变量(hostvariable)就是在嵌入式SQL语句中引用主语言说明的程序变量(如例中的user[31]变量)。
如:
charuser[31],passwd[31];
…………
execsqlconnect:
………….
在嵌入式SQL语句中使用主变量前,必须采用BEGINDECLARESECTION和ENDDECLARESECTION之间给主变量说明。
这两条语句不是可执行语句,而是预编译程序的说明。
主变量是标准的C程序变量。
嵌入SQL语句使用主变量来输入数据和输出数据。
C程序和嵌入SQL语句都可以访问主变量。
另外,在定义宿主变量时也可以使用client-library定义的数据类型,如:
CS_CHAR。
这些定义存放在cspublic.h文件中。
CS_CHARuser[30],passwd[30];
client-library定义的数据类型共有:
CS_BINARY、CS_BIT、CS_BOOL、CS_CHAR、CS_DATETIME、CS_DATETIME4、CS_DECIMAL、CS_FLOAT、CS_REAL、CS_IMAGE、CS_INT、CS_MONEY、CS_MONEY4、CS_NUMERIC、CS_RETCODE、CS_SMALLINT、CS_TEXT、CS_TINYINT、CS_VARBINARY、CS_VARCHAR、CS_VOID。
为了便于识别主变量,当嵌入式SQL语句中出现主变量时,必须在变量名称前标上冒号(:
)。
冒号的作用是,告诉预编译器,这是个主变量而不是表名或列名。
不能在声明时,初始化数组变量。
由上可知,SYBASESQLSERVER使用宿主变量传递数据库中的数据和状态信息到应用程序,应用程序也通过宿主变量传递数据到SYBASE数据库。
根据上面两种功能,宿主变量分为输出宿主变量和输入宿主变量。
在SELECTINTO和FETCH语句之后的宿主变量称作“输出宿主变量”,这是因为从数据库传递列数据到应用程序。
execsqlbegindeclaresection;
CS_CHARid[5];
execsqlenddeclaresection;
execsqlselecttitle_idinto:
idfromtitles
wherepub_id="
0736"
andtype="
business"
除了SELECTINTO和FETCH语句外的其他SQL语句(如:
INSERT、UPDATE等语句)中的宿主变量,称为“输入宿主变量”。
这是因为从应用程序向数据库输入值。
CS_CHARid[7];
CS_CHARpublisher[5];
...
execsqldeletefromtitleswheretitle_id=:
id;
execsqlupdatetitlessetpub_id=:
publisher
wheretitle_id=:
另外,也可以通过宿主变量获得存储过程的执行状态信息。
CS_SMALLINTretcode;
execsqlbegintransaction;
execsqlexec:
retcode=update_proc;
if(retcode!
=0)
execsqlrollbacktransaction;
也可以通过宿主变量获得存储过程的返回值。
execsqlexeca_proc:
par1out,:
par2out;
2)、主变量的数据类型
SYBASESQLSERVER支持的数据类型与程序设计语言支持的数据类型之间有很大差别。
这些差别对主变量影响很大。
一方面,主变量是一个用程序设计语言的数据类型说明并用程序设计语言处理的程序变量;
另一方面,在嵌入SQL语句中用主变量保存数据库数据。
所以,在嵌入SQL语句中,必须映射C数据类型为合适的SQLServer数据类型。
必须慎重选择主变量的数据类型。
在SQLSERVER中,预编译器能够自动转换兼容的数据类型。
请看下面这个例子:
EXECSQLBEGINDECLARESECTION;
inthostvar1=39;
char*hostvar2="
telescope"
floathostvar3=355.95;
EXECSQLUPDATEinventory
SETdepartment=:
hostvar1
WHEREpart_num="
4572-3"
SETprod_descrip=:
hostvar2
SETprice=:
hostvar3
在第一个update语句中,department列为smallint数据类型(integer),所以应该把hostvar1定义为int数据类型(integer)。
这样的话,从C到SQLServer的hostvar1可以直接映射。
在第二个update语句中,prod_descip列为varchar数据类型,所以应该把hostvar2定义为字符数组。
这样的话,从C到SQLServer的hostvar2可以从字符数组映射为varchar数据类型。
在第三个update语句中,price列为money数据类型。
在C语言中,没有相应的数据类型,所以用户可以把hostvar3定义为C的浮点变量或字符数据类型。
SQLServer可以自动将浮点变量转换为money数据类型(输入数据),或将money数据类型转换为浮点变量(输出数据)。
注意的是,如果数据类型为字符数组,那么SQLServer会在数据后面填充空格,直到填满该变量的声明长度(CS_CHAR数据类型除外)。
下表列出了C的数据类型和SQLSERVER数据类型的一些兼容关系:
可兼容的C数据类型
分配的SQLServer数据类型
SYBASE提供的数据类型
描述
short
Smallint
CS_SMALLINT
2字节整数
Int
Long
CS_INT
4字节整数
Float
Real
CS_REAL
4字节浮点数
Double
CS_FLOAT
8字节浮点数
Char
Carchar[X]
VARCHAR
CS_CHAR
字符数据类型
Unsignedchar
Binary
Varbinary
CS_BINARY
Binary数据类型
Unsignedchar
tinyint
CS_TINYINT
1字节整数
无
Datetime
CS_DATETIME
8字节datetime类型
Smalldatetime
CS_DATETIME4
4字节datetime类型
Decimal
CS_DECIMAL
Decimal数据类型
numeric
CS_NUMERIC
Numeric数据类型
Money
CS_MONEY
8字节money类型
smallmoney
CS_MONEY4
4字节money类型
Text
CS_TEXT
文本数据类型
image
CS_IMAGE
图象数据类型
boolean
CS_BIT
Bit数据类型
因为C没有date或time数据类型,所以SQLServer的date或time列将被转换为字符。
缺省情况下,使用以下转换格式:
mmddyyyyhh:
mm:
ss[am|pm]。
你也可以使用字符数据格式将C的字符数据存放到SQLServer的date列上。
你也可以使用Transact-SQL中的convert语句来转换数据类型。
SELECTCONVERT(char,