第15章 嵌入式SQL的应用
第15章 嵌入式SQL的应用
SQL在如今的数据库领域虽然应用的非常的广泛,但是,与一些高级语言相比,在某些功能上还有一定的限制。也就是说,在有些功能上,纯粹使用SQL语句还无法实现。数据库访问只是其中一个部件。有些如与用户交互、图形化显示数据等动作只能通过应用高级语言来实现。
15.1 嵌入式SQL介绍
在关系数据库中,可以将SQL语句嵌入到宿主语言中,既实现嵌入式SQL,从而完成在单独使用SQL语句时难以实现的功能。
15.1.1 直接调用SQL
直接调用SQL也称为交互式SQL。通常是指用户在数据库产品提供的客户端应用软件中直接运行SQL语句,同时通过该软件返回SQL语句的执行结果。前面所讲解的SQL Server数据库及其相关的示例,其交互式SQL的实现都是通过在查询分析器中实现的。在SQL Server的查询分析器中直接运行SQL语句,同时返回语句的执行结果,如图15.1所示。
图15.1 SQL Server2005的查询分析器界面
说明:本书中所使用的SQL Server数据库是SQL Server2005的SQL Server Management
Studio版本,该版本将SQL Server2000中的企业管理器和查询分析器的功能都集合在一起,图19.1就是该版本的查询分析器界面。
在不同的数据库管理系统当中,实现交互式SQL的方法是不同的。在Oracle数据库当中,通过SQL*Plus软件实现交互式SQL。但是,无论通过什么方式实现交互式SQL,SQL中其基本的SELECT、INSERT、UPDATE和DELETE语句以及与存储过程、触发器、事务和连接等有关的语句,几乎都可以在交互式SQL环境中实现,即实现直接调用操作。
交互式SQL是一个纯SQL环境,因此,通过交互式SQL很难与应用程序建立起连接,这就使得交互式SQL的应用受到了很大的限制。在实际应用中,大多数的访问都是通过嵌入式SQL和SQL调用层接口(CLI)完成的,很少依靠交互式SQL来实现。
15.1.2 SQL调用层接口(CLI)
通常情况下,应用程序要想与SQL数据库之间进行交流,需要SQL调用层接口来实现。SQL调用层接口是一种支持预定义例程的应用程序接口。应用程序调用例程,然后连接到数据库。通过例程可以访问数据库中的数据信息,同时将访问到的数据信息返回给应用程序。
应用程序与SQL数据库之间通过SQL调用层接口(CLI)进行交流的过程如图15.2所示。
图15.2 通过SQL调用层接口(CLI)访问数据库的流程
通常情况下,应用程序与CLI例程之间是通过函数来实现的。
程序通过使用函数来调用CLI例程,函数通过设定参数把值传递给例程,由函数作为应用程序和SQL数据库之间的接口。目前应用最广泛的的CLI模块工具是Microsoft公司的ODBC(Open Database Conectivity)和Microsoft公司的OLE-DB/ADO(ActiveX Data Object)。
1.ODBC
ODBC技术是对数据库进行访问的标准应用程序接口(API)和Windows开放式服务体系结构OSA的一个重要组成部分,已被得到了广泛的应用。
ODBC为开发应用数据库程序提供了非常强大的功能和灵活性。ODBC通过驱动程序管理器与数据库进行交换信息。驱动程序管理器负责将应用程序对ODBC的调用,传递给正确的驱动程序,而驱动程序在执行完相应的操作后,将结果通过驱动程序管理器返回给应用程序。
ODBC所包含的部件及其关系如图15.3所示。
图15.3 ODBC包含的各部件及其关系图
说明:应用程序要访问一个数据库,首先必须用ODBC管理器注册一个数据源,管理器根据数据源提供的数据库位置、数据库类型及ODBC驱动程序等信息,建立起ODBC与具体数据库的联系。
2.OLE-DB/ADO
OLE DB是系统级的编程接口,可在C/C++语言中直接使用。OLE DB提供了一组标准的服务组件,用于提供查询、缓存、数据更新和事务处理等操作。OLE DB还通过定义的COM接口将各种数据系统的访问操作进行封装,为数据使用方和数据提供方建立了标准。
微软公司的ADO是最新的对象层次上的数据操作技术,ADO技术为操作OLE DB数据源提供了一套高层次自动化接口。虽然OLE DB已经是一个强大的数据操作接口,但是很多的数据库应用程序开发人员并不需要OLE DB提供的操作数据的底层控制接口。
注意:通过CLI访问SQL数据库的核心并不在于SQL本身,而在于访问SQL数据库的高级语言开发工具(如C语言)以及CLI实现的本身。
ADO同OLE DB、数据库应用以及数据源之间的关系如图15.4所示。
图15.4 ADO同OLE DB、数据库应用以及数据源之间的关系
15.2 嵌入式SQL的使用
15.2.1 嵌入式SQL
嵌入式SQL是指将SQL语言嵌入到某种高级语言当中,如在FORTRAN、COBOL和C语言中都可以嵌入SQL语言,来弥补SQL语言在实现复杂应用方面的不足。
通常使用预处理的方式来实现嵌入式SQL。通过扩充宿主语言(高级编程语言)的编译程序,使其能够处理SQL语句和预处理的方式。预处理方式的处理过程主要可以表示为以下几个方面:
- 由DBMS的预处理程序扫描源程序,从源程序中识别出SQL语句使其能够被编译执行。
- 把识别出的SQL语句转换成主语言调用语句,使高级语言编译程序能识别该调用语句。
- 由高级语言的编译程序将整个源程序编译成目标代码。
其具体实现的流程如图15.5所示。
图15.5 嵌入式SQL预处理方式的实现
从图15.5中可以看出,预处理方式首先从含有高级语言和SQL语句的程序开始。在编译程序之前,首先把程序提交给一个预编辑器,通过预编译器将SQL语句从高级语言中分离出来,并且实现对SQL语句的调用。然后通过高级语言编译器按照自己的方式进行编译,最后得到目标代码,实现连接到数据库的例程当中。
15.2.2 SQL通信区
SQL通信区(SQL Communication Area)简称SQLCA。在SQL语句运行时,DBMS返回描述系统当前工作状态以及运行环境状态等信息。应用程序根据从SQLCA中取出的信息来决定下一步要执行的操作。
在使用SQLCA时,首先需要在高级语言中定义,其实现定义的语句结构如下所示:
EXEC SQL INCLUDE SQLCA
SQLCA中包含的主要字段及其字段的含义如下所示:
- SQLCAID:该字段含有8字节字符,其作用是在查看内存内容时帮助进行调试。
- SQLCABC:该字段是包含SQLCA结构长度的长整型数。
- SQLCODE:数据库在请求上检测到错误时,指定错误代码的长整数。成功操作的错误代码是0,正数表示警告,负数表示错误。
- SQLERRML:字段中信息的长度。
- SQLERRMC:要插入到错误消息中的零个或多个字符串。
- SQLERRD:长整数的实用程序数组。
下面通过一个示例来说明如何在嵌入式SQL语句中应用SQLCA。
【上机实战】
在C语言中嵌入SQL语句中SQLCA。
#include<stdio.h>
/* 定义SQLCA变量,用于进行错误检测 */
EXEC SQL INCLUDE SQLCA;
main()
{/* 连接数据库 */EXEC DQL CONNECT TO MyDataBase USER SA;if(sqlca.sqlcode){printf(Printer,"连接数据库服务器错误!");exit();}
}
示例中的代码表示通过SQLCA检测在连接数据库时是否有错误产生。如果sqlca.sqlcode的值为0,则连接数据库的SQL语句执行失败,说明连接数据库不成功,程序将提示“连接数据库服务器错误!”的提示信息。
15.2.3 主变量
在SQL语句中使用的高级语言程序的变量简称为主变量。使用主变量可以输入或输出数据。
1.主变量的分类
主变量可以分为输入主变量和输出主变量两种。输入主变量通过SQL语句进行引用,然后由应用程序对其赋值;输出主变量由SQL语句对该变量进行赋值或设置状态信息,然后将该信息返回给应用程序。
利用输入主变量,可以指定向数据库中插入的数据,将数据库中的数据修改为指定值的功能。利用输出主变量,可以得到SQL语句的结果数据和状态。
2.主变量的定义和使用
在SQL语句中,输入主变量前面要加冒号,以便于区别数据库对象名。输入主变量可以被应用在SQL的数据操纵语句当中的任何位置。定义输出变量的方法是在SQL语句的BEGIN DECLARE SECTION与END DECLARE SECTION之间进行说明。
下面通过一个示例来讲解如何定义输入主变量。
【上机实战】
定义输入主变量。
/* 定义输入主变量 */
EXEC SQL SELECT sName,sSex,sPhone,sAddress/* 下面的变量tName,tSex,tPhone,tAddress,In_No是在高级语言中定义的 */INTO :tName,:tSex,:tPhone,:tAddressFROM employeeWHERE No=:In_No;
下面通过一个示例来讲解如何定义输出主变量。
/* 定义输出主变量 */
EXEC SQL BEGIN DECLARE SECTIONINT out_No;CHAR out_name[10];CHAR out_sex[2];INT out_age;CHAR out_phone[11];CHAR out_address[50];CHAR SQLSTATE[6]
EXEC SQL END DECLARE SECTION
EXEC SQL SELECT sName,sSex,sAge,sPhone,sAddressINTO :tName,:tSex,:tAge,:tPhone,:tAddressFROM employeeWHERE No=:In_No;
15.2.4 在嵌入式SQL中使用SQL语句
本节中讲解的是在嵌入式SQL中如何使用SELECT语句、UPDATE语句、DELETE语句和INSERT语句。
1.在嵌入式SQL中使用SELECT语句
在嵌入式SQL中使用SELECT语句是对交互式SELECT语句的补充。嵌入式SQL中使用了INTO语句,并且其返回的结果只有一条记录。
下面通过一个示例来说明如何在嵌入式SQL中使用查询结果为单记录的SELECT语句。
【上机实战】
从员工信息表(employee)中查询员工编号(No)为1001的员工姓名和性别信息,并且将其值赋予主变量
tName和tSex。
EXEC SQL SELECT sName,Sex
INTO :tName,:tSex
FROM employee
WHERE No=1001
代码中的tName和tSex都是前面示例中定义过的主变量。语句返回员工信息表(employee)中员工编号为1001的单行记录信息。
2.在嵌入式SQL中使用UPDATE语句
在嵌入式SQL中使用UPDATE语句的语法形式与使用交互式UPDATE语句的语法形式基本相似。只不过在嵌入式SQL中使用的UPDATE语句中的SET子句和WHERE子句中可以使用主变量而以。
下面通过一个示例来说明如何在嵌入式SQL中使用UPDATE语句。
【上机实战】
通过主变量将员工工资表(EmPays)中所有女员工的工资提高。假设增加的工资已经赋给主变量
AddPays。
EXEC SQL UPDATE EmPays
SET EmPays=EmPays + :AddPays
WHERE EmSex='女'
该代码执行以后,员工工资表(EmPays)中所有女员工的工资提都被更改提高。
3.在嵌入式SQL中使用DELETE语句
在嵌入式SQL中使用DELETE的语法结构中,除了在其WHERE子句中可以使用主变量之外,其他部分都与交互式DELETE语句相同。
下面通过一个示例来说明如何在嵌入式SQL中使用DELETE语句。
【上机实战】
通过主变量将学生信息表(student)中所有年龄大于某值的员工信息删除。假设该值已经赋予了主变量
del_age。
EXEC SQL DELETE
FROM student
WHERE SAge>:del_age;
该代码执行以后,学生信息表(student)中所有年龄大于主变量del_age中值的员工信息都被删除。
4.在嵌入式SQL中使用INSERT语句
在嵌入式SQL中使用INSERT的语法结构中,除了在其VALUES子句中可以使用主变量之外,其他部分都与交互式INSERT语句相同。
下面通过一个示例来说明如何在嵌入式SQL中使用INSERT语句。
【上机实战】
通过主变量向学生信息表(student)中插入数据信息,并且假定表中的各字段信息都存储在主变量stud_no、stud_spno、stud_name和stud_age当中。
EXEC SQL INSERT INTO student
VALUES(:stud_no,:stud_spno,:stud_name,:stud_age);
该代码执行以后,主变量中的数据信息被插入到学生信息表(student)当中。
15.2.5 在嵌入式SQL中使用游标
嵌入式SQL中的一组主变量一次只能存放一条记录。因此,只是使用主变量,并不能完全满足SQL语句向应用程序输出数据的要求。为此,嵌入式SQL引入了游标的概念,用游标来解决上述出现的问题。
在嵌入式SQL中,游标是系统为用户开设的一个数据缓冲区,其用于存放SQL语句的执行结果。用户可以用SQL语句逐一从游标中获取记录,并赋给主变量,然后再通过高级语言程序进行处理,完成相应的操作。
在嵌入式SQL中使用游标主要有以下几个步骤:
(1)定义一个游标,使之对应一个SELECT语句。实现过程可用下面的语句进行表示:
EXEC SQL DECLARE <游标名称> CURSOR FOR <SELECT语句>
(2)打开游标,在定义了游标之后,可以执行游标对应的查询,其结果集合为该游标的活动集。实现过程可用下面的语句进行表示:
EXEC SQL OPEN <游标名称>
此时游标指针定位于结果集中第一行的前一行。
(3)在活动集中将游标移到特定的行,并取出该行数据放到相应的主变量中,其实现的过程可以用下面的语句进行表示:
EXEC SQL FETCH FROM <游标名称> INTO <主变量名称>
(4)关闭游标,游标在使用完成以后,需要释放活动集及其所占用的资源,使它不再和查询结果相联系。其实现的过程可以通过下面的语句进行表示:
EXEC SQL CLOSE <游标名称>
下面通过一个具体的示例来说明如何在嵌入式SQL中使用游标。
【上机实战】
在C语言中使用嵌入式SQL,并且使用了游标。
EXEC SQL INCLUDE SQLCA;
EXEC SQL BEGIN DECLARE SECTION;
CHAR employee_name[10];
CHAR employee_phone[11];
CHAR emoloyee_address[50];
EXEC SQL END DECLARE SECTION;
main()
{EXEC SQL DECLARE employee_Cursor CURSOR FORSELECT sName,sPhone,sAddress;/* 打开游标*/EXEC SQL OPEN employee_Cursor;for(;;){/* 将当前值当道主变量当中*/EXEC SQL FETCH employee_Cursor INTO :employee_name,:employee_phone,:emoloyee_address;if(sqlca.sqlcode<>0)break;/* 输出结果*/printf("姓名:%s,联系电话:%s,联系地址:%s",employee_name,employee_phone,emoloyee_address);}/* 关闭游标*/
EXEC SQL CLOSE employee_Cursor
}
上面示例演示的是在嵌入式SQL中游标最基本的使用方法。下面讲解如何在查询结果为多条记录的SELECT语句中使用游标。
下面的代码演示的是,通过主变量从员工工资表(EmPays)中检索员工姓名(EmName)、员工性别(EmSex)和员工的基本工资(EmBasicPays)信息,其中员工姓名由主变量InName给出。
Void Pays()
{EXEC SQL INCLUDE SQLCA;EXEC SQL BEGIN DECLARE SECTION;CHAR emname[10];CHAR emsex[2];INT empays;
EXEC SQL END DECLARE SECTION;
gets(emname);
EXEC SQL DECLARE emppay_cursor CURSOR FOR
SELECT EmName,EmSex,EmBasicPays
FOR EmPays
WHERE EmName=:emname;
EXEC SQL OPEN emppay_cursor;
WHILE(1)
{EXEC SQL FETCH FROM emppay_cursor INTO :emname,:emsex,:empays;if(sqlca.sqlcode<>0)break;printf("姓名:%s,性别:%s,基本工资:%d",emname,emsex,empays);
}
EXEC SQL CLOSE emppay_cursor;
}
第15章 嵌入式SQL的应用相关推荐
- 第十二章 使用嵌入式SQL(三)
文章目录 第十二章 使用嵌入式SQL(三) 主机变量 主机变量示例 用列号下标的主机变量 `NULL`和未定义的主机变量 主机变量的有效性 主机变量和程序块 第十二章 使用嵌入式SQL(三) 主机变量 ...
- 《SQL必知必会》读书笔记上(第1~15章)
目录 第1章 了解SQL 第2章 MySQL简介 第3章 使用MySQL 3.1 连接数据库 3.2 选择数据库 3.3 显示数据库和表 3.4 其他SHOW语句 第4章 检索数据 4.1 SELEC ...
- 【梳理】数据库系统概论 第8章 数据库编程 8.1 嵌入式SQL 8.2 过程化SQL 8.3 存储过程和函数 8.4 ODBC编程
教材:王珊 萨师煊 编著 数据库系统概论(第5版) 高等教育出版社 注:文档高清截图在后 第8章 数据库编程 标准SQL是非过程化的查询语言,操作统一.面向集合.功能丰富.使用简单.非过程化语言是相对 ...
- 嵌入式系统知识点总结【1-5章】
第一章 嵌入式系统概述 1.嵌入式系统的定义及特点 定义 从广义的角度:嵌入式系统是一切非PC和大型机的计算机系统 从应用的角度:嵌入式系统是以应用为中心,以计算机技术为基础,采用可剪裁软硬件,适用于 ...
- DB2数据库嵌入式SQL开发
如有转载,请注明出处:http://blog.csdn.net/embedded_sky BY:super_bert@csdn 1.1 DB2应用程序开发概述 1.1.1 程序结构 DB2应用程 ...
- 第15章:存储引擎和表类型#innodb的性能调整
原贴:http://dev.mysql.com/doc/refman/5.1/zh/storage-engines.html#innodb-tuning 第15章:存储引擎和表类型 目录 15.1. ...
- linux cached释放_正点原子Linux第四十一章嵌入式Linux LED驱动开发实验
1)资料下载:点击资料即可下载 2)对正点原子Linux感兴趣的同学可以加群讨论:935446741 3)关注正点原子公众号,获取最新资料更新 第四十一章嵌入式Linux LED驱动开发实验 上一章我 ...
- 数据库期末总结笔记(零基础)-第三章 关系数据库SQL
第三章 关系数据库SQL 三.SQL查询 1.基本查询格式 select [distinct] (去重)所查内容 from 所查询的表(可多个)where 要求条件 例:查计算机科学系全体学生 sel ...
- 【正点原子Linux连载】第四十一章 嵌入式Linux LED驱动开发实验 -摘自【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.0
1)实验平台:正点原子阿尔法Linux开发板 2)平台购买地址:https://item.taobao.com/item.htm?id=603672744434 2)全套实验源码+手册+视频下载地址: ...
最新文章
- Saltstack自动化环境部署
- Windows 11,一个新功能,一场新屠杀!
- xml内容过多装不下,怎么实现下滑功能(最简单的下滑功能实现)
- 大型网站后台架构的Web Server与缓存
- matlab复数方程的根,matlab解一元三次方程,得到的都是复数根。
- Python 爬取周杰伦instagram
- 前端经典面试题 不经典不要star!
- Android显存到内存拷贝耗时,memcpy速度太慢?掌握这个技术让内存拷贝效率成倍提升...
- python中while语句是_如何在Python中使用while语句[适合初学者]
- java 6 损坏,Java 异常处理六
- c语言检查tcp连接_TCP/IP的底层队列
- 【第二篇】ASP.NET MVC快速入门之数据注解(MVC5+EF6)
- Python开发过程中错误解决记录【持续更新记录,欢迎交流】
- linux重定向文件容加时间,[单选] linux系统,把当前日期重定向到/tmp/date文件中,并不想覆盖原来的内容,下面正确的操作是()。...
- 【图纸加密】命令lockdwg转换为多重属性块
- 非线性激活函数的作用
- 前沿科技赋能教育,掌门优课创新教学体验
- 单位强制解除与员工的劳动关系怎么办
- Unity获取包名,产品名,版本号等
- Jenkins配置远程服务器SSH Servers节点参数设置说明
热门文章
- 如何让简历中的“岗位业绩”打动HR?
- Mysql current_time,current_date()与now()区别
- 论文阅读笔记:Ultra-Scalable Spectral Clustering and Ensemble Clustering
- SQL入门经典第5版(Sams Teach Yourself SQL in 24 Hours, 5th)随书习题的建表和插入
- Linux中reboot和reset的使用和区别
- Hadoop笔记-02 安装
- vue 地图可视化 (2)
- FPGA零基础学习:半导体存储器和可编程逻辑器件简介
- 分析如何区分MOS管是N沟道还是P沟道-KIA MOS管
- 薛斯通道的十二种买入法和四种卖出法