« | August 2025 | » | 日 | 一 | 二 | 三 | 四 | 五 | 六 | | | | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | | | | | | | |
| 公告 |
暂无公告... |
Blog信息 |
blog名称:VFP及Sql Server拙笔 日志总数:46 评论数量:107 留言数量:0 访问次数:431122 建立时间:2005年5月12日 |

| |
[VFP与SQL]在VFP中处理SQLSERVER的IMAGE字段的两种方法 原创空间, 随笔, 读书笔记, 心得体会, 事件记录, 日后处理, 软件技术
老瓷 发表于 2005/11/29 21:44:24 |
方法一:原理——SQLSERVER的IMAGE字段存储格式是十六进制字符串,将十六进制字符串通过转换成字符串后利用字符串与文件的互换函数FileToStr与StrToFile可得到需要的结果。写入SQLSERVER中:利用FileToStr()函数将二进制文件转为字符串后,再转换为16进制字符串,然后写入SQLSERVER的IMAGE类型字段从SQLSERVER中读:先从SQLSERVER中按SQLSERVER规定(单次最多8000字符)将16进制文件分节取得并合并,再利用StrToFile转换成二进制文件(注:这个“单次最多8000字符”规定,是不是真的存在,没有考证,姑且照用。亦有说一次性最大下载达到了16M的,不知真假)
以下为方式一的实际示例:****************************************************************************************SET SAFETY OFF &&指定在改写已有文件时不显示对话框LOCAL cImgFilePUBLIC nConnCon=SQLSTRINGCONNECT("driver=SQL Server;Server=SERVER;Uid=sa;pwd=;database=DBSMarket") cImgFile="E:\My Documents\aaaa.JPG"*=MESSAGEBOX(cImgFile,0,"")cImgFile=DownLoadFile(cImgFile)@1,1 SAY cImgFile BITMAP && 显示图形文件*cImgFile=GETPICT("JPG;BMP")*=MESSAGEBOX(cImgFile,0,"")*DO UpLoadFile WITH cImgFile=SQLDISCONNECT(nCon)
*!* 使用的过程与函数*!* 因为向SqlServer写入IMAGE类型字段要把原始数据转换成16进制代码,所以要建一个16进制转换过程,IMAGE字段并不只限于图像文件,任何二进制文件(包括EXE可执行文件)都可转换成十六进制后写入。
*!* 字符转换函数(ASC码字符串转为十六进制代码)*!* 输入参数是字符串,可以把要传的文件用filetostr()函数转为字符串后用此过程转为16进制字符串。PROCEDURE ASCToHex()LPARAMETERS cStrToLOCAL cChrSet,nToHex,nHex,I,nLen,ArrHex(256)cChrSet="0123456789ABCDEF"FOR I=0 TO 255 nToHex=FLOOR(I/16)+1 nHex=IIF(I%16=0,1,nHex+1) ArrHex(I+1)=SUBSTR(cChrSet,nToHex,1)+SUBSTR(cChrSet,nHex,1) ENDFORcChrSet=""nLen=LEN(cStrTo)FOR I=1 TO nLen cChrSet=cChrSet+ArrHex(ASC(SUBSTR(cStrTo,I,1))+1)ENDFORRETURN cChrSetENDPROC
*!* 写入(上传至数据库)过程。传入参数是文件名,例中的ImgBody字段是image类型PROCEDURE UpLoadFileLPARAMETERS cFileNameLOCAL cStr,cHexcStr=FILETOSTR(cFileName)cHex="0x"+ASCToHex(cStr) && "0x"一定得加,这样SQL SERVER才会把它当作16进制代码处理*cSqlStr="insert into TabName(ImgBody) select "+cHexcSqlStr="update YourTable set photo="+cHex+" Where Idno='000001'"=SQLEXEC(nCon,cSqlStr)ENDPROC
*!* 读取(自服务器下载)过程。输入参数是要转换成的文件名称PROCEDURE DownLoadFileLPARAMETERS cFileNameLOCAL I,cSqlStr,cStrChr,cStrHexcStrChr=""cStrHex=""FOR m.I=1 TO 10000000 && 下载时只能每次8000字节,这是SQL2000中限定的* cSqlStr="select substring(ImgBody,"+ALLTRIM(STR(m.I-1))+"*8000+1,8000) as ImgField from TabName where no1=1" cSqlStr="select substring(photo,"+ALLTRIM(STR(m.I-1))+"*8000+1,8000) as ImgField from YourTable Where Idno='000001'" =SQLEXEC(nCon,cSqlStr,"CurTemp") SELECT CurTemp cStrHex=CurTemp.ImgField USE IN ("CurTemp") IF LEN(cStrHex)=0 && 文件下载完后自动跳出循环。 EXIT ENDIF cStrChr=cStrChr+cStrHex && 拼合下载的内容ENDFORSTRTOFILE(cStrChr,cFileName)RETURN cFileNameENDPROC************************************************************************************
方法二:利用流文件与ADO方式直接进行二进制文件与十六进制文件转换及存取以下为方法二的实际应用例子:************************************************************************************LOCAL lcConnStr, lcSQL, loConnection, lcImageName, loRecordSet, loADOStream, lpictprolpictpro=ALLTRIM(thisform.text1.Value)lcSQL = "SELECT * FROM YourTable where Idno='"+TRANSFORM(lpictpro)+"'"lcConnStr=cLinkStrlcImageName = ALLTRIM(thisform.text2.Value) && 设置本地文件名.IF EMPTY(lcImageName) then &&此处为更新时需用原文件 =MESSAGEBOX("图片文件路径不对,找不到该文件!",0,"提示!") RETURNENDIF
*!* 创建对象.loConnection = CREATEOBJECT("ADODB.Connection")loRecordSet = CREATEOBJECT("ADODB.Recordset")loADOStream = CREATEOBJECT("ADODB.Stream")
*!* 打开连接.loConnection.OPEN(lcConnStr)loRecordSet.OPEN(lcSQL,loConnection,1,3,1)
*!* 设置 Stream 对象属性.loADOStream.TYPE = 1 && 1=二进制数据, 2=文本数据.loADOStream.OPEN
*!*自文件读入后写入服务器loADOStream.LoadFromFile("&lcImageName") && 读取一个文件到 stream 对象.loRecordSet.Fields("photo").Value = loADOStream.ReadloRecordSet.Update &&更新字段内容
*!*自服务器读取后存为文件*loADOStream.WRITE(loRecordSet.FIELDS("photo")) && 传递数据到 stream 对象.*lcImageName = _ROOT+"temp___0.jpg" && 设置本地文件名.*loADOStream.SaveToFile(lcImageName,2) && 保存 stream 对象到一个文件.***erase "&lcImageName"
*!* 关闭连接.loRecordSet.CLOSEloConnection.CLOSEloADOStream.CLOSE***************************************************************************** |
|
回复:在VFP中处理SQLSERVER的IMAGE字段的两种方法 原创空间, 随笔, 读书笔记, 心得体会, 事件记录, 日后处理, 软件技术
haixiao(游客)发表评论于2007/5/3 16:14:23 |
向楼主请教一个问题。为方便解答,请给我一个信箱地址。谢谢
haiixao3269@sohu.com
|
|
回复:在VFP中处理SQLSERVER的IMAGE字段的两种方法 原创空间, 随笔, 读书笔记, 心得体会, 事件记录, 日后处理, 软件技术
江南风(游客)发表评论于2006/8/10 0:46:43 |
VFP9才有STRCONV(str,15)的转换功能,但VFP6但没有16进制转换的功能 |
|
回复:在VFP中处理SQLSERVER的IMAGE字段的两种方法 原创空间, 随笔, 读书笔记, 心得体会, 事件记录, 日后处理, 软件技术
thornbird313(游客)发表评论于2006/5/30 2:15:08 |
晕,果然和我总结的生活经验一样:千万不要在一段话中同时多两个或两个以上的问题,否则默认情况下对方只会你提到的第一点。烦请加倍虫回答一下我以上提到的第二个问题。谢谢!(我又没按经验办事。) |
|
回复:在VFP中处理SQLSERVER的IMAGE字段的两种方法 原创空间, 随笔, 读书笔记, 心得体会, 事件记录, 日后处理, 软件技术
ThornBird(游客)发表评论于2006/4/21 0:01:37 |
关于第一种方法,其实VFP有一个函数STRCONV可以把字符串转换为十六进制编码,而且完全也可以把图片存到text字段中,读取也方便许多(直接读到备注型字段中)。不知楼主注意过没有,直接执行SQLEXEC(nConnectHandle, "SELECT * FROM Employees")时(SQL Server Northwind)数据库,得到的临时表中的Photo字段是通用型的,我们可以双击打开查看。而用楼主的方法却不行。当然,把Northwind.Employee中的Photo保存成照片无法查看,因为它前后各多了若干字节(大概是90个)。我们如何才能作到如上效果呢?即把图片存入Image字段中以后可以把它转成VFP的通用字段中直接查看。
以下为blog主人的回复:
您说的是完全正确的,但是在VFP6下没有SCRCONV函数可用,不得不用一个转换函数呀…… |
|
» 1 »
|