时间:2022-11-06 18:30:02 | 来源:信息时代
时间:2022-11-06 18:30:02 来源:信息时代
嵌入式SQL : SQL语言的一种使用方式,它将SQL文本嵌入到某种特定的程序设计语言文本中构成编译单元。这种方式允许数据库应用被表达成混合形式,从而能够利用程序设计语言的过程性结构来弥补SQL语言实现复杂应用方面的不足。
有关嵌入式SQL的语法,在SQL99中由第五部分“主语言绑定”专门说明,在SQL2003中因该部分与第二部分联系非常紧密而与之合并,第五部分从此不再存在。
嵌入SQL文本的程序设计语言被称为宿主语言。SQL文本可以被嵌入到多种宿主语言文本中,目前SQL标准中指定了标准嵌入式语法的宿主语言有Ada、C、COBOL、FORTRAN、MUMPS、PASCAL和PL/I,并要求SQL实现必须至少支持其中一种。SQL文本由一个或多个嵌入SQL语句和可选的一个或多个嵌入SQL声明段构成。在嵌入SQL的宿主程序中,任何允许出现可执行的宿主语言语句的地方,都允许出现可执行的SQL语句; 任何允许出现说明性宿主语言语句的地方,都允许出现SQL声明段。SQL 声明段以 EXEC SQL BEGIN DECLARE SECTION开始,以EXEC SQL END DECLARE SECTION结束,中间可声明变量。
在使用标准程序设计语言编译器对宿主程序进行编译之前,需要对其进行预处理,将嵌入的SQL语句及宿主变量声明替换为宿主语言编译器能够识别的形式,这个过程称为预编译。为了能够区分SQL语句与宿主语言语句,标准规定所有SQL语句前都必须加上SQL前缀(如EXEC SQL),并以SQL终结符(如END-SQL)结束,但不同宿主语言的SQL前缀和终结符可能是不一样的。
SQL标准将SQL声明段中声明的变量称为宿主变量,宿主变量可以用来在程序和SQL数据之间传送数据。嵌入式SQL语句可以在任何可以放置标量表达式的地方含有宿主语言变量,但宿主变量必须前置一个冒号以同SQL对象名相区别。根据宿主变量的作用,可以将其分为输入变量、输出变量和指示符变量。输入变量用于向DBMS输入数据。输出变量用于接收从DBMS输出的数据。指示符变量是一个数值型变量,当输入输出值可能为null值时,可以在相应的宿主变量后跟随一个宿主变量。对于输入宿主变量,任何小于0的指示符值的意思是传送的值为null,而任何指示符值大于等于0的意思是传送的是一个非空值; 对于输入宿主变量,规定指示符值-1表示传送的值为null,而0表示传送的值为非空值。
SQL语言与宿主语言之间存在阻抗不匹配问题,即: SQL是在集合上操作,而宿主语言是在集合成员上操作。为解决上述问题,SQL标准提供对游标的支持。游标是对SQL数据进行操作的一种机制,通过它每次对表的一行进行操作。可以这样理解游标的作用: 游标与一个SQL查询检索到的结果表相关联,它指向结果表中的一行,并且可以在结果表的行之间移动。当游标正指向某一行,即“定位”在这一行上时,可以使用更新语句或删除语句的“定位”形式来更新或删除这一行。为使游标正常地工作,通常需要包括四个动作: 声明游标、打开游标、获取游标和关闭游标。在SQL标准中,这些功能分别由声明游标语句、打开语句、获取语句和关闭语句实现。在动态SQL方式下,还可以动态声明和操纵游标。
SQL标准还提供了一套诊断机制,使得应用程序能够获知SQL语句的执行情况。基本的诊断信息项目SQLSTATE。SQLSTATE是一个5字符变量,可以在SQL声明段中定义。在每个SQL语句之后,DBMS会将一个值(状态代码)放入SQLSTATE。状态代码由数字和字母构成。前两个数字或字母是“类”,描述状态的一般类别: 接下来的三个数字或字母是“子类”,表示进一步的状态信息。例如:类“00”表示“SUCCESS”;类“01”表示“WARNING”;类“02”表示“NO DATA”;其他类表示“ERROR”等。此外,通过获取诊断语句还可以得到更详细的语句执行信息。
以下是一个嵌入式C程序范例,该程序检索表tab_1中的列col_1,并将每一行中该列的值显示在屏幕上。
#include <stdio.h>
EXEC BEGIN DECLARE SECTION;int x; /*输出宿主变量*/
int x_indicator; /*指示符变量*/
EXEC SQL END DECLARE SECTION;
int i;
void main()
{
EXEC SQL CONNECT TO db_server USER user_1;/*连接数据库*/
EXEC SQL DECLARE cur_1 CURSOR FOR SELECT col_1 FROM tab_1;
EXEC SQL OPEN cur_1;
for(;;){
EXEC SQL FETCH cur_1
INTO :x :x_indicator;
if(!strncmp(SQLSTATE,“02000”,5))
break; /*若无返回数据,则跳出循环*/
if(x_indicator<0)printf(“NULL/n”);
else printf(“%d/n”,x);
}
EXEC SQL CLOSE cur_1;
EXEC SQL DISCONNECT db_server;
}
嵌入式SQL曾经是一种主流的数据库应用开发技术,但由于其与宿主语言间的这种接口形式通用性较差,目前已逐渐为其他的接口形式所取代。