將圖片或文件內(nèi)容保存到SQL的Text字段的另一種方法
[ 2005-12-08 09:17:34 | 作者:
Admin ]
前段時間本人用VFP9做了一個節(jié)目管理軟件(C/S結(jié)構(gòu)),后臺使用SQL,連接方式采用SPT即使用ODBC連接。在這套軟件中
涉及到劇照文件的處理問題。當時也反復試驗,又不想使用遠程視圖來做,最后找到這條思路。
1、圖片 保存到 SQL表的Text字段
lnID = &&節(jié)目ID號
lcPicJZ = FileToStr(FileName)+chr(0) && 讀入字符串變量 ** 注意在圖像數(shù)據(jù)后加ASC代碼為0的字符
lcCommand = ‘INSERT INTO 節(jié)目劇照信息庫 (Jmid, 劇照) Values (?lnId, ?lcPicJZ)‘
=SQLPREPARE(gHandle, lcCommand) && gHandle 是通過SQLCONNECT()或SQLSTRINGCONNECT()函數(shù)返回的連接句柄
=SQLEXEC(gHandle) && 提交SQL語句
即完成圖片的保存
2、將保存到SQL表的Text圖像數(shù)據(jù)顯示到Image控件或生成一個圖像文件
lnID = &&節(jié)目ID號
=SQLEXEC(gHandle, ‘select 劇照 from 節(jié)目劇照信息庫 where Jmid=‘+str(lnID,20), ‘tmp_DB‘)
ThisForm.ImgJZ.PictureVal = LEFT(tmp_DB.劇照, LEN(tmp_DB.劇照)-1)
** 上面語句中 LEFT()函數(shù)去除圖像數(shù)據(jù)后加ASC代碼為0的字符
&&保存到文件 StrToFile(LEFT(tmp_DB.劇照, LEN(tmp_DB.劇照)-1), ‘圖像文件.bmp‘)
今天看了MiHu大俠的方法感覺也不錯,但就本文引用部分有不同意見,讀入數(shù)據(jù)后無需使用STRCONV()函數(shù)進行轉(zhuǎn)換
也能保存進入,本人今天又反復試驗了以下,用這種方法將2M多的圖片及RAR文件保存到SQL表中,再還原成文件都
沒有發(fā)生丟失現(xiàn)象。我當初試驗的時候開始沒有在讀入數(shù)據(jù)后加chr(0) SQLEXEC 這條語句會偶爾出錯,多次試驗后
加了ASC代碼為0的字符就沒有這個問題了。隨便讀圖片,文件都沒有問題。
另外我覺得在VFP5-VFP9中這種方法都適用,只是在低版本中FileToStr,StrToFile這些函數(shù)要使用FOpen,FRead,FWrite
這些函數(shù)來代替啦。
這個方法本人試驗了好幾天,希望能給網(wǎng)友方便!歡迎各位大俠發(fā)表這方面的心得,請多指點!
+ chr(0)
呵呵,這個方法好啊,當初我可沒想到,如果是今天以前我會非常感謝你的,不過現(xiàn)在我研究出了用blob來保存,那可比你的更加方便簡單。
因為: PictureVal(LEFT(tmp_DB.劇照, LEN(tmp_DB.劇照)-1)) 這個應該是你的自定義函數(shù)吧,你的圖片還是要還原成文件,然后再綁定到Iamge控件上?我估計這里你是寫錯了吧。
就算你是直接用LEFT(tmp_DB.劇照, LEN(tmp_DB.劇照)-1),其過程還是經(jīng)過了轉(zhuǎn)化,而我得到的Cursor里的blob可以直接綁定Image控件,不需要再經(jīng)過任何轉(zhuǎn)換,你說效率哪個高?如果再結(jié)合VFP9 CA的DelayedMemoFetch新功能(經(jīng)測試Blob型字段也完全可以使用DelayedMemoFetch功能),其編程方便性和程序運行效率是SPT根本無法做到的。
不過還是要謝謝你,讓我知道了+CHR(0)可以避免字節(jié)缺失。
十分感謝MiHu大俠的指正, 關(guān)于文中確實多寫了一個PictureVal ,現(xiàn)在已經(jīng)更正。
本菜鳥這篇文章是希望能對以SPT方式下操作SQL數(shù)據(jù)表中的圖像數(shù)據(jù)提供方便。
順便再介紹一下MiHu大俠貼中所提及的幾個術(shù)語意思,希望對和我一樣菜鳥級的VFP愛好者能有所幫助。
1、BLOB
BLOB數(shù)據(jù)類型沒有固定的長度限制,與Memo類型有些相似。它被存儲在以.FPT結(jié)尾的文件中,被.DBF文件引用。BLOB字段與Memo字段有相同
的限定條件,并且他們都不支持索引。
與VarBinary數(shù)據(jù)類型一樣,Visual FoxPro 9不會將BLOB類型作代碼頁轉(zhuǎn)換,而是保持它原始的二進制格式。
BLOB數(shù)據(jù)類型的設(shè)計意圖旨在取代最初的Gerneral字段。如果圖形或者其它一些媒體類型以BLOB的格式存儲,可用Image控件的PictureVal屬
性對它們進行瀏覽。
MEMO與BLOB類型的數(shù)據(jù)不能直接修改,如果直接修改的話,那只會顯示它們的16進制的映像。
2、blob可以直接綁定Image控件
就是將Blob字段的值 直接賦于Image控件的PictureVal
例如 ThisForm.Image1.PictureVal = tmp_DB.圖形
3、CA 就是指 CursorAdapter 類
CursorAdapter類是VFP8中最重要的新功能之一,因為它提供了一種簡單易用、接口統(tǒng)一的訪問遠程數(shù)據(jù)源方式。
訪問一個后臺數(shù)據(jù)庫你可以使用以下機制:
a、遠程視圖,它基于 ODBC 連接;
b、SQL Passthrough (SPT) 函數(shù),例如 SQLCONNECT()、SQLEXEC() 和 SQLDISCONNECT(),它們也基于 ODBC 連接;
c、ActiveX Data Objects ,簡稱 ADO,它提供了一個對各種數(shù)據(jù)庫引擎的 OLE Provider 的一個面對對象訪問方式;
d、XML,它是一個輕量級的、平臺無關(guān)的數(shù)據(jù)傳輸機制。
有關(guān)CursorAdapter 類的詳細介紹大家可以在網(wǎng)上找到很多這樣的介紹資料,我就不多做介紹了。
4、DelayedMemoFetch
vfp8的CA有一個FetchMemo屬性
如果設(shè)置FetchMemo= .F.
那Memo字段的內(nèi)容會不讀取,但如果需要里面的內(nèi)容就會變的非常麻煩VFP9開始有了DelayedMemoFetch方法
可以做到,cursorFill()的時候,Memo里面全空但,當光標移動到Memo字段的時候才自動讀取當前條記錄的Memo字段內(nèi)容
注意是:當前條記錄的Memo字段內(nèi)容這個方法能極大的提高讀取帶有Memo字段表的效率
操作辦法如下:
1.FetchMemo = .F.
2.FetchMemoDataSourceType = ca.DataSourceType
3.FetchMemoDataSource = ca.DataSource
4.FetchMemoCmdList
DelayedMemoFetch是個內(nèi)置保護方法
在程序里是不能直接調(diào)用
從Mihu大俠的文章可以看出對CursorAdapter應該是非常熟悉的,本人也是最近才對CursorAdapter有所了解,在嘗試使用ADO連接方式來做
希望以后能得到Mihu大俠的指點!先在此謝謝Mihu大俠!
學了半天,終于有了一點認識,請大家批評:
1、chr(0)應該是字符文件的結(jié)束符標識,系統(tǒng)一讀到它就會停止,所以海諾大俠的“ThisForm.ImgJZ.PictureVal = LEFT(tmp_DB.劇照, LEN(tmp_DB.劇照)-1) ”完全可以寫成ThisForm.ImgJZ.PictureVal =tmp_DB.劇照,沒有必要去管那個chr(0)。
2、向數(shù)據(jù)庫寫文件時,不做加chr(0)處理。而在讀出的數(shù)據(jù)后,再加chr(0)是一樣的,事實上,從數(shù)據(jù)庫中讀出來的數(shù)據(jù),系統(tǒng)應該會把最后一個字符去掉,它認為這是個標識而不是數(shù)據(jù),這樣除了數(shù)據(jù)就有一個結(jié)束符的文件肯定會出錯(沒結(jié)束符了?。?,這也就是為什么有的文件能讀出來,有的卻不行的原因,事實上是讀出來了,就是少那么一點,加上就行了:ThisForm.ImgJZ.PictureVal =tmp_DB.劇照+chr(0)
3、那么多的前輩高人,采用image存儲,strconv轉(zhuǎn)換無非是想用二進制的方式避開文件結(jié)束的這個問題。如今不用這么做了,一是有了海諾大俠找到的chr(0)作結(jié)束的方法,二是vf9的image控件有了pictureval這個可以綁定二進制與文本的屬性。我們完全可以用append from把圖片拷入到備注字段,再與image作綁定,注意不能用G字段。
4、如果不是因為有了新方法DelayedMemoFetch,恐怕有勇氣在c/s上把成百上千的pic傳來傳去的也沒幾個人,這真是個好東西呀,可以隨用隨取,可惜俺才學什么都不會,還望大家多多指點。
真心希望mihu大俠能給幾個ca方面的典型例子,壇子上的幾個ca的例子我都看了,還是一團糊。
見笑了!
本人嘗試過如果向數(shù)據(jù)庫寫的文件內(nèi)容來源于JPG格式的文件,不加Chr(0)的話SQLEXEC語句會有錯誤提示,因此為確保任何圖片格式的文件內(nèi)容都能寫進SQL數(shù)據(jù)庫,我認為還是應該加CHR(0)這個結(jié)束符的。再者既然加了這個結(jié)束符,如果是對于圖片數(shù)據(jù)的話將其直接賦于Image的PictureVal屬性顯示可以正常,但如果需還原為文件的話還是應該去掉這個加入的結(jié)束符,因此在讀出數(shù)據(jù)使用時應該使用LEFT函數(shù)截取掉這個結(jié)束符。
希望能對仍然工作在SPT方式下需要操作SQL圖像,文件數(shù)據(jù)的網(wǎng)友能提供方便!
很奇怪,我在寫入sqlserver時沒有加chr(0),sqlexec時沒有報錯,昨天試了幾個jpg文件,最大的一個7m,讀出來的時候加個chr(0)就正常顯示了,不加的話,有些是不行的。
文件讀入和還原我沒有試過,不過我覺得chr(0)這個東西很值得思考一下,從中能反應出sqlserver和vf怎么控制讀寫文本數(shù)據(jù)的長度,有機會還要多作幾次實驗。
個人覺得加chr(0)真是一個使用spt與image的pictureval作綁定的簡單易行的好辦法,后臺數(shù)據(jù)庫只要設(shè)為text型,加個小小的chr(0)一切就ok了,很爽呀。如果沒有這個辦法,想必只有后臺設(shè)為image型,讀出spt字段后,把G型字段(spt默認image型轉(zhuǎn)化為G),作cast轉(zhuǎn)換再與image綁定,雖然比還原成一個文件簡單可是比起海諾大俠的這人辦法,可就要遜色許多了!
但用Blob字段,后臺只能用IMAGE字段,速度太慢了,特別是文件稍大些,如1M以上,簡直是煩人
不過我以前保存JPG到SQL SERVER是用加了STRCONV()才解決,看了加CH(0)的方法后,試過不錯。ch(0)到ch(9)測試都可以。主要是用此方法速度好
這個與前后臺用什么類型的字段有什么關(guān)系?
前臺用 VFP9的blob還能用DelayedMemoFetch功能來提高程序的運行效率,用SPT就只能干瞪眼的了。
本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請
點擊舉報。