




已阅读5页,还剩10页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
嵌入式SQL编程和通过ODBC访问数据库预备知识(供大家学习参考)1)嵌入式SQL编程:嵌入式SQL由SQL语句和C/C+代码组成。其中SQL语句由预处理器翻译成C或C+的源代码。对预处理后的源代码进行编译、连接生成可执行程序后方可运行。l SQL预处理器SQLServer的预处理程序是nsqlprep.exe。其常用的语法格式如下:nsqlprep 程序文档名 n nsqlprep详细的语法格式以及参数意义,请看联机帮助。nsqlprep的语法格式如下:nsqlprep program_file_name /SQLACCESS | /NOSQLACCESS/FLAGGER ENTRY | NONE /DB server_name.database_name /PASS login.password | $INTEGRATED /BIND file_name /MSG file_name /NOLOGO /PLAN name /NOLINES /user_defined_optionn 要求程序文档名的后缀为.sqc,可以省略。n 预编译后得到的文档,与程序文档同名,后缀为.c;放在与程序文档名同一个路径下nsqlprep.exe在SQLServer的安装目录的 MSSQLBinn下。在本机中SQLServer的安装目录是C:Program FilesMicrosoft SQL Server, nsqlprep.exe在C:Program FilesMicrosoft SQL ServerMSSQLBinn。由于默认的安装方式(典型安装)并没有安装应用程序nsqlprep.exe,因此,需要拷贝到该目录下。l 连接方式经预处理后的c文件就可以用c的编译器进行编译连接了。使用Visual C+ 6.0进行编译连接,连接方式是动态连接,用到动态链接库SQLakw32.dll,sqlaiw32.dll;此两文件已经随同binn.rar的其他内容,被拷贝到C:Program FilesMicrosoft SQL ServerMSSQLBinn下;但仍然需要把该路径加到系统的路径变量中,以使得程序运行时能找到这两个文件。方法1:把该两文件拷贝到操作系统目录下的子目录system32中方法2:把C:Program FilesMicrosoft SQL ServerMSSQLBinn加到系统环境变量path中。“我的电脑”-“属性”-“高级”-“环境变量”-“path,编辑”,如下图所示:在变量值中加入该路径值;注意,路径间用分号”;”分开。在实验过程中发现如果只做第二步,在之后的运行过程中会报错,只有将方法一也执行了这个连接的准备工作才算是正式完成。2)通过ODBC访问数据库:配置ODBC,为SQL Server添加数据源。如下图所示:初始化环境:1 SQL Server2000为其嵌入式SQL提供了一些特殊的接口;默认的安装方式(典型安装)并没有安装这些接口;因此,需要把devtools.rar解压到SQLServer的系统目录下(注意,不是安装目录);本机是把操作系统安装在C盘,则SQLServer的系统目录则是C:Program FilesMicrosoft SQL Server。2 初始化SQL Server的预编译环境。n 初始化Visual C+ 6.0 编译器环境,运行文件:Microsoft Visual StudioVC98BinVCVARS32.BAT这个过程要在DOS下运行才有效,即找vcvars32.bat的路径,在DOS下运行。具体步骤如下:n 初始化SQLServer的预编译环境,运行文件:devtoolssamplesesqlcsetenv.bat。运行方式与vcvars32.bat相同,结果如下:3 初始化Visual C+ 6.0环境。n Tools-options-directories-Include Files: C:Program FilesMicrosoft SQL Serverdevtoolsincluden Tools-options-directories-LibFiles:C:Program FilesMicrosoft SQL Serverdevtoolsx86lib注意:这些路径需要设为第一项。如下图所示:n Project-Settings-Link-Object/Library Modules,添加库文件:SQLakw32.lib,Caw32.lib注意,两个文件之间用空格分开。实验活动1. 阅读和分析程序esql.sqc,解释程序的主要内容和主要数据结构。程序的主要内容:嵌入式SQL的使用,将SQL嵌入到C语言中,在SQL的数据库中通过SELECT语句获取数据,并将获得的信息通过主变量传递给主语言并打印输出。给出的程序中将程序连接到SQL服务器上的pubs数据库上,查询满足以下SELECT语句的数据信息:select EmployeeID from orders where OrderID = 345查询得到的结果由主变量EmployeeID传给主语言(C语言),C语言得到数据信息后打印输出。程序分为以下几块:1) 主变量的声明:在EXEC SQL BEGIN DECLARE SECTION;和EXEC SQL END DECLARE SECTION;之间声明主变量EmployeeID。2) 连接到DBMS:连接到数据库的管理系统以便从中查询登陆的数据库。连接到数据库的语法为:EXEC SQL CONNECT TO SQLServer.DataBaseName USER logName.passwd3) 查错:为了更好的判断和查找错误以修改程序,所以在每次执行完SQL语句后都应该对sqlca所返回的状态值加以判断。若sqlcode等于0,则输出建立成功信息,否则报错。4) 执行查询:在这里嵌入SQL的查询语句EXEC SQL select EmployeeID INTO :EmployeeID from orders where OrderID = 345 ,并通过主变量EmployeeID返回查询到的结果,打印结果。5) 断开所有连接:执行完所有的数据库的访问后,断开所有的连接以释放系统资源。语法为:EXEC SQL DISCONNECT ALL;数据结构:主要为在数据库中存储的表,及针对表进行的查找。2. 对程序esql.sqc作适当的修改,使之可以在本地系统上可以运行。进行预处理、编译、连接(lib连接),查看运行结果。1)修改:只需要对连接的服务器及数据库进行修改即可:EXEC SQL CONNECT TO SKY.pubs USER abc.abc;(SKY 为SQLServer,根据自己的定义的名称修改)同时由于pubs数据库中没有orders表,所以对SELECT语句也作了修改如下:EXEC SQL select emp_id INTO :EmployeeID from employee where lname = Accorti;2)进行预处理:将esql.sqc文件放在C:Program FilesMicrosoft SQL ServerMSSQLBinn目录下,运行cmd,进入C:Program FilesMicrosoft SQL ServerMSSQLBinn目录,用nsqlprep esql.sqc的方式运行该文件,可以在C:Program FilesMicrosoft SQL ServerMSSQLBinn中找到预编译后生成的.c文件。运行过程显示如下:3)连接操作已经在前面的初始化环境过程中完成。4)出现的怪异问题:尽管之前的准备步骤都已经全部做完,但是在预编译时总是会出现以下问题,每次都要重新把安装文件下的BIN和DEVTOOLS重新拷一遍到C盘SQLSERVER相应得路径下,然后再在DOS下运行setenv.bat和vcvars32.bat两个文件才能解决这个问题,有时甚至所有步骤都要重新做一次。思考:l sqlca结构中主要的数据项有哪些?我们常用的有哪些?sqlca是一个含有错误变量和状态指示符的数据结构。通过检查sqlca,应用程序能够检查出嵌入式SQL语句是否成功,并根据成功与否决定是否继续往下执行。与编译器自动在嵌入SQL语句中包含SQLCA数据结构。从联机帮助上我们可以找到,SQLCA结构中主要的数据项如下(用结构体表示):在SQLCA中我们经常用到的是sqlcode,它用来记录最近执行的SQL状态:0 :表示该SQL语句被正确执行,无错误发生0 :表示执行了该语句,但遇到了错误0 :表示由于数据库、系统、网络或应用程序错误等等原因未执行该语句l SQL操作的常见的错误类型有哪些?如何得到错误信息?举例说明SQL中常见的错误类型有:通过下面的这些返回值,可以得到相应的出错信息。Message numberRun time/compile timeDescription-4998CAttempt to connect to the specified database server failed.-19031CUnable to open bindfile.-19051CToo many sections.-19101RStatement too long.-19103RIllegal %s value %s.Nonnumeric %s value %s.(Invalid number for the time-out value.)-19104R/CIncorrect SQL statement syntax.-19199CESQL keyword(s) detected in PREPARE statement.-19306CHost variable used but not declared.-19313RToo few host variables.-19324CHost variable may not be used in this context.-19408RInvalid SQL data type for SQL_TYP_DECIMAL.-19413RData overflow occurred during decimal data conversion.-19422RUnknown SQL Server data type.-19423RInvalid destination data type.-19501RNo cursor declared.-19505CDuplicate cursor name: %s.-19508RCursor not positioned on a row.-19514RCursor not prepared.-19517RCursor open attempted for non-SELECT prepared statement.-19521ROpen cursor failure for section %d of plans.-19523RFailure to locate/close cursor. Section %d, plan %s.-19524RTable for this cursor not updatable.-19525RAttempt to fetch on unopened cursor.-19526RNo access plan for this cursor.-19527RCould not get section for this cursor.-19528RConnection for section %d of plan %s has NULL DBPROCESS.-19701RNULL connection name. Connection %s not found.-19702RConnection name not found. Attempt to close nonexistent connection.-19703RFailed to get DBPROCESS. Autoconnect failure.-19706RLogin failure in section %d.-19707RDuplicate connection name.-19822RImproperly initialized user SQLDA.-19911CThe SQL data type specified for a host variable is invalid.-19913CThe token identifier has already been used.-19917CInvalid or incorrect option to sqlainit().-19946CCursor %s not declared.-19953CInvalid call type.-19955RText not found in %s section %u.-19956RAccess plan section or statement text not found.-19957RAccess plan or statement text not found.-19994RCannot run next BEGIN DECLARE sections. Statement ignored.-19995REND DECLARE encountered without preceding BEGIN DECLARE statement. Statement ignored.-19999CAn internal error occurred.连接DBMS错误通过sqlca中的变量sqlcode的返回值获得错误信息,当返回值为0时,表示连接成功,否则,连接失败。例如esql.sqc中用以下语句获得错误信息: if (SQLCODE = 0) printf(Connection to SQL Server establishedn); else / 连接DBMS错误 printf(ERROR: Connection to SQL Server failedn); return (1);l 如何处理SQL操作的错误信息?a) 对于DBMS连接错误:检查连接是否正常:1)看SQL服务器是否启动 2)所连接的数据库是否存在 3)登录用户是否具备相应的权限(登录用户的数据库角色) 4)网络连接端口(1433)是否打开b) 用sqlcode:在程序的error段输入如下语句:error:printf(错误%dn,SQLCODE);根据sqlcode的值查看联机帮助,根据在联机帮助上查到的错误信息检查相应的SQL语句,针对性的进行修改,直到其能正确运行c)WHENEVER语句:在每条嵌入式SQL语句之后立即编写一条检查SQLCODE值的程序是一件很繁琐的事情,为了简化错误处理,可以使用WHENEVER语句: WHENEVER是说明语句,不是可执行语句,不返回SQLCODE,只是根据SQLCA中的返回码指定相应的措施。它通知预编译程序在每条可执行嵌入式SQL语句之后自动生成错误处理程序,并指定了错误处理操作。用户可以使用WHENEVER语句通知预编译程序去如何处理三种异常处理:lWHENEVER SQLERROR action:表示一旦sql语句执行时遇到错误信息,则执行action,action中包含了处理错误的代码(SQLCODE0)。lWHENEVER SQLWARNING action:表示一旦sql语句执行时遇到警告信息,则执行aciton,即action中包含了处理警报的代码(SQLCODE=1)。lWHENEVER NOT FOUND:表示一旦sql语句执行时没有找到相应的元组,则执行action,即action包含了处理没有查到内容的代码(SQLCODE=100)。针对上述三种异常处理,用户可以指定预编译程序采取以下三种行为(action):lWHENEVER GOTO:通知预编译程序产生一条转移语句。lWHENEVERCONTINUE:取消先前的WHENEVER语句的作用,通知预编译程序让程序的控制流转入到下一个主语言语句。lWHENEVERCALL:通知预编译程序调用函数。例如:EXEC SQL WHENEVER SQLERROR GOTO er1 EXEC SQL INSERT INTO student VALUES (s1, .)EXEC SQL INSERT INTO student VALUES (s2, .)经过预编译后会转换为以下语句:EXEC SQL INSERT INTO student VALUES (s1, .)If (sqlca.sqlcode 0) goto er1 ;EXEC SQL INSERT INTO student VALUES (s2, .)If (sqlca.sqlcode 0) goto er1;出错处理函数如下: void hSQLError(char *msg) printf(n%s,%ld,%sn, msg,sqlca.sqlcode,(char *)sqlca.sqlerrm.sqlerrmc); EXEC SQL ROLLBACK RELEASE; exit(-1); l 如何断开连接,并释放资源清除环境?建议尝试程序esql.sqc的方法以外的别的方法。释放资源清除环境:EXEC SQL COMMIT WORK RELEASE;断开连接:EXEC SQL DISCONNECT ALL;/断开所有连接EXEC SQL DISCONNECT connection_name;/如果在连接时定义了连接名,则可通过断开连接名来断开连接(如定义了EXEC SQL CONNECT TO SKY.pubs AS Myconnection USER sa.sa;就可以通过EXEC SQL DISCONNECT Myconnection断开和数据库pubs的连接,此语句对和其他数据库的连接无效)EXEC SQL DISCONNECT CURRENT;/表示断开当前连接3. 阅读和分析程序odbc.cpp,解释程序的主要内容和主要数据结构。程序的主要内容:在连接到的数据源上查询sno=s1的sname和city.程序主要分为以下几块:以下为程序开始部分:1) 定义retcode, henv, hdbc,hstmt四个变量,分别对应错误返回码, 环境句柄, 数据库连接句柄,语句句柄;2) 用SQLAllocHandle分配环境变量,同时用SQLSetEnvAttr告诉odbc这是一个odbc3.0的应用程序;3) 用SQLAllocHandle分配连接句柄;4) 用SQLConnect连接数据库;以下为程序主体部分:5) 使用SQLAllocHandle分配语句句柄;6) 用SQLExecDirect或别的语句执行表的创建,查询,及修改;7) 用SQLBindCol把某个结果属性列绑定到变量上,用SQLFetch获取查询信息;或是用SQLFetch和SQLGetData来获取查询信息。以下为程序结束部分,释放所有句柄和环境空间:8) 用SQLFreeHandle释放语句句柄;9) 用SQLDisconnect断开连接;10) 用SQLFreeHandle释放连接句柄11) 用SQLFreeHandle释放环境句柄4. 对程序odbc.cpp作适当的修改,使之可以在本地系统上可以运行。进行编译、连接,查看运行结果。首先配置ODBC,为SQL Server添加数据源,如下图:添加了sqlhw数据源,其配置如下:更改默认数据库为exp之后要在程序中对数据源以及登录ID和密码做修改,修改如下: char* szDSN = sqlhw;char* szUID = abc;/log namechar* szAuthStr = abc;/passward并对SELECT语句做相应的修改,修改为如下查询语句:SElECT sname,city FROM provider where sno=s1查询结果如下:思考:a) 如何判断调用ODBC函数是否正确?常见的错误类型有哪些?如何得到错误信息?举例说明在驱动程序执行ODBC函数的时候会根据其执行情况返回不同的代码,数据类型为ERTCODE。函数的返回码有一下几种取值:l SQL_SUCCESS 返回值为0,执行成功,无错误信息。l SQL_SUCCESS_WITH_INFO返回值大于0, 函数执行成功,但可能产生了非致命的错误。l SQL_ERROR 返回值小于0,函数执行失败。l 此外还有一些在我们这次实验用不多的返回值。可以使用两个 ODBC 函数调用来检索 ODBC 信息:SQLGetDiagRec 和 SQLGetDiagField。若要获得 SQLState、pfNative 和 ErrorMessage 诊断字段中与 ODBC 有关的主要信息,则调用 SQLGetDiagRec,直到它返回 SQL_NO_DATA 为止。可对每个诊断记录调用 SQLGetDiagField 以检索个别字段。所有驱动程序专用字段都必须用
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025合同签订与履行管理规程
- 医学教育评估体系的创新与挑战
- 小麦抗白粉病育种中的全基因组关联分析
- 阅读力的培养
- 共创绿色愿景
- 关节镜穿刺术后护理
- 2025养殖场的租赁合同范本
- 家畜繁殖学试题及答案
- 2025合同范本 初创企业股权分配的6大核心、4条原则、3步落地、5大陷阱指南
- 化学考试综合试题题库及答案
- 2024北京朝阳区四年级(下)期末语文试题及答案
- 规划退让地界协议书
- 电缆拆除合同协议
- 房子回收合同协议
- 2025-2030中国石头纸产业发展深度分析与运营机制风险研究报告
- 2025年安徽省中考化学模拟试卷(含答案解析)
- 精神科病人藏药护理措施
- 小学道德与法治学业水平测试要点解析
- 某引水式水电站-压力钢管安装技术措施
- 2025-2030快速换模系统行业市场现状供需分析及投资评估规划分析研究报告
- 榫卯结构科普课件
评论
0/150
提交评论