现在的位置: 首页 > 综合 > 正文

用于C语言与SQL Server的嵌入式SQL编程技术

2013年10月08日 ⁄ 综合 ⁄ 共 4410字 ⁄ 字号 评论关闭

张华,张淼,郑宏珍
(哈尔滨工业大学,山东 威海 264209)
收稿日期:2006-02-19
作者简介:张华(1978-),男,理学硕士,研究方向:Web信息提取,ERP,多媒体技术;张淼,女,硕士;郑宏珍,女,博士生,副教授,硕士导师。
摘要:针对嵌入式SQL编程技术,本文论述了C程序中嵌入SQL语句的代码格式,嵌入式SQL语言与C语言之间的通信方式以及嵌入式SQL应用程序在VC++6.0中的编译过程,并给出了直观的代码实例。
关键词:C语言;SQL Server;嵌入式SQL;VC++6.0

中图法分类号:TP311    文献标志码:A    文章编号:1009-3044(2006)14-0102-01
Programming Embedded SQL for C-language and Database of SQL Server
ZHANG Hua, ZHANG Miao, ZHENG Hong-zhen
(School of Computer Science and Technology, Weihai 264209, China)
Abstract: As to programming technology of Embedded SQL, the code format of Embedded SQL in C applications and the communication modes between C-language and sentences of Embedded SQL were discussed in the paper. The compiling processes of Embedded
SQL Application based on C-language and Database of SQL Server was also shown detailedly in VC++6.0. At last, an example was given in order to attaining an intuitionistic understanding of Embedded SQL programming for C-language and Database of SQL Server.
Key words: C-language; SQL Server; embedded SQL; VC++6.0

1 引言
    基于数据库的操作中,许多事务处理应用都是过程性的,需要根据不同的条件来执行不同的任务,因此单纯用SQL语言是很难实现这类应用的。为了解决这一问 题,将SQL语言嵌入到某种高级语言中使用,利用高级语言的过程性结构来弥补SQL语言实现复杂应用方面的不足,这种方式下使用的SQL语言称为嵌入式 SQL(Embedded SQL),而嵌入SQL的高级语言称为主语言或宿主语言[1]。下面就用于C语言与SQL Server的嵌入式编程技术给以详细论述。

2 C程序中嵌入SQL语言的代码格式
    在C程序中,为了能够区分SQL语句与C语言语句,所有SQL语句都必须加前缀EXEC SQL。例如一条SQL语句:"DROP TABLE emp",嵌入到C程序中,应写作"EXEC SQL DROP TABLE emp"。

3 C语言与SQL语言的通信
    嵌入SQL的C语言应用程序中,SQL语句负责操纵数据库,具有面向集合的性质,C语句负责控制程序流程,具有面向过程的性质。因此,弄清这两种不同计算模型的语句间的通信方式是至关重要的[2]。

3.1 通过SQLCA通信结构通信
    应用程序执行时,每执行一条SQL语句,就返回一个状态符和一些反映SQL语句执行情况的附加信息。这些信息有助于分析应用程序的错误所在,它们都存放在 sqlca.h的SQLCA结构体中。SQLCA是SQL与宿主语言的通信区,其常用的结构成员sqlcode用于保留最近执行的SQL语句的状态 码,sqlerrmc用来保留与sqlcode中的状态码对应 的错误信息文本。嵌入SQL语句的C程序都必须要加入一条语句,即EXEC SQL INCLUDE sqlca.h。

3.2 通过主变量通信
    负责SQL语句与C语句数据交换的是主(Host)变量,这种变量既可以用在SQL语句中,又可以用在C语句中。主变量必须在DECLARE SECTION中说明,说明格式与举例详见表1。

3.3 通过游标通信
    一条SQL语句原则上可以产生或处理多条记录,而一组主变量一次只能存放一条记录。因此,仅使用主变量并不能完全满足SQL语句向应用程序输出数据的要 求。为了解决这个问题,嵌入式SQL引入了游标的概念来协调这两种不同的处理方式。游标是系统开设的一个数据缓冲区,存放SQL语句的执行结果集。每个游 标区都有一个名字,用户可以用SQL语句逐一从游标中获取记录,并赋给主变量,交由主语言进一步处理。与游标有关的命令共有四条,功能与格式详见表2。

表1:主变量声明格式及举例

表2:游标命令及格式

    嵌入SQL的C应用程序具体到VC++6.0、SQL Server2000下调试可分为五步:(1)环境初始化;(2)预编译;(3)编译;(4)连接;(5)运行。下面就其中重要的操作方法给以详细说明。

4.1 环境初试化
(1)SQL Server2000为其嵌入式SQL提供了一些特殊的接口;默认的安装方式并没有安装这些接口;因此,需要把devtools.rar解压到SQL Server的系统目录下;如果操作系统安装在C盘,则SQL Server的系统目录是:C:\Program Files\Microsoft SQL Server。
(2)初始化Visual C++6.0编译器环境。在命令行方式下运行文件:\Microsoft Visual Studio\VC98\Bin\vcvars32.bat。
(3)初始化SQL Server的预编译环境。在命令行方式下运行文件:\Devtools\samples\esplc\setenv.bat。
(4)VC++6.0环境配置。具体配置分为如下三步[3]:
[1]Tools->options->directories->Include
Files: C:\Program Files\Microsoft SQL Server\devtools\include
[2]Tools->options->directories->Lib
Files: C:\Program Files\Microsoft SQL Server\devtools\x86lib
[3]project->Settings->Link->Object/Library Modules,添加库文件:SQLakw32.lib,Caw32.lib。这两个文件之间用空格分开。

4.2 预编译
    C语言编译程序不能识别应用程序中的SQL语句,需要经过预处理程序将其转换成C语句。SQL Server的预处理程序是nsqlprep.exe。nsqlprep.exe在SQL Server安装目录的MSSQL\Binn下。若SQL Server数据库采用的是默认安装方式,则需要把binn.rar的内容拷贝到指定目录下。nsqlprep.exe的常用语法格式与相关说明见表3。

表3:nsqlprep语法格式与相关说明

4.3 编译、链接与运行
    在VC++6.0中创建一个“WIN32 Console Application”类型的Project,然后将预编译生成的c文件加入Project,编译连接即可生成访问SQL Server的可执行程序[4]。Visual C++6.0进行编译连接时需要用到动态链接库SQLakw32.dll与SQLaiw32.dll;尽管这两个文件已经随同binn.rar被拷贝到 SQL Server安装目录的MSSQL\Binn文件夹下,但仍然需要把它们的路径加到系统路径变量中,以使得程序运行时能找到它们,具体添加方法如下:
    方法1:把这两个文件拷贝到操作系统目录下的system32子目录中。
    方法2:“我的电脑”->“属性”->“高级”->“环境变量”->“path,编辑”,在变量值中加入路径值;新路径已有路径间用“;”间隔。

5 程序实例
    下面给出带有嵌入式SQL的一段C程序,一提高对嵌入式SQL应用程序的感性认识。
......

EXEC SQL INCLUDE sqlea.h;/*(1)定义SQL通信区 */
EXEC SQL BEGIN DECLARE SECTION;/*(2)说明主变量开始*/
CHAR title_id(7);
CHAR title(81);
INT royalty;
EXEC SQL END DECLARE SECTION;/*说明主变量结束*/
main()
{
    EXEC SQL DECLARE C1 CURSOR FOR	/*(3)游标操作(定义游标)*/
    SELECT tit_id,tit,roy FROM titles;/*从title表查tit_id,tit,roy*/ 
    for(;;)
    {
    /*(5)游标操作(将当前数据放入主变量并推进游标指针)*/
    EXEC SQL FETCH C1 INTO:title_id:title,:royalty;
    /*(6)利用SQLCA中的状态信息决定何时推出循环*/
    if(sqlca.sqlcode<>SUCCESS)
    break;/*打印查询结果*/
    printf("Title ID:%s, Royalty:%d",:title_id,:royalty");
    printf("Title:%s",:title);
    }
    EXEC SQL CLOSE C1;/*(7)游标操作(关闭游标)*/
}

6 总结
    当一个程序既要访问数据库,又要处理数据时,把SQL语言嵌入到宿主语言中,将SQL语言访问数据库的功能和宿主语言的数据处理功能相结合,是解决该问题 的有效途径。需要说明的是用于C语言与SQL Server的嵌入式SQL编程不是线程安全的[5]。如果在C程序的一个线程应用中使用嵌入式SQL,那么应该仅仅在一个单一线程中调用嵌入式SQL, 最好在主线程中使用。
参考文献:
[1]萨师煊,王珊。数据库系统概论[M]。高等教育出版社。2000,2.
[2]杨安祺,单振芳,杨竞澜。基于C/C++与ORACLE9i的嵌入式SQL编程技术[M]。微计算机信息。2005,2。
[3]丁益祥。嵌入式SQL语言在VC中的实现[J]。武汉科技学院学报。2003,8。
[4]颜昌学。一种嵌入式SQL语言在VC++中的实现方法[J]。西南民族大学学报。2003,6。
[5]ESQL/C资料。http://www.ddvip.net/OS/scounix/index2/57.htm[EB/OL]。2005,3。
[6](美)Robison.L.著;黄惠菊,张捷等译。轻松掌握用Visual C++6对数据库编程[M]。电子工业出版社。1999,6。
[7]袁鹏飞。SQL Server 7.0数据库管理与应用开发[M]。人们邮电出版社。1999,5。

抱歉!评论已关闭.