将图片或文件内容保存到SQL的Text字段的另一种方法

来源:百度文库 编辑:神马文学网 时间:2024/04/28 13:03:23
将图片或文件内容保存到SQL的Text字段的另一种方法
[ 2005-12-08 09:17:34 | 作者:Admin ]
:||
前段时间本人用VFP9做了一个节目管理软件(C/S结构),后台使用SQL,连接方式采用SPT即使用ODBC连接。在这套软件中
涉及到剧照文件的处理问题。当时也反复试验,又不想使用远程视图来做,最后找到这条思路。
1、图片 保存到 SQL表的Text字段
lnID = &&节目ID号
lcPicJZ = FileToStr(FileName)+chr(0) && 读入字符串变量 ** 注意在图像数据后加ASC代码为0的字符
lcCommand = ‘INSERT INTO 节目剧照信息库 (Jmid, 剧照) Values (?lnId, ?lcPicJZ)‘
=SQLPREPARE(gHandle, lcCommand) && gHandle 是通过SQLCONNECT()或SQLSTRINGCONNECT()函数返回的连接句柄
=SQLEXEC(gHandle) && 提交SQL语句
即完成图片的保存
2、将保存到SQL表的Text图像数据显示到Image控件或生成一个图像文件
lnID = &&节目ID号
=SQLEXEC(gHandle, ‘select 剧照 from 节目剧照信息库 where Jmid=‘+str(lnID,20), ‘tmp_DB‘)
ThisForm.ImgJZ.PictureVal = LEFT(tmp_DB.剧照, LEN(tmp_DB.剧照)-1)
** 上面语句中 LEFT()函数去除图像数据后加ASC代码为0的字符
&&保存到文件 StrToFile(LEFT(tmp_DB.剧照, LEN(tmp_DB.剧照)-1), ‘图像文件.bmp‘)
今天看了MiHu大侠的方法感觉也不错,但就本文引用部分有不同意见,读入数据后无需使用STRCONV()函数进行转换
也能保存进入,本人今天又反复试验了以下,用这种方法将2M多的图片及RAR文件保存到SQL表中,再还原成文件都
没有发生丢失现象。我当初试验的时候开始没有在读入数据后加chr(0) SQLEXEC 这条语句会偶尔出错,多次试验后
加了ASC代码为0的字符就没有这个问题了。随便读图片,文件都没有问题。
另外我觉得在VFP5-VFP9中这种方法都适用,只是在低版本中FileToStr,StrToFile这些函数要使用FOpen,FRead,FWrite
这些函数来代替啦。
这个方法本人试验了好几天,希望能给网友方便!欢迎各位大侠发表这方面的心得,请多指点!
+ chr(0)
呵呵,这个方法好啊,当初我可没想到,如果是今天以前我会非常感谢你的,不过现在我研究出了用blob来保存,那可比你的更加方便简单。
因为: PictureVal(LEFT(tmp_DB.剧照, LEN(tmp_DB.剧照)-1)) 这个应该是你的自定义函数吧,你的图片还是要还原成文件,然后再绑定到Iamge控件上?我估计这里你是写错了吧。
就算你是直接用LEFT(tmp_DB.剧照, LEN(tmp_DB.剧照)-1),其过程还是经过了转化,而我得到的Cursor里的blob可以直接绑定Image控件,不需要再经过任何转换,你说效率哪个高?如果再结合VFP9 CA的DelayedMemoFetch新功能(经测试Blob型字段也完全可以使用DelayedMemoFetch功能),其编程方便性和程序运行效率是SPT根本无法做到的。
不过还是要谢谢你,让我知道了+CHR(0)可以避免字节缺失。
十分感谢MiHu大侠的指正, 关于文中确实多写了一个PictureVal ,现在已经更正。
本菜鸟这篇文章是希望能对以SPT方式下操作SQL数据表中的图像数据提供方便。
顺便再介绍一下MiHu大侠贴中所提及的几个术语意思,希望对和我一样菜鸟级的VFP爱好者能有所帮助。
1、BLOB
BLOB数据类型没有固定的长度限制,与Memo类型有些相似。它被存储在以.FPT结尾的文件中,被.DBF文件引用。BLOB字段与Memo字段有相同
的限定条件,并且他们都不支持索引。
与VarBinary数据类型一样,Visual FoxPro 9不会将BLOB类型作代码页转换,而是保持它原始的二进制格式。
BLOB数据类型的设计意图旨在取代最初的Gerneral字段。如果图形或者其它一些媒体类型以BLOB的格式存储,可用Image控件的PictureVal属
性对它们进行浏览。
MEMO与BLOB类型的数据不能直接修改,如果直接修改的话,那只会显示它们的16进制的映像。
2、blob可以直接绑定Image控件
就是将Blob字段的值 直接赋于Image控件的PictureVal
例如 ThisForm.Image1.PictureVal = tmp_DB.图形
3、CA 就是指 CursorAdapter 类
CursorAdapter类是VFP8中最重要的新功能之一,因为它提供了一种简单易用、接口统一的访问远程数据源方式。
访问一个后台数据库你可以使用以下机制:
a、远程视图,它基于 ODBC 连接;
b、SQL Passthrough (SPT) 函数,例如 SQLCONNECT()、SQLEXEC() 和 SQLDISCONNECT(),它们也基于 ODBC 连接;
c、ActiveX Data Objects ,简称 ADO,它提供了一个对各种数据库引擎的 OLE Provider 的一个面对对象访问方式;
d、XML,它是一个轻量级的、平台无关的数据传输机制。
有关CursorAdapter 类的详细介绍大家可以在网上找到很多这样的介绍资料,我就不多做介绍了。
4、DelayedMemoFetch
vfp8的CA有一个FetchMemo属性
如果设置FetchMemo= .F.
那Memo字段的内容会不读取,但如果需要里面的内容就会变的非常麻烦VFP9开始有了DelayedMemoFetch方法
可以做到,cursorFill()的时候,Memo里面全空但,当光标移动到Memo字段的时候才自动读取当前条记录的Memo字段内容
注意是:当前条记录的Memo字段内容这个方法能极大的提高读取带有Memo字段表的效率
操作办法如下:
1.FetchMemo = .F.
2.FetchMemoDataSourceType = ca.DataSourceType
3.FetchMemoDataSource = ca.DataSource
4.FetchMemoCmdList
DelayedMemoFetch是个内置保护方法
在程序里是不能直接调用
从Mihu大侠的文章可以看出对CursorAdapter应该是非常熟悉的,本人也是最近才对CursorAdapter有所了解,在尝试使用ADO连接方式来做
希望以后能得到Mihu大侠的指点!先在此谢谢Mihu大侠!
学了半天,终于有了一点认识,请大家批评:
1、chr(0)应该是字符文件的结束符标识,系统一读到它就会停止,所以海诺大侠的“ThisForm.ImgJZ.PictureVal = LEFT(tmp_DB.剧照, LEN(tmp_DB.剧照)-1) ”完全可以写成ThisForm.ImgJZ.PictureVal =tmp_DB.剧照,没有必要去管那个chr(0)。
2、向数据库写文件时,不做加chr(0)处理。而在读出的数据后,再加chr(0)是一样的,事实上,从数据库中读出来的数据,系统应该会把最后一个字符去掉,它认为这是个标识而不是数据,这样除了数据就有一个结束符的文件肯定会出错(没结束符了!),这也就是为什么有的文件能读出来,有的却不行的原因,事实上是读出来了,就是少那么一点,加上就行了:ThisForm.ImgJZ.PictureVal =tmp_DB.剧照+chr(0)
3、那么多的前辈高人,采用image存储,strconv转换无非是想用二进制的方式避开文件结束的这个问题。如今不用这么做了,一是有了海诺大侠找到的chr(0)作结束的方法,二是vf9的image控件有了pictureval这个可以绑定二进制与文本的属性。我们完全可以用append from把图片拷入到备注字段,再与image作绑定,注意不能用G字段。
4、如果不是因为有了新方法DelayedMemoFetch,恐怕有勇气在c/s上把成百上千的pic传来传去的也没几个人,这真是个好东西呀,可以随用随取,可惜俺才学什么都不会,还望大家多多指点。
真心希望mihu大侠能给几个ca方面的典型例子,坛子上的几个ca的例子我都看了,还是一团糊。
见笑了!
本人尝试过如果向数据库写的文件内容来源于JPG格式的文件,不加Chr(0)的话SQLEXEC语句会有错误提示,因此为确保任何图片格式的文件内容都能写进SQL数据库,我认为还是应该加CHR(0)这个结束符的。再者既然加了这个结束符,如果是对于图片数据的话将其直接赋于Image的PictureVal属性显示可以正常,但如果需还原为文件的话还是应该去掉这个加入的结束符,因此在读出数据使用时应该使用LEFT函数截取掉这个结束符。
希望能对仍然工作在SPT方式下需要操作SQL图像,文件数据的网友能提供方便!
很奇怪,我在写入sqlserver时没有加chr(0),sqlexec时没有报错,昨天试了几个jpg文件,最大的一个7m,读出来的时候加个chr(0)就正常显示了,不加的话,有些是不行的。
文件读入和还原我没有试过,不过我觉得chr(0)这个东西很值得思考一下,从中能反应出sqlserver和vf怎么控制读写文本数据的长度,有机会还要多作几次实验。
个人觉得加chr(0)真是一个使用spt与image的pictureval作绑定的简单易行的好办法,后台数据库只要设为text型,加个小小的chr(0)一切就ok了,很爽呀。如果没有这个办法,想必只有后台设为image型,读出spt字段后,把G型字段(spt默认image型转化为G),作cast转换再与image绑定,虽然比还原成一个文件简单可是比起海诺大侠的这人办法,可就要逊色许多了!
但用Blob字段,后台只能用IMAGE字段,速度太慢了,特别是文件稍大些,如1M以上,简直是烦人
不过我以前保存JPG到SQL SERVER是用加了STRCONV()才解决,看了加CH(0)的方法后,试过不错。ch(0)到ch(9)测试都可以。主要是用此方法速度好
这个与前后台用什么类型的字段有什么关系?
前台用 VFP9的blob还能用DelayedMemoFetch功能来提高程序的运行效率,用SPT就只能干瞪眼的了。