C语言与嵌入式SQL混合编程及图像处理技术
SQL Server是现阶段应用程序最普遍采用的数据库技术,在数据库中对图像、视频和声音等数据的存取需要越来越频繁。普通数据可直接在用户定义的字段上存取,而这类被称为二进制大对象(Binary Large Object)的大数据块由于其数据量太大,不是作为数据记录的一部分被存储在数据记录页中,而是存储在其所属的一组专用页中,数据表的对应字段中仅是一个十六进制的指针,该指针指向存放该记录的页面。由于SQL语言是一种面向集合运算的描述语言,其本身不具有过程性结构,使用SQL Server中的Image类型字段存放图像文件时,Image类型字段是只存储位串,SQL Server不对它进行编译,而是由应用程序完成解释。又因Image类型的字段内容在SQL Server 2000中不能使用INSERT和UPDATA等语句进行插入和更新,所以需编写专门的过程来处理图像字段。尽管在SQL Server 2005可以使用有关的函数解决这一问题,但由于实际的应用系统是非常复杂的,数据库访问只是其中一个部分,有些用户交互、图形化输入输出数据只能用高级语言实现。利用高级语言的过程性结构来弥补SQL语言实现复杂应用方面的不足, 将SQL语言嵌入到C语言的嵌入式编程将有广泛的应用前景。
1 嵌入式SQL及语法要素
1.1 C语言嵌入式语句[1]
SQL语言可以嵌入到C语言中使用,数据库管理系统一般采用的处理方法是预处理方法。预处理方法就是从含有主程序C语言和SQL语句的程序开始的。首先,把程序提交给一个专门用于C语言和SQL实现方式的预编译器,预编译器从C语言代码中剥离SQL语句,把SQL语句转换成C语言调用语句,以使用C语言编译程序,并将整个编译成目标代码,链接到各数据库并形成可执行文件。在C语言中嵌入SQL语句产生应用程序的过程为[2]:编辑C源代码+嵌入式SQL→SQL预编译器→C编译器→链接程序(DLL导入库)→应用程序(数据库)。
1.2 嵌入式SQL的语法要素
(1)创建嵌入式语句。将SQL嵌入到C语言中混合编程,程序中会含有两种不同计算模型的语句。为了区别SQL语句与C语句,须在所有的SQL语句前加前缀EXEC SQL,且以分号结束,一般形式为“EXEC SQL ”。嵌入式语句分为可执行语句和说明性语句,可执行语句用来完成在交互式环境下的SQL语句中的数据定义、数据操纵和数据控制任务,说明性语句用于声明通信区和SQL变量等。
(2)SQL通信区。SQL Server数据库管理系统提供了一个通信区SQLCA,用于存储SQL语句运行时DBMS反馈给应用程序的状态,这些信息主要描述系统当前工作状态以及运行环境等。应用程序从SQLCA中取出这些状态信息,以决定接下来执行的语句。在C语言中定义为SQL通信区的语句为:EXEC SQL INCLUDE SQLCA。
(3)主变量。嵌入式SQL语句中可以使用C语言的程序变量及主变量来输入或输出数据。一个主变量可以附带一个任选的指示变量用来指示返回给主变量的值是否为NULL值以及返回给主变量的字符串是否发生了截断。输入主变量出现于SQL语句中时,可在前面加冒号(:)以区别表字段名。而定义输出变量用指示变量的方法,是在SQL语句EXEC SQL BEGIN DECLARE SECTION与EXEC SQL END DECLARE SECTION之间进行说明。
(4)链接数据库。C程序的主函数中应包含一条登录语句,向预编译和程序提供用户名和口令,以实现与SQL Server数据库管理系统建立链接。其命令语法为:EXEC SQL CONNECT TO 服务器名.数据库名AS链接名 USER 用户名.口令。
2 SQL Server中图像数据处理技术
2.1 SQL Server 2000图像存储方法
SQL Server 2000中,对于小于8 000 B的图像数据可以使用二进制数据类型(binary、varbinary)表示,但通常要保存的图像都大于8 000 B,对于这类大对像数据,系统提供了Image数据类型。Image数据类型不同于其他数据类型,该字段内容不能使用标准INSERT和UPDATE等语句进行插入和更新,因此用C语言程序[3]来编写处理图像文件,需要先将图像文件等数据转换成十六进制后存储,再将Image列中的数据存储为位串。SQL Server不能对它进行解释,Image列数据的解释必须由应用程序完成,这与普通的数据存储方式是不同的。Image列所做的全部工作就是提供一个位置用来存储组成图像数据值的位流,这需用到SQL Server中的TEXTPTR、WRITETEXT和UPDATETEXT等函数进行图形的添加和修改。以下是一个C语言与SQL Server 2000的嵌入式编程及图像处理的实例,程序给出的是解决该问题的核心部分。
Demo1.sqc
#include
#include
#define Buffer_Size 1024
EXEC SQL INCLUDE USERCA;
//filein为.jpg文件,fileout为.txt文件
void imagetofield(char *filein,char * fileout)
{
EXEC SQL BEGIN DECLARE SECTION;
FILE *fin,*fout; int j, Len;
unsigned char buffer1[Buffer_Size+1];
unsigned char buffer2[Buffer_Size*3+1];
unsigned char *Temp;
EXEC SQL END DECLARE SECTION;
if(!(fin=fopen(filein, rb )))
return;
if(!(fout=fopen(fileout, w)))
{fclose(fin);return;}
Len=fread(buffer1, sizeof(char), Buffer_Size, fin);
Temp=buffer2;
while(Len==Buffer_Size)
{ for(j=0;j
{ fprintf(fout,%X,buffer1[j]);
Temp+= 3; };
//这样就把二进制的数据转换成为16进制的字符串,
并且存储到buffer1当中了
fwrite(buffer1, sizeof(char), nLen*3, fout);
Len=fread(buffer1, sizeof(char), Buffer_Size, fin); }
fclose(fin);
fclose(fout);
……
EXEC SQL CONNECT Serverl:mydb USER sa.sa;
EXEC SQL CREATE TEALE(sno char(9), sname char
(20), resume nvarchar(max),photo image);
//表中插入一条记录,并初始化photo字段
EXEC SQL INSERT INTO teacher VALUES (’1001’,
’Arlen’,’’,0xfffffff)
加入微信
获取电子行业最新资讯
搜索微信公众号:EEPW
或用微信扫描左侧二维码