嵌入式SQL是一种将SQL语句直接写入过程化程序设计语言(例如C语言)代码之中,使得应用程序拥有访问数据以及处理数据能力的方法。其中,将SQL语句嵌入的目标代码的语言称为宿主语言。
SQL—86规范中定义了对于COBOL、FORTRAN等语言的嵌入式SQL规范。SQL—89规范中定义了对于C语言的嵌入式SQL规范。一些大型的数据库厂商(例如Oracle、DB2等)发布的数据库产品中,都提供了对嵌入式SQL的支持。
▶4.2.1.1 工作原理与步骤
在实际的应用系统开发中,为了访问数据库,需要具体的DBMS产品提供对嵌入式SQL的支持,在技术上需要解决以下4个问题:
①宿主语言的编译器无法识别和接收SQL语句,需要将SQL的宿主语言源代码编译成可执行码;
②宿主语言程序与DBMS之间的数据传递;
④数据库与宿主语言的数据类型并不完全对应,需要进行数据类型转换。
为了解决上述这些问题,DBMS产品需要提供一个嵌入式SQL的预编译器,把包含嵌入式SQL语句的宿主语言代码转换成纯宿主语言的代码,使用对应的程序编译器进行编译。通常经过预编译后,原有的嵌入式SQL会被换成一系列函数调用。因此,还需要提供一系列函数库,以确保链接器能够对代码中的函数调用与对应的实现进行链接。最终,嵌入式SQL经过宿主语言的编译器编译和链接,形成目标语言程序(见图4-4)。
图4-4 嵌入式SQL工作步骤
▶4.2.1.2 建立和关闭数据库连接
嵌入式SQL程序要访问数据库必须先建立与数据库的连接。RDBMS根据用户信息对连接请求进行合法性验证,只有通过了身份验证才能建立可用的合法连接。
建立数据库连接的嵌入式SQL语句为:
EXEC SQL CONNECT TO〈数据库服务器〉
[AS〈数据库连接名〉][USER〈用户名〉];
其中,〈数据库服务器〉是要连接的数据库服务器标识。
关闭数据库连接的嵌入式SQL语句为:
EXEC SQL DISCONNECT[〈数据库连接名〉];
▶4.2.1.3 游标
关系数据库中的操作会对整个记录集合(也称为行集)起作用。由SELECT语句返回的行集包括满足该语句的WHERE子句中条件的所有行。这种由语句返回的完整行集称为结果集。应用程序,特别是交互式联机应用程序,并不总能将整个结果集作为一个单元来有效地处理。这些应用程序需要一种机制以便每次处理一行或一部分行。游标就是提供这种机制对结果集的一种扩展。
游标通过以下方式来扩展结果处理:
①允许定位在结果集的特定行。
②从结果集的当前位置检索一行或一部分行。
③支持对结果集中当前位置的行进行数据修改。
④为由其他用户对显示在结果集中的数据库数据所做的更改提供不同级别的可见性支持。
⑤提供脚本、存储过程和触发器中用于访问结果集中的数据的T-SQL语句。
使用DECLAR ECURSOR语句定义T-SQL游标的属性,例如游标的SCROLL行为和用于生成游标所操作的结果集的查询。(www.xing528.com)
基于SQL—92标准的DECLARE CURSOR语句语法为:
DECLARE〈游标名〉[INSENSITIVE][SCROLL]CURSOR
FOR〈SELECT语句〉
[FOR{READ ONLY|UPDATE[OF列名[,列名…]]}]
其中,各项参数的解释如下:
①〈游标名〉:所定义的Transact-SQL服务器游标的名称。游标名必须符合标识符规则。
②INSENSITIVE:定义一个游标,以创建该游标对应数据的一个临时副本。这样,如果基本表被修改,则修改不会反映到基于该游标的查询操作中,并且该游标不允许修改。
③SCROLL:指定所有的提取选项(FIRST、LAST、PRIOR、NEXT、RELATIVE、ABSOLUTE)均可用。如果未指定SCROLL,则NEXT是唯一支持的提取选项。
④〈SELECT语句〉:定义游标结果集的标准SELECT语句。
⑤READ ONLY:禁止通过该游标进行更新。在UPDATE或DELETE语句的WHERE CURRENT OF子句中不能引用游标。该选项优于要更新的游标的默认功能。
⑥UPDATE[OF列名[,列名…]]。定义游标中可更新的列。如果指定了OF列名[,列名…],则只允许修改列出的列。如果指定了UPDATE,但未指定具体的列,则可以更新所有列。
在定义游标后,需要进行OPEN才能进行数据操作,语法如下:
OPEN{{[GLOBAL]〈游标名〉}|〈游标变量名〉};
其中,GLOBAL关键字指定全局可用的游标,〈游标变量名〉是宿主语言中引用游标的变量名称。
通过FETCH语句可以检索游标中特定的行:
FETCH
[[NEXT|PRIOR|FIRST|LAST|ABSOLUTE{n|@nvar}
|RELATIVE{n|@nvar}]
FROM]{{[GLOBAL]〈游标名〉}|@〈游标变量名〉}
[INTO@〈局部变量名〉[,〈局部变量名〉…]];
其中,NEXT返回游标中当前行的下一行数据,并且游标位置加1。PRIOR返回游标中当前行的前一行数据,并且游标位置减1。FIRST返回游标中的第1行并将其作为当前行。
LAST返回游标中的最后一行并将其作为当前行。
如果n或@nvar为正数,则ABSOLUTE返回从游标第1行开始的第行,并将返回行变成新的当前行。反之,则返回从游标末尾开始的第行,并将返回行变成新的当前行。如果n或@nvar为0,则不返回行。n必须是整数常量,并且@nvar的数据类型必须为smallint、tinyint或int。
如果n或@nvar为正数,则RELATIVE返回从当前行开始的第行,并将返回行变成新的当前行。如果n或@nvar为负数,则返回当前行之前的第行,并将返回行变成新的当前行。如果n或@nvar为0,则返回当前行。
INTO@〈局部变量名〉[,〈局部变量名〉…]允许将提取操作的列数据放到局部变量中。列表中的各个变量从左到右与游标结果集中的相应列相关联。各变量的数据类型必须与相应的结果集列的数据类型匹配,或是结果集列数据类型所支持的隐式转换。[4]变量的数目必须与游标选择列表中的列数一致。
当不再需要游标时,使用CLOSE语句关闭它:
CLOSE{{[GLOBAL]cursor_name}|cursor_variable_name};
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。