嵌入式SQL语言-程序员宅基地

技术标签: database  数据库系统笔记  数据库  sql  

一、概述

高级语言+SQL语言
既继承高级语言的过程控制性又结合SQL语言的复杂结果集操作的非过程性;同时又为数据库操作者提供安全可靠的操作方式,通过应用程序进行操作。
嵌入式SQL语言
将SQL语言嵌入到某一种高级语言中使用,如C/C++, Java, PowerBuilder等,又称宿主语言(HostLanguage)。

示例交互式SQL语言
select Sname, Sage from Student where Sname =‘张三’;

示例嵌入式SQL语言
以宿主语言C语言为例
exec sql select Sname, Sage into :vSname, :vSage from Student where Sname=‘张三’;

典型特点

  1. exec sql 引导SQL语句:提供给C编译器,以便对SQL语句预编译成C编译器可识别的语句。
  2. 增加 into子句:该子句用于指出接收SQL语句检索结果的程序变量,由冒号引导的程序变量,如:‘:vSname’, ‘:vSage’

二、变量声明与数据库连接

1、变量的声明与使用

在嵌入式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;

变量声明和赋值中,要注意:

  1. 宿主程序的字符串变量长度应比字符型字段的长度多1个。因宿主程序的字符串尾部多一个终止符为\0 ‘,而程序中用双引号来描述。
  2. 宿主程序变量类型与数据库字段类型之间有些是有差异的,有些DBMS可支持自动转换,有些不能。

声明的变量,可以在宿主程序中赋值,然后传递给SQL语句的where等子句中,以使SQL语句能够按照指定的要求(可变化的)进行检索。
exec sql begin declare section; char vSname[10], specName[10]=“张三”;int vSage; exec sql end declare section;
exec sql select Sname,Sage into :vSname, :vSage from Student where Sname = :specName ;

相应的交互式SQL语句:
select Sname, Sage from Student where Sname =张三’;

嵌入式比交互式SQL语句灵活了一些:只需改一下变量值,SQL语句便可反复使用,以检索出不同结果。

(1) 数据库与DBMS连接

SQL标准连接语法为:
exec sql connect to target-server as connect-name user user-name;

exec sql connect to default;
Oracle中数据库连接:
exec sql connect :user_name identified by :user_pwd;
DB2 UDB中数据库连接:
exec sql connect to mydb user :user_name using :user_pwd;

(2) 与数据库断开连接

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;

(3) SQL执行的提交与撤消

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

SQL执行的提交:
exec sql commit work;
SQL执行的撤消:
exec sql rollback work;

很多DBMS都设计了捆绑提交/撤消与断开连接在一起的语句,以保证在断开连接之前使用户确认提交或撤消先前的工作
例如Oracle中:
exec sql commit release;

exec sql rollback release;

(4) 事务的概念与特性

事务:(从应用程序员角度)是一个存取或改变数据库内容的程序的一次执行或者说一条或多条SQL语句的一次执行被看作一个事务

事务一般是由应用程序员提出,因此有开始和结束,结束前需要提交或撤消。

Begin Transaction
exec sql …
exec sql …
exec sql commit work | exec sql rollback workEnd Transaction

在嵌入式SQL程序中,任何一条数据库操纵语句(如exec sql select等)都会引发一个新事务的开始,只要该程序当前没有正在处理的事务。而事务的结束是需要应用程序员通过commit或rollback确认的。因此Begin Transaction和End Transaction两行语句是不需要的。

事务∶(从微观角度,或者从DBMS角度)是数据库管理系统提供的控制数据操作的一种手段,通过这一手段,应用程序员将一系列的数据库操作组合在一起作为一个整体进行操作和控制,以便数据库管理系统能够提供一致性状态转换的保证。
在这里插入图片描述
事务的特性: ACID

  1. 原子性Atomicity : DBMS能够保证事务的一组更新操作是原子不可分的,即对DB而言,要么全做,要么全不做
  2. 一致性Consistency: DBMS保证事务的操作状态是正确的,符合一致性的操作规则,它是进一步由隔离性来保证的
  3. 隔离性lsolation: DBMS保证并发执行的多个事务之间互相不受影响。例如两个事务T1和T2,即使并发执行,也相当于或者先执行了T1,再执行T2;或者先执行了T2,再执行T1。
  4. 持久性Durability: DBMS保证已提交事务的影响是持久的,被撤销事务的影响是可恢复的。

换句话说:具有ACID特性的若干数据库基本操作的组合体被称为事务。

事务处理是DBMS的核心技术。

在这里插入图片描述
在这里插入图片描述
步骤:

  1. 引入SQLCA
  2. 声明变量
  3. 设置SQL错误捕获语句
  4. 连接数据库
  5. 设置SQL语句,并提交
  6. 断开连接

三、数据集与游标

1、检索单行结果

可将结果直接传送到宿主程序的变量中

EXEC SQL SELECT[ALL | DISTINCT]expression [, expression…]
INTO host-variable , [host-variable,…]
FROM tableref [corr_name] [ , tableref [corr_name] …]WHEREsearch_condition;

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

2、检索多行结果

检索多行结果,则需使用游标(Cursor)
游标是指向某检索记录集的指针。通过这个指针的移动,每次读一行,处理一行,再读一行….,直至处理完毕。

读一行操作是通过Fetch…into语句实现的:每一次Fetch,都是先向下移动指针,然后再读取。
记录集有结束标识EOF,用来标记后面已没有记录了

3、游标(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;

游标可以定义一次,多次打开(多次执行),多次关闭

Cursor的定义:declare cursor

EXEC sQL DECLAREcursor_name CURSOR FOR
Subquery
[ORDER BY result_column [ASC | DESC][, result_column …]
[FOR [ READ ONLY | UPDATE [OF columnname [, columnname…]]l];

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

Cursor的打开和关闭open cursor //close cursor
EXEC SQL OPEN cursor_name;
EXEC SQL CLOSE cursor_name;

Cursor的数据读取Fetch
EXEC SQL FETCH cursor_name INTOhost-variable , [host-variable,...];

示例
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;

四、可滚动游标及数据库的增删改

1、可滚动游标的概念、定义和使用

标准的游标始终是自开始向结束方向移动的,每fetch一次,向结束方向移动一次;一条记录只能被访问一次;再次访问该记录只能关闭游标后重新打开。
可滚动游标是可使游标指针在记录集之间灵活移动、使每条记录可以反复被访问的一种游标。

EXEC SQL DECLAREcursor_name [INSENSITIVE] [SCROLL] CURSOR
[WITH HOLD] FOR Subquery
[ORDER BY result_column [ASC | DESC][, result_column …][FOR READ ONLY | FOR UPDATE OF columnname [,
columnname ]…];
EXEC SQL FETCH
[NEXT |PRIOR | FIRST | LAST
I [ABSOLUTE | RELATIVE] value_spec ]
FROM cursor_name INTO host-variable [, host-variable …];

NEXT向结束方向移动一条;
PRIOR向开始方向移动一条;
FIRST回到第一条;
LAST移动到最后一条;
ABSOLUT value_spec定向检索指定位置的行,
value_spec由1至当前记录集最大值;
RELATIVE value_spec相对当前记录向前或向后移动,
value_spec为正数向结束方向移动,为负数向开始方向移动

可滚动游标移动时需判断是否到结束位置,或到起始位置。可通过判断是否到EOF位置(最后一条记录的后面),或BOF位置(起始记录的前面)。如果不需区分,可通过whenever not found语句设置来检测。

2、数据的删除与更新

一种是查找删除(与交互式DELETE语句相同),一种是定位删除
EXEC sQL DELETE FROM tablename [corr_name]
WHERE search_condition | WHERE CURRENT OF cursor_name;

示例:查找删除
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 delcustWhile (TRUE){
exec sql fetch delcust into :cust_id;
exec sql delete from customers where current of delcust ; }

3、数据库记录的更新

一种是查找更新(与交互式Update语句相同),一种是定位更新
EXEC sQL UPDATEtablename [corr_name]
SET columnname = expr [, columnname = expr …]
[ WHEREsearch_condition ] | WHERE CURRENT OF cursor_name;

示例:查找更新
execsql 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 ofstud ; }

4、数据库记录的插入

只有一种类型的插入语句
EXEC SQL INSERT INTOtablename [(columnname [,columnname, …] )]
[ VALUES (expr [ , expr , …] ) | subqurey ];

示例:插入语句
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;

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

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

#include <stdio.h>
#include "prompt.h”
exec sql include sqlca;
char custprompt[ ] ="Please enter a customer ID:int main()
{
    
exec sql begin declare section;
char cid[5],user_name[20], user_pwd[10];
double dollars; 
int ocount;
exec sql end declare section;
exec sql declare dollars_cursor cursor for
select dollars from orders where cid = :cid and dollars is not nullorder by dollars;

int i;
exec sql whenever sqlerror goto report_error;
strcpy(user_name, "poneilsql");
strcpy(user_pwd, "xxXx”);
exec sql connect :user_name identified by :user_pwd;
While ( prompt(custprompt, 1, cid ,4)>=0 {
    
exec sql select count(dollars) into :ocount from orders where cid =:cid ;
if (ocount ==0 )
printf("No record reviewed for cid value %sln", cid);
continue; }
exec sql open dollars _cursor;
for (i =0; i< (ocount+1)/2; i++)
exec sql fetch dollars_cursor into :dollars;
exec sql close dollars_cursor;
exec sql commit work;
printf("Median dollar amount =%fln”, dollars); }
}

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

状态捕获及其处理
状态,是嵌入式SQL语句的执行状态,尤其指一些出错状态;有时程序需要知道这些状态并对这些状态进行处理

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

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

SQL通信区:SQLCA
SQLCA是一个已被声明过的具C语言的结构形式的内存信息区,其中的成员变量用来记录SQL语句执行的状态,便于宿主程序读取与处理
SQLCA是DBMS(执行SQL语句)与宿主程序之间交流的桥梁之一

状态捕获语句
exec sql whenever condition action;

Whenever语句的作用是设置一个“条件陷阱”,该条语句会对其后面的所有由Exec SQL语句所引起的对数据库系统的调用自动检查它是否满足条件(由condition指出).

  1. SQLERROR:检测是否有SQL语句出错。其具体意义依赖于特定的
  2. DBMSONOT FOUND:执行某一SQL语句后,没有相应的结果记录出现
  3. SQLWARNING:不是错误,但应引起注意的条件

如果满足condition,则要采取一些动作(由action指出)

  1. CONTINUE:忽略条件或错误,继续执行
  2. GOTO标号:转移到标号所指示的语句,去进行相应的处理STOP:终止程序运行、撤消当前的工作、断开数据库的连接
  3. DO函数或CALL函数:调用宿主程序的函数进行处理,函数返回后从引发该condition的Exec SQL语句之后的语句继续进行。

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

int main(){
    
exec sql whenever sqlerror goto handle_error;
exec sql create table customers(cid char(4) not null,
cname varchar(13), ... ...);
handle_error:
exec sql whenever sqlerror continue;
//控制是否无限循环:无,则可能:有,则不会
exec sql drop customers;exec sql disconnect;
fprintf(stderr,"could not create customers tableln");return -1;
}

典型DBMS系统记录状态信息的三种方法状态记录

  1. sqlcode:典型DBMS都提供一个sqlcode变量来记录其执行sql语句的状态,但不同DBMS定义的sqlcode值所代表的状态意义可能是不同的,需要查阅相关的DBMS资料来获取其含义
  2. sqlcode== 0, successful call;
  3. sqIcode<0, error, e.g., from connect, database does not exist , -16;
  4. sqlcode > 0, warning, e.g., no rows retrieved from fetch
  5. sqlca.sqlcode:支持SQLCA的产品一般要在SQLCA中填写sqlcode来记录上述信息;除此而外,sqlca还有其他状态信息的记录
  6. sqlstate:有些DBMS提供的记录状态信息的变量是sqlstate或sqlca.sqlstate

当我们不需明确知道错误类型,而只需知道发生错误与否,则我们只要使用前述的状态捕获语句即可,而无需关心状态记录变量(隐式状态处理)
但我们程序中如要自行处理不同状态信息时,则需要知道以上信息,但也需知道正确的操作方法(显式状态处理)

显式状态处理示例

exec sql begin declar section;
char sQLSTATE[6];
exec sql end declare section;

exec sql whenever sqlerror goto handle_error;

exec sql whenever sqlerror continue;exec sql create table custs
(cid char(4) not null, cname varchar(13),... .…. );

if (strcmp(SQLSTATE, "82100")==0)
<处理82100错误的程序>

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_49090973/article/details/122532908

智能推荐

2018上半年GitHub上最热门的开源项目-程序员宅基地

文章浏览阅读43次。关注GitHub的人都知道,这个平台上面有太多优秀的值得学习的开源项目了,这里总结了2018上半年GitHub上最热门的开源项目。1: tensorflowhttps://github.com/tensorflow/tensorflowTensorFlow是一个使用数据流图进行数值计算的开源软件库。图节点表示数学运算,而图边表示在它们之间流动的多维数据数组(张量)..._build-your-own-vue

【vscode】远程连接报错Resolver error: Connecting was canceled_resolver error: error: connecting was canceled-程序员宅基地

文章浏览阅读1.7w次。https://blog.csdn.net/qq_41058526/article/details/105291284亲测解决。_resolver error: error: connecting was canceled

Windows的torch + Cuda + cuDNN_cuda必须安装在c盘吗-程序员宅基地

文章浏览阅读2k次。windows下的pytorch-gpu安装_cuda必须安装在c盘吗

java/jsp/ssm酒店客房管理系统的设计与实现【2024年毕设】-程序员宅基地

文章浏览阅读38次。springboot基于小程序的临沂大学非机动车车辆管理系统。开发软件:eclipse/myeclipse/idea。springboot基于微信小程序的线下剧本杀管理系统。springboot微信小程序的代驾系统的设计与实现。springboot一品萫茶馆管理系统的设计与实现。springboot交通违章处理系统的设计与实现。springboot洛阳地铁信息查询与管理系统。ssm基于微信小程序的多多母婴购物商城的设计与。springboot企业客户信息反馈平台。springboot校园篮球联赛管理系统。

【操作系统-Windows】使用“任务计划程序”延时启动程序_任务计划延时启动程序-程序员宅基地

文章浏览阅读1.1w次,点赞3次,收藏16次。第一步、打开任务方式一、控制面板中打开控制面板 &gt;所有控制面板项 &gt; 管理工具 ,任务计划程序方式二、运行中打开【Win+R】输入taskschd.msctaskschd.msc第二步、创建任务选中并右击【任务计划程序库】,点击【新文件夹】,命名为【Rsszy】。点击【操作】-【创建基本任务…】输入【名称】和【描述】,点击【下一步..._任务计划延时启动程序

【信息安全】数据安全与信息安全_信息安全的指标有什么-程序员宅基地

文章浏览阅读5.2k次,点赞2次,收藏26次。数据安全与信息安全的关系,是包含的关系,信息安全包括了数据安全与网络安全,数据安全主要是数据使用的安全。_信息安全的指标有什么

随便推点

C语言求两个整数最大值_两个整数的最大值-程序员宅基地

文章浏览阅读5.7k次,点赞6次,收藏5次。上代码:#include#define Max(a,b) ((a>b)?(a):(b)) //预处理实现int max(int a,int b) //函数实现{return a>b?a:b;}int main(){printf("%d\n",Max(18,19));printf("%d\n",Max(19,18));printf("\n");p_两个整数的最大值

wordpress 搬家 如何修改配置文件?实用教程建议收藏_wordpress网站搬家要修改那个表-程序员宅基地

文章浏览阅读435次。首先备份好源码以及数据库上传到新服务器以及数据库分别修改以下文件和数据库文档 上传覆盖 即可wp-config修改文件‘wp-config’ 填写新的数据库名称、用户名、密码、MySQL主机(万网测试需要修改)、如图然后:在新主机的数据库中修改原来域名的连接(这个是给有换新域名的用,如只换过主机没有换域名,此步可跳过。)首先介绍下SQL替换命令UPDATE 表名 SET 字段 = REPLACE(字段,’替换内容’,’替换值’);实例如下: UPDATE.._wordpress网站搬家要修改那个表

php服务器接口开发教程,20180313 - API服务端开发入门(5)从零开始编写接口-程序员宅基地

文章浏览阅读137次。前言现在,我们来“假设”一个接口需求,然后来完成它。需求简介我们的APP需要一个商品模块,包含了如下功能,我们应该如何设计接口呢?检索,从商品数据库中找到目标商品展示,查看一个商品的详细信息评论,查看与编写评论准备工作选择一个接口框架印象中,说起框架就是指 think PHP、Laravel、yii等,但其实还有大量的“专业框架”,比如专门为接口开发而设计的框架,不要问我都有哪些框架,自行搜索,反..._php编写api接口

cocos creator主程入门教程(二)—— 弹窗管理_cocos 弹窗设计 同时可以存在几个-程序员宅基地

文章浏览阅读1.2k次。我们已经知道怎样制作、加载、显示界面。但cocos没有提供一个弹窗管理模块,对于一个多人合作的项目,没有统一的管理,界面层级容易混乱。作为主程,在项目开始就应该处理好这些问题,将弹窗划分为不同的层次,不同类型的信息显示在不同的层中。下面将讲解怎样设计弹窗堆栈。一般地,从下向上,我会将弹窗划分为以下层:1)内容层,展示游戏相关的信息界面。2)tips层,显示提示性信息界面,例如获得物品的浮窗、网络异常的提示。3)新手引导层,主要显示新手引导的手指、新手提示文本框等。4)alert层,主要显_cocos 弹窗设计 同时可以存在几个

PowerDesigner16x64_Evaluation安装_powerdesigner x64-程序员宅基地

文章浏览阅读221次。https://www.sap.com/_powerdesigner x64

【Python】Python 包 ① ( Python 包引入 | Python 包概念 | Python 包结构 | 创建 Python 包 | 导入 Python 包 )_python包-程序员宅基地

文章浏览阅读2.6k次,点赞3次,收藏14次。一、Python 包简介1、Python 包引入2、Python 包概念3、Python 包结构4、创建 Python 包5、导入 Python 包_python包

推荐文章

热门文章

相关标签