数据库—嵌入式SQL
为什么要使用嵌入式SQL呢?
- SQL能够表达常见的查询,但是不能表达所有查询
- 一些非数据库操作,如打印报表、将查询结果送到图形用户界面中,都不能用SQL语句实现
如何区分和处理两种语言的语句?
当主语言源程序中嵌入SQL语句时,这种源程序已经不是纯的主语言源程序,通常的主语言(如C语言)编译系统不能处理这种源程序
解决这一问题的方法有两种:
(1) 扩充主语言编译系统,使之能处理SQL语句
(2) 预处理:在编译前先扫描源程序,将SQL语句翻译成目标(或主语言程序)过程代码,并将SQL执行翻译成主语言的过程调用。预处理后的源程序再提交主语言的编译系统处理
- 通常,商品化DBMS采用预处理方法,预处理程序由DBMS开发商提供 例如,微软的SQL Server™ 2000
提供的预处理程序nsqlprep.exe可以对嵌入C语言源程序中的 SQL 语句进行预处理 - 为了能够区分源程序中的SQL语句和主语言语句,SQL规定: 所有嵌入式SQL语句都必须加前缀EXEC SQL
- SQL语句的结束标志则因主语言的不同而异 例如,当主语言是PL/1和C语言时,SQL语句以分号(;)为结束标记
当主语言为COBOL语言时,SQL语句以END-EXEC为结束标记 这样,当主语言是C语言时,嵌入式SQL语句的一般形式为:
EXEC SQL <SQL语句>;
两种语言的语句如何交换信息?
SQL语句和主语言语句之间的信息交换(通信)可以通过
- SQLCODE
- 主语言变量
- 游标
SQLCODE:
- 每个SQL语句执行执行之后需要反馈一些状态信息,指出该SQL是成功执行还是出现异常;如果查询执行成功,是否得到数据等
- SQL语句执行之后,系统将这些状态信息存入SQLCODE中,主语言语句可以访问SQLCODE,了解SQL语句的执行结果,根据结果采取相应的动作
- SQLCODE是一个整型变量 如果SQL语句成功执行,则SQLCODE=0
如果执行结果无数据(如没有满足查询条件的元组),则SQLCODE=100 其他情况为异常,SQLCODE取负值,其具体值依赖于实现 - 每个嵌入式SQL语句执行之后,主语言程序应当先检测SQLCODE的值,然后决定下一步的处理
主语言变量:
- SQL语句与主语言语句交换信息的另一种途径是使用主语言变量
- 在一般情况下,主语言程序定义的变量不能在SQL语句中使用。但是,使用如下形式说明的主语言变量在主语言语句和SQL语句都能使用:
- EXEC SQL BEGIN DECLARE SECTION;
- 主语言变量说明;
- EXEC SQL END DECLARE SECTION;
- SQL语句与主语言语句可以通过主语言变量交换信息 主语言语句可以提前对SQL语句使用的主语言变量赋值,将特定的值传递给SQL语句
- SQL语句也可以将查询结果存放到主语言变量中,供主语言语句使用 这种主语言变量简称主变量
- SQL规定:SQL语句中出现的主语言变量之前必须加冒号(:)
- 原因:为了区别SQL语句中的数据库对象和主语言变量 ,数据库对象(关系、属性等)和主语言变量都用标识符表示,主语言变量可能与关系或属性同名
游标
- 为什么需要游标?
- 主语言是面向记录的过程式语言,而SQL是面向集合的非过程式语言
- 存在矛盾:一个SQL语句得到的结果可能是多个记录,而主语言没有办法一次处理多个记录
- 解决该问题的方法是使用游标
- 游标其实就是一个数据缓冲区,暂时存放SQL语句的执行结果,以便主语言可以逐一获取记录,进行处理
- 使用游标需要预先说明游标,在使用前打开游标,通过专门的SQL语句逐一提取记录,并在使用完之后关闭游标
如何连接数据库?
- 在使用主语言编写的应用程序中,访问数据库前必须先建立数据库连接。SQL提供了建立和关闭数据库连接语句
- 建立数据库连接的语句形式为:
- EXEC SQL CONNECT TO <SQL服务器>[AS <连接名>] [USER <用户名>];
- <SQL服务器>是要连接的数据库服务器。它可以是服务器标识串,形如
<dbname>@<hostname>:<port> - AS <连接名>为建立的连接命名,当整个程序只建立一个数据库连接时可以省略
- USER <用户>指明建立连接的用户名,缺省时为当前用户
- 建立到当前服务器的默认连接 EXEC SQL CONNECT TO DEFAULT;
- 关闭数据库连接的语句形式为 EXEC SQL DISCONNECTION <连接名>;