第九讲|第九讲 嵌入式SQL语言之基本技巧

嵌入式SQL语言 为什么需要嵌入式SQL语言?
交互式SQL本身不够灵活, 对于普通用户来说, 复杂的查询掌握起来太难, 开发应用程序很有必要. 而且查询本身具有复杂性, 若是能结合高级语言的流程控制等特性, 将会有很大优势.
第九讲|第九讲 嵌入式SQL语言之基本技巧
文章图片
高级语言中使用嵌入式语言需要解决的问题 程序与数据库连接 第九讲|第九讲 嵌入式SQL语言之基本技巧
文章图片
第九讲|第九讲 嵌入式SQL语言之基本技巧
文章图片
SQL语句在执行过程中,必须有提交和撤消语句才能确认其操作结果.

  • SQL执行的提交:
    exec sql commit work;
  • SQL执行的撤消:
    exec sql rollback work;
为什么需要提交和撤销?
先了解一下事务的概念:
事务 (从应用程序员角度)是一个存取或改变数据库内容的程序的一次执行,或者说一条或多条SQL语句的一次执行被看作一个事务.
事务一般是由应用程序员提出,因此有开始和结束, 结束前需要提交或撤消。
Begin Transaction exec sql … … exec sql … exec sql commit work | exec sql rollback work End Transaction

在嵌入式SQL程序中,任何一条数据库操纵语句(如exec sql select等)都会引发一个新事务的开
始,只要该程序当前没有正在处理的事务。而事务的结束是需要应用程序员通过commit或
rollback确认的。因此Begin Transaction和End Transaction两行语句是不需要的。
事务, 就是提供一组操作, 要么全部执行, 要么全部不执行, 保证这个这组操作过程的完整性.
事务的特性:
  • 原子性Atomicity
    DBMS能够保证事务的一组更新操作是原子不可分的,即对DB而言,要么全做,要么全不做
  • 一致性Consistency
    DBMS保证事务的操作状态是正确的,符合一致性的操作规则,它是进一步由隔离性来保证的
  • 隔离性Isolation
    DBMS保证并发执行的多个事务之间互相不受影响。例如两个事务T1和T2, 即使并发执行,也相当于或者先执行了T1,再执行T2; 或者先执行了T2, 再执行T1
  • 持久性Durability: DBMS保证已提交事务的影响是持久的,被撤销事务的影响是可恢复的.
第九讲|第九讲 嵌入式SQL语言之基本技巧
文章图片
嵌入式SQL示例:
#include #include “prompt.h” exec sql include sqlca; // SQLCA: SQL communication, Area SQL通信区 char cid_prompt[ ] = "Please enter customer id: "; int main() { exec sql begin declare section; // 变量声明 char cust_id[5], cust_name[14]; float cust_discnt; char user_name[20],user_pwd[20]; exec sql end declare section; exec sql whenever sqlerror goto report_error; // SQL错误捕获语句 exec sql whenever not found goto notfound; // SQL错误捕获语句strcpy(user_name, "poneilsql"); // 连接数据库 strcpy(user_pwd, "*****"); exec sql connect :user_name identified by :user_pwd; while((prompt(cid_prompt, 1, cust_id, 4)) >=0) { exec sql select cname,discnt into :cust_name, :cust_discnt from customers where cid=:cust_id; exec sql commit work; // SQL Commit Wortprintf("Customer’s name is %s and discount is %5.1f\n", cust_name,cust_discnt); continue; notfound: printf("Can’t find customer %s, continuing\n", cust_id); } exec sql commit release; return 0; report_error: print_dberror(); // 打印错误 exec sql rollback release; // 断开连接 return 1; }

游标 游标是什么? 我们为什么需要它?
检索单行结果,可将结果直接传送到宿主程序的变量中.例如:
exec sql select Sname, Sage into :vSname, :vSage from Student where Sname = :specName ;

检索多行结果, 就需要使用游标(Cursor)
  • 游标是指向某检索记录集的指针
  • 通过这个指针的移动, 每次读一行处理一行, 再读一行...., 直到处理完毕
  • 读一行通过Fetch...into语句实现, 每次Fetch, 都是向下移动指针, 然后再读取
  • 记录集有结束标识EOF, 用来标记后面已没有记录了
第九讲|第九讲 嵌入式SQL语言之基本技巧
文章图片
游标 游标的使用:
游标(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;

可滚动的游标
标准的游标总是从上往下的读的. 但是我们想向上向下滚动读取. ODBC(Open DataBase Connectivity)是一种跨DBMS的DB操作平台, 它在应用程序与实际的DBMS之间提供了一种通用接口, 可以帮助我们实现滚动游标.
数据库记录的删除与更新
删除 查找删除:
exec sql delete from customers c where c.city = 'Harbin' and not exists ( select * from orders o where o.cid = c.cid);

定位删除:
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 ; }

更新 一种是查找更新, 一种是定位更新
查找更新:
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 ; }

数据库插入
exec sql insert into student ( sno, sname, sclass) values ('03510128', '张三', '035101') ;

状态捕获及其处理 状态, 是嵌入式SQL语句的执行状态, 尤其指一些出错状态, 有时程序需要知道这些状态并对这些状态进行处理.
嵌入式SQL程序中, 状态捕获及处理有三部分构成:
  • 设置SQL通信区: 一般在嵌入式SQL程序的开始处便设置
    exec sql include sqlca;
  • 设置状态捕获语句: 在嵌入式SQL程序的任何位置都可以设置, 可以多次设置, 但是有作用域
    exec sql whenever sqlerror goto report_error;
  • 状态处理语句: 某一段程序以应对SQL的某种状态
    report_error: exec sql rollback;
SQL通信区: SQLCA
  • SQLCA是一个已被声明过的具C语言的结构形式的内存信息区,其中的成员变量用来记录SQL语句执行的状态,便于宿主程序读取与处理
  • SQLCA是DBMS(执行SQL语句)与宿主程序之间交流的桥梁之一

    第九讲|第九讲 嵌入式SQL语言之基本技巧
    文章图片
状态捕获语句
exec sql whenever condition action;
Whenever语句的作用是设置一个"条件陷阱", 当满足条件的时候, 就会执行相应的动作.

第九讲|第九讲 嵌入式SQL语言之基本技巧
文章图片
条件(condition)与动作(action) 【第九讲|第九讲 嵌入式SQL语言之基本技巧】作用范围, 两个whenever 之间, 否则直到程序结束.
注意:作用域是语句在程序中的位置,而不是控制流程(因是预编译程序处理条件陷阱)
第九讲|第九讲 嵌入式SQL语言之基本技巧
文章图片
第九讲|第九讲 嵌入式SQL语言之基本技巧
文章图片
回顾 第九讲|第九讲 嵌入式SQL语言之基本技巧
文章图片
数据库系统学习笔记

    推荐阅读