前言

正文

一、嵌入式SQL

以宿主语言C语言为例

exec sql select Sname, Sage into :vSname, :vSage from Student
where Sname=‘张三’ ;
  • 典型特点
    ---- exec sql引导SQL语句: 提供给C编译器,以便对SQL语句预编译成C编译器
    可识别的语句
    ---- 增加一 into子句: 该子句用于指出接收SQL语句检索结果的程序变量
    ---- 由冒号引导的程序变量,如: ‘:vSname’, ‘:vSage’
变量的声明与使用

在嵌入式SQL语句中可以出现宿主语言语句所使用的变量:

exec sql select Sname, Sage  into :vSname, :vSage from
Student  where Sname= :specName;

这些变量需要特殊的声明:

exec sql begin declare section;
char vSname[10], specName[10]=“张三”;
int vSage;
exec sql end declare section;
程序与数据库的连接和断开
  • SQL标准中建议的连接语法为:
execsql connecttotarget-server asconnect-name useruser-name;

execsql connecttodefault;
  • Oracle中数据库连接:
execsql connect:user_name identified by :user_pwd;
  • DB2 UDB中数据库连接:
execsql connecttomydb user:user_name using:user_pwd;

在嵌入式SQL程序执行之后,需要与数据库断开连接

  • SQL标准中建议的断开连接的语法为:
exec sql disconnect connect-name;

exec sql disconnect current;
  • Oracle中断开连接:
exec sql commit release;

exec sql rollback release;
  • DB2 UDB中断开连接:
exec sql connect reset;
exec sql disconnect current;
SQL执行的提交与撤消

SQL语句在执行过程中,必须有提交和撤消语句才能确认其操作结果

  • SQL执行的提交:
execsql commitwork;
  • SQL执行的撤消:
execsql rollbackwork;
  • 为此,很多DBMS都设计了捆绑提交/撤消与断开连接在一起的语句,以保证在断开连接之前使用户确认提交或撤消先前的工作,例如Oracle中:
    execsql commitrelease;

    execsql rollbackrelease;

示例

嵌入式设备连接mysql_ci


嵌入式设备连接mysql_sql_02

二、数据集与游标

检索多行结果,则需使用游标(Cursor)

  • 游标是指向某检索记录集的指针
  • 通过这个指针的移动,每次读一行,处理一行,再读一行… , 直至处理完毕
  • 读一行操作是通过Fetch…into语句实现的:每一次Fetch, 都是先向下
    移动指针,然后再读取
  • 记录集有结束标识EOF, 用来标记后面已没有记录了

嵌入式设备连接mysql_ci_03

游标(Cursor)的使用
  • 游标(Cursor)的使用需要先定义、再打开(执行)、接着一条接一条处理,最后再关闭
//定义
exec sql declare cur_student cursor for
select Sno, Sname, Sclass from Student where Sclass=‘035101’ ;
//打开
exec sql open cur_student;
//推进
exec sql fetch cur_student into :vSno, :vSname, :vSclass;
… …
//关闭
exec sql close cur_student;
  • 游标可以定义一次,多次打开(多次执行),多次关闭

示例

exec sql declare cur_student cursor for
select Sno, Sname, Sclass from Student where Sclass= :vClass
order by Sno for read only ;

exec sql open cur_student;
…
exec sql fetch cur_student into :vSno, :vSname, :vSage
…
exec sql close cur_student;
可滚动游标
  • 可滚动游标是可使游标指针在记录集之间灵活移动、使每条记录可以反复被访问的一种游标

    NEXT向结束方向移动一条; PRIOR向开始方向移动一条;FIRST回到第一条;LAST移动到最后一条;ABSOLUTvalue_spec定向检索指定位置的行,value_spec由1至当前记录集最大值;RELATIVEvalue_spec相对当前记录向前或向后移动,value_spec为正数向结束方向移动,为负数向开始方向移动
  • 可滚动游标移动时需判断是否到结束位置,或到起始位置
  • 可通过判断是否到EOF位置(最后一条记录的后面),或BOF位置(起始记
    录的前面)
  • 如果不需区分,可通过whenevernotfound语句设置来检测

嵌入式设备连接mysql_SQL_04

数据库记录的删除

一种是查找删除(与交互式DELETE语句相同),一种是定位删除

嵌入式设备连接mysql_sql_05

示例:查找删除

普通SQL语句一样的删除

exec sql delete from customers c where c.city = ‘Harbin’ and
not exists ( select * from orders o where o.cid = c.cid);

示例:定位删除
current of 游标名 表示删除游标所指的当前内容

exec sql declare delcust cursor for
select cid from customers c where c.city =‘harbin’ and
not exists ( select * from orders o where o.cid = c.cid)
for update of cid;
exec sql open delcust
While (TRUE) {
exec sql fetch delcust into :cust_id;
exec sql delete from customers where current of delcust ; }
数据库记录的更新

一种是查找更新(与交互式Update语句相同),一种是定位更新

嵌入式设备连接mysql_sql_06


示例:查找更新

exec sql update student s set sclass = ‘035102’
where s.sclass = ‘034101’

示例:定位更新

exec sql declare stud cursor for
select * from student s where s.sclass =‘034101’
for update of sclass;
exec sql open stud
While (TRUE) {
exec sql fetch stud into :vSno, :vSname, :vSclass;
exec sql update student set sclass = ‘035102’ where current of
stud ; }
数据库记录的插入

只有一种类型的插入语句

嵌入式设备连接mysql_嵌入式设备连接mysql_07


示例:插入语句

exec sql insert into student ( sno, sname, sclass)
values (‘03510128’, ‘张三’, ‘035101’) ;

示例:插入语句

exec sql insert into masterstudent ( sno, sname, sclass)
select sno, sname, sclass from student;

示例:宿主语言与SQL结合的过程性控制

求数据库中某一列位于中值的那一行

嵌入式设备连接mysql_SQL_08


嵌入式设备连接mysql_嵌入式设备连接mysql_09

三、状态捕获及错误处理机制

嵌入式 SQL程序中,状态捕获及处理有三部分构成

  • 设置SQL通信区:一般在嵌入式SQL程序的开始处便设置exec sql include sqlca;
  • 设置状态捕获语句:在嵌入式SQL程序的任何位置都可设置;可多次设置;
    但有作用域exec sql whenever sqlerror goto report_error;
  • 状态处理语句:某一段程序以应对SQL操作的某种状态report_error: exec sql rollback;

嵌入式设备连接mysql_sql_10

嵌入式设备连接mysql_SQL_11


状态捕获语句Whenever的作用范围是其后的所有Exec SQL语句,一直到程序中出现另一条相同条件的Whenever语句为止,后面的将覆盖前面的。

嵌入式设备连接mysql_嵌入式设备连接mysql_12

  • S1标号指示的语句受第二个Whenever语句约束。
  • 注意:作用域是语句在程序中的位置,而不是控制流程(因是预编译程序处
    理条件陷阱)

总结

嵌入式设备连接mysql_sql_13