5.1.3 嵌入式SQL

5.1.3 嵌入式SQL

SQL标准定义了嵌入SQL到许多不同的语言中,例如C、C++、 CobolPascalJavaPL/IFortran

宿主语言

SQL查询所嵌入的语言被称为宿主语言,

嵌入是SQL

宿主语言中使用的SQL结构被称为嵌入式SQL.

使用宿主语言写出的程序可以通过嵌入式SQL的语法访问和修改数据库中的数据。

嵌入式SQLJDBCODBC的主要区别

一个使用嵌入式SQL的程序在编译前必须先由一个特殊的预处理器进行处理。嵌入的SQL请求被宿主语言的声明以及允许运行时刻执行数据库访问的过程调用所代替。然后,所产生的程序由宿主语言编译器编译。这是嵌入式SQLJDBCODBC的主要区别。

  • JDBC中,SQL语句是在运行时被解释的(即使是利用预备语句特性对其进行准备也是如此)
  • 当使用嵌入式SQL时,一些SQL相关的错误(包括数据类型错误**)可以在编译过程中被发现**。

EXEC SQL语句

为使预处理器识别嵌入式SQL请求,我们使用EXEC SQL语句,格式如下

1
EXEC SQL<嵌入式SQL语句>;

嵌入式SQL语法依赖于宿主语言

嵌入式SQL的确切语法依赖于宿主语言。例如,当宿主语言是Cobol时,语句中的分号用END-EXEC来代替。

嵌入式SQL的相关的东西先省略,这里了解一下即可,后面用到再说.

我们在应用程序中合适的地方插入SQL INCLUDE SQLCA语句,表示预处理器应该在此处插入特殊变量以用于程序和数据库系统间的通信。

在执行任何SQL语句之前,程序必须首先连接到数据库。这是用下面语句实现的:

1
EXEC SQL connect to server user user-name using password;

这里, server标识将要建立连接的服务器。
在嵌入的SQL语句中可以使用宿主语言的变量,不过前面要加上冒号(:)以区别于SQL变量。如此使用的变量必须声明在一个DECLARE区段里,见下面的代码。不过声明变量的语法还是因循宿主语言的惯例。

1
2
3
EXEC SQL BEGIN DECLARE SECTION;
int credit amount;
EXEC SQL END DECLARE SECTION;

嵌入式SQL语句的格式和本章描述的SQL语句类似。但这儿要指出几点重要的不同之处。
为了表示关系査询,我们使用声明游标(declare cursor)语句。然而这时并不计算查询的结果,而程序必须用openfetch语句(本章后面将讨论)得到结果元组。接下来我们将看到,使用游标的方法与JDBC中对结果集的迭代处理是很相似的。
考虑我们使用的大学模式。假设我们有一个宿主变量credit_amount,声明方法如前所见,我们想找出学分高于credit_amount的所有学生的名字。我们可写出查询语句如下:

1
2
3
4
EXEC SQL declare c cursor for
select ID,name
from student
where tot_cred >:credit_amount;

上述表达式中的变量c被称为该查询的游标(cursor)。我们使用这个变量来标识该查询,然后用open语句来执行查询。
我们的例子中的open语句如下:

1
EXEC SQL open c;

这条语句使得数据库系统执行这条查询并把执行结果存于一个临时关系中。当open语句被执行的时候,宿主变量(credit_amount)的值就会被应用到查询中。
如果SQL查询出错,数据库系统将在SQL通信区域(SQCA)的变量中存储一个错误诊断信息。
然后我们利用一系列的fetch语句把结果元组的值赋给宿主语言的变量。 fetch语句要求结果关系的每一个属性有一个宿主变量相对应。在我们的查询例子中,需要一个变量存储I的值,另一个变量存储name的值。假设这两个变量分别是sisn,并且都已经在DECLARE区段中被声明。那么以下语句:

1
EXEC SQL fetch c into:si,:sn;

产生结果关系中的一个元组。接下来应用程序就可以利用宿主语言的特性对sisn进行操作了。
条单一的feth请求只能得到一个元组。如果我们想得到所有的结果元组,程序中必须包含对所有元组执行的一个循环。嵌入式SoL为程序员提供了对这种循环进行管理的支持。虽然关系在概念上是一个集合,查询结果中的元组还是有一定的物理顺序的。执行SQLopen语句后,游标指向结果的第一个元组。执行一条fetch语句后,游标指向结果中的下一个元组。当后面不再有待处理的元组时,