版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
数据库原理及应用第1页,共29页,2023年,2月20日,星期六嵌入式SQL是指在程序内执行的SQL语句,它强调这些SQL语句是“嵌入”在编程语言的常规语句中的。Java中标准的嵌入式SQL称为SQLJ,可以在ORACLE、INFORMIX、DB2UDB中使用,也可以通过JDBC在Java中使用,JDBC是标准Java的一部分,用来连接任何数据库。我们将重点放在C语言编写的嵌入式SQL程序。在本章中,我们将会碰到两种数据库系统的差别,即oracle和db2udb第2页,共29页,2023年,2月20日,星期六5.1C语言中嵌入SQL的介绍关键词execsql声明SQL语句嵌入到宿主语言源文件中。例如:execsqlselectcount(*)into:host_varfromcustomers;注:1、execsql可以扩展到该文件的多行。2、在嵌入式SQL中使用宿主变量时必须加(:)例:假如字符串变量cust_id在C程序中被赋值为“c001”第3页,共29页,2023年,2月20日,星期六execsqlselectcname,discnt
into:
cust_name,:cust_discntfromcustomerswherecid=:cust_id则检索到顾客编号为c001的顾客的名字和折扣率,并将它们分别赋值给变量cust_name,cust_discnt。
当然,要在嵌入式SQL中使用这些宿主变量,必须先声明它们,包括对预编译程序的声明。第4页,共29页,2023年,2月20日,星期六
execsqlbegindeclaresection;charcust_id[5]=“c001”;charcust_name[14];floatcust_discnt;
execsqlenddeclaresection;这三个变量的声明是标准的C语言中的声明,出现在begindeclare和enddeclare语句之间,这是预编译程序和C语言程序都能理解的相同的格式。嵌入式SQL中使用的宿主变量必须能被数据库系统识别。第5页,共29页,2023年,2月20日,星期六
在SQL中建立和释放数据库连接:考虑怎样与数据库管理系统建立数据库连接。在FullSQL-99中连接到SQL数据库的语法:
execsqlconnecttotarget-server[asconnect-name][userusername]或execsqlconnecttodefaulttarget-server是目标数据库名,connect-name是对这次该数据库连接的一个名字,以后当再次使用是,可以直接引用它;username是该数据库的一个合法用户名。connecttodefault是默认数据库的连接。第6页,共29页,2023年,2月20日,星期六由于不同平台在用户识别、权限要求方面的可变性,connect语句并不是EntrySQL-92和CoreSQL-99的一部分。在ORACLE和DB2UDB中,字符串常量通常不能直接作为connect语句的参数,我们需要首先声明:execsqlbegindeclaresection;
charuser_name[10],user_pwd[10];
execsqlenddeclaresection;设口令“1234”,我们对上述变量初始化:
strcpy(user_name,”cap”);strcpy(user_pwd,”1234”);第7页,共29页,2023年,2月20日,星期六那么在DB2中嵌入式SQL的Connect语句为:execsqlconnectto
cap
:user_name
using:user_pwd;
在ORACLE中嵌入式SQL的Connect语句为:
execsqlconnect:user_name
identifiedby:
user_pwd;简单的断开连接:
execsqldisconnectcurrent/connect_name;注意:
在断开连接之前,必须对成功的事务提交确认,或是对失败的事务回滚以撤消已做的工作,否则直接断开连接会失败。第8页,共29页,2023年,2月20日,星期六对成功的任务结束为:execsqlcommitwork;execsqldisconnectcurrent;对失败的任务结束则为:
execsqlrollbackwork;execsqldisconnectcurrent;在ORACLE中可以使用
execsqlcommitrelease;
或execsqlrollbackrelease;第9页,共29页,2023年,2月20日,星期六例5.1.1实现一个嵌入式SQL程序,要求程序不断提示用户输入一个顾客的cid,显示该顾客的名字和折扣,当用户输入一个空字符串则程序终止。程序头如下:#include<stdio.h>#include”prompt.h”/*headerfordbssqlcastructure*/execsqlincludesqlca;charcid_prompt[]=“pleaseentercustomerid”;第10页,共29页,2023年,2月20日,星期六程序主体代码:intmain(){execsqlbegindeclaresection;charcust_id[5],cust_name[14];floatcust_discnt;charuser_name[20],user_pwd[20];execsqlenddeclaresection;execsqlwheneversqlerrorgotoreport_error;execsqlwhenevernotfoundgotonotfound;strcpy(user_name,”cap”);strcpy(user_pwd,”1234”);execsqlconnect:user_nameidentifiedby:user_pwd;第11页,共29页,2023年,2月20日,星期六while((prompt(cid_prompt,1,cust_id,4))>=0)
{execsqlselectcname,discntinto:cust_name,:cust_discntfromcustomerswherecid=:cust_id;execsqlcommitwork;printf(“customer’snameis%sanddiscntis%5.1f”,cust_name,cust_discnt);continue;notfound:printf(“can’tfind%s“,cust_id)}execsqlcommitrelease;return0;report_error:print_dberror();execsqlrollbackrelease;return1;}第12页,共29页,2023年,2月20日,星期六程序说明:
print_dberror()函数显示数据库系统的错误消息,如ORACLE中的“ORA-00942:tableorviewdoesnotexist”。prompt函数提示用户交互,prompt函数也可以接受用户输入的多个标记,若用户在提示行上键入回车,则返回结果小于0。
C语言编译程序不能识别嵌入式execsql语句的语法,所以源程序必须先通过预编译程序将其转换成C中的正确语句。(参见附录B.3)Whenever语句是条件处理语句,该语句使我们在遇到出错和其他情况时,控制程序的运行。第13页,共29页,2023年,2月20日,星期六其格式如下:
execsqlwheneverconditionaction;例execsqlwheneversqlerrorgotoreport_error;Whenever设置了一个条件陷阱,这样会对所有后面由execsql语句引起的对数据库系统的调用自动检查是否出错条件,若存在这样的出错条件,就必须采取规定的动作。(1)条件
sqlerror
这些错误通常是由编程错误引起的。并且错误代码依赖于某一特定的DBMS。notfound
执行某条SQL语句,如insert、delete、update等,检测是否没有记录受到该SQL语句的影响。第14页,共29页,2023年,2月20日,星期六sqlwarning
检测不是错误但应该引起注意的条件。注意:sqlwarning不是FullSQL-92的标准。(2)动作
continue
不采取任何动作,程序按正常流程
goto标号等同与C语言中的“goto标号”
stop
结束程序的运行,撤消当前的事务,断开与数据库的连接
do函数(ORACLE)、call函数(INFORMIX)引发一个对已经命名的C函数的调用,这一函数返回后,程序从引发该变迁的execsql语句之后继续执行下去。
第15页,共29页,2023年,2月20日,星期六注意:当遇到一条后续的whenever语句覆盖了前面的whenever语句时,程序动作就被改变了。例5.2.1
main(){execsqlwheneversqlerrorstop;
execsqldelete*fromagentswhereaid=‘a03’gotos1;execsqlwheneversqlerrorcontinue;s1:execsqlupdateagentssetpercent=percent+1;…….}第16页,共29页,2023年,2月20日,星期六注意:在没有whenever时,缺省动作是continue;可以通过execsqlwheneversqlerrorcontinue来重建这一缺省动作。我们在使用whenever语句时要注意避免无限循环。例:execsqlwheneversqlerrorgotohandle_error;execsqlcreatetablecustomers(cid……);
由于某个错误(磁盘空间不够等)导致建表失败,控制流转入handle_errorhandle_error:
有问题吗?execsqldropcustomers;execsqldisconnect;return–1;第17页,共29页,2023年,2月20日,星期六删除表时,可能会引起无限循环。故应改为:
handle_error:
execsqlwheneversqlerrorcontinue;execsqldropcustomers;execsqldisconnect;return–1;第18页,共29页,2023年,2月20日,星期六SQL通信区:SQLCASQL通信区,称为SQLCA,是一个已经被声明过的内存结构(C中的结构),它的成员变量用来在数据库系统监视器与程序之间进行信息通信。SQLCA在嵌入式的C程序中声明,通常写在其他的外部声明语句前面。
execsqlincludesqlca;实际上,whenever机制的基础是一个提供了更多与条件有关的信息的错误编码系统。支持SQLCA的产品要填写sqlca.sqlcode(一个与错误码相关的变量)第19页,共29页,2023年,2月20日,星期六注意:SQL-92、SQL-99等标准支持一种新的报告错误的方法,SQLSTATE。在ORACLE中,必须预处理程序运行时设置MODE=ANSI才能支持。在DB2UDB中提供SQLSTATE作为SQLCA的一个成员。SQLSTATE是由一个5个字符的字符串编码组成,前两个字符为“类别编码”,后3个字符为“子类编码”。例如:“00000”代表没有错误,“82100”表示“内存溢出”,对于所有的产品这一编码都是相同的。若whenever语句中采取的动作不是continue,那么要进行显示的错误检测是不行的。第20页,共29页,2023年,2月20日,星期六例5.2.3考虑如下代码段:
execsqlwheneversqlerrorgotohandle_error;…execsqlcreatetablecusts(cidchar(4)notnull,cnamevarchar(13),..);if(strcmp(sqlca.sqlstate,”82100”)==0)<callproceduretohandlethiscondition>注意:虽然预处理程序在createtable之后立即设置了sqlerror检测,但是该错误渐次将永远不会执行。为什么?如何修改?第21页,共29页,2023年,2月20日,星期六execsqlwheneversqlerrorgotohandle_error;…..execsqlwheneversqlerrorcontinue;execsqlcreatetablecusts(cidchar(4)notnull,cnamevarchar(13)..);if(strcmp(sqlca.sqlstate,”82100”)==0)<callproceduretohandlethiscondition>elseif(strcmp(sqlca.sqlsqlstate,”00000”)!=0)gotohandle_error;execsqlwheneversqlerrorgotohandle_error;…第22页,共29页,2023年,2月20日,星期六使用游标选择多行只有当select语句保证每次最多读一行到一个列变量的集合时,才能使用例5.1.1中的嵌入式select语句格式。我们在程序中如何对检索到的多行进行处理呢?一次一行原则
从一条select语句中,我们总是每次查看一行,每次从记录集中检索一行,需要一个游标记录当前位置。第23页,共29页,2023年,2月20日,星期六例如,对一个用户交互提供的一个特定的顾客的编号cust_id,我们需要检索出为该顾客提供定货的代理商aid,以及每个代理商所提供给顾客的定单金额总值。
Execsqlselectaid,sum(dollars)fromorderswherecid=:cust_idgroupbyaid下面,我们为这段select语句声明一个名为agent_dollars的游标。Execsql
declare
agent_dollarscursorfor
selectaid,sum(dollars)fromorderswherecid=:cust_idgroupbyaid第24页,共29页,2023年,2月20日,星期六注意:在游标被声明后,它仍然不是active状态。之后,必须激活该游标:
execsqlopenagent_dollars;
执行程序在碰到该激活语句,向数据库系统检测器发出一个调用,以执行该游标声明的select语句,将查询的结果集保存在数据库系统为该游标创建的系统缓冲区中。然后,我们可以使用fetch语句从该缓冲区中检索连续的记录行:
execsqlfetchagent_dollarsinto:agent_id,:dollar_sum第25页,共29页,2023年,2月20日,星期六当一个游标所有的fetch语句都执行之后,应该执行closecursor语句,关闭游标,释放资源。注:游标中保持一个当前指针,该指针总是指向最近刚刚被检索到的行,在随后的提取调用中,游标的位置指针首先加1,然后这条记录中的值被检索到指定的宿主变量中去。例5.1.2下面给出了一个检索多行的程序:groupbyselect语句列出了代理商的ID值,以及由这些代理商提供给某一用户指出的顾客的定单金额总值。注:该程序是按照DB2UDB的格式第26页,共29页,2023年,2月20日,星期六#inclued<stdio.h>…..execsqlincludesqlca;execsqlbegindeclaresection;charcust_id[5],agent_id[4];doubledollar_sum;execsqlenddeclaresection;
intmain()
{charcid_prompt[]=“pleaseentercustomerid”;execs
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 软件公司总经理聘任合同
- 河道整治自卸车租赁协议
- 政府机构租赁合同-政府
- 垃圾处理保温系统安装协议
- 高空水电站设备维护合同
- 资产转让协议三篇
- 芹菜收购合同范本(2篇)
- 公交车广告违约终止合同通知书
- 集体合同培训材料
- 烟酒货物运输合同范例
- 公路工程设计设计的质量保证措施、进度保证措施
- GB/T 43786-2024音频、视频和信息技术设备生产过程中的例行电气安全试验
- XXX加油站安全验收评价报告
- 超市经营管理方案
- 开源情报行业分析
- 物业企业安全风险管控责任清单
- 4.5.1 函数的零点与方程的解(九大题型)(解析版)
- 2024年江西生物科技职业学院高职单招(英语/数学/语文)笔试历年参考题库含答案解析
- 柜长管理方案
- 散打集体活动策划方案
- 学管师述职报告
评论
0/150
提交评论