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