線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:3780
推到 Plurk!
推到 Facebook!

如何以Insert拷出Blob欄位資料

答題得分者是:kevin2004
limary
初階會員


發表:41
回覆:109
積分:30
註冊:2007-01-11

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-06-07 18:18:11 IP:61.219.xxx.xxx 訂閱
請教各位前輩:
小妹會自己寫命令將pg資料庫各表格中的資料撰寫成Insert命令以將整個資料庫各表資料轉移逋來,這沒問題。可是如果某個表格裏有Blob欄位,那要如何寫這個Insert命令?
謝謝。
編輯記錄
taishyang 重新編輯於 2007-06-07 18:19:30, 註解 將文章分類成[問題]‧
hua2000
中階會員


發表:102
回覆:200
積分:65
註冊:2006-11-04

發送簡訊給我
#2 引用回覆 回覆 發表時間:2007-06-07 21:45:06 IP:218.14.xxx.xxx 未訂閱
blob這種要除外,它是二進製的,



limary
初階會員


發表:41
回覆:109
積分:30
註冊:2007-01-11

發送簡訊給我
#3 引用回覆 回覆 發表時間:2007-06-09 08:00:28 IP:61.219.xxx.xxx 訂閱
我寫了一個系統,主要是管一大堆Word/Access/txt等格式的附檔。我想在這個系統中設計一個除了Win-PG本身提供的備份格式與備份功能外,另一個可以將整個資料庫轉移出來到其他的資料庫如Access/MSSQL/MySQL的方法,所以我試了好久如何組這個Insert命令的功能。我成功的判斷各個欄位的FieldType,及試出在Access等資料庫中幾種常見的FieldType在insert中應如何表示的方法。可是一遇到這個關鍵的Blob欄位,就有問題了。系統裏有很多Blob欄位,涉及的附檔,雖然經壓縮存入資料庫通常只有20,30K,可是現在也已經有好幾百個附檔了。光轉其他欄位而不轉Blob欄位,是不行的。
我要如何解決這個讓人很困擾的問題?
編輯記錄
limary 重新編輯於 2007-06-09 08:03:09, 註解 無‧
limary 重新編輯於 2007-06-09 08:03:38, 註解 無‧
limary 重新編輯於 2007-06-09 08:05:09, 註解 無‧
kevin2004
資深會員


發表:18
回覆:463
積分:416
註冊:2005-05-29

發送簡訊給我
#4 引用回覆 回覆 發表時間:2007-06-09 16:14:32 IP:61.219.xxx.xxx 訂閱
你這問題不容易解決。原則上就如hua2000前輩講的,Binary資料不該寫到Insert中。通常除非整個資料庫有Blob欄位的表很少,且這種筆數很少很少,不然我們是絕對不會把這Blob資料內容寫到Insert裏去的。這道理很簡單,即使假設你很節制不將Video/Image/Voice等超大容量的Binary資料寫到資料庫,即使你用了壓縮率超高到10%超級壓縮軟體,那一個Blob維持30K,50K或100K是很自然的,如果一個資料庫轉移的SQL命令群組中有個五百或兩千個Binary資料的轉移,這個SQL檔的內容會多大就知道了。
------
Kevin
編輯記錄
kevin2004 重新編輯於 2007-06-09 16:51:14, 註解 無‧
kevin2004
資深會員


發表:18
回覆:463
積分:416
註冊:2005-05-29

發送簡訊給我
#5 引用回覆 回覆 發表時間:2007-06-09 16:33:43 IP:61.219.xxx.xxx 訂閱
如果你非要將Blob欄位資料寫到Insert,那以可以。以PG的ByteA來講,此ByteA literal 也只不過是個用single quotes括起來的一個string literal罷了。作時要小心以下幾個東東
1.此string中如有single quote ,你可以像在Delphi中用double quotes,如 'Uncle jim'' cabin'。或用BackSlash,如 '......\'.....'表之。或用octal value表之,如 '........\047....'。最後那種是psql-ODBC在作Parse及Insert生成時的制式作法。
2.當Byte值為null﹝不是Char-0﹞也必須escape起來,如 'This is a zero byte \\000'
3.當有backslash value時,如 'This is a backslash \\\\',或'This is a backslash \\134'
這些工作是不能省的。
考慮到安全的問題,如果你的Binary資料中有一段是末明其妙及有殺傷力的Delete/Update等的SQL命令,你沒作任何處理就包到你的Insert中去,且假設它竟然可以執行,你想想有多可怕,它執行的不是你的Insert,而是其他的可怕SQL命令...

這個工實在太龐大了。

比較簡單的方法是繞過去,不要走這條路。
------
Kevin
編輯記錄
kevin2004 重新編輯於 2007-06-09 16:35:36, 註解 無‧
kevin2004 重新編輯於 2007-06-09 16:36:44, 註解 無‧
kevin2004 重新編輯於 2007-06-09 16:48:45, 註解 無‧
kevin2004
資深會員


發表:18
回覆:463
積分:416
註冊:2005-05-29

發送簡訊給我
#6 引用回覆 回覆 發表時間:2007-06-09 16:47:39 IP:61.219.xxx.xxx 訂閱
另一條路是由你的AP提供。你要利用你系統原先將Binary資料﹝即你所謂的Word/Access/txt格式的附檔資料﹞在硬碟刷進刷出的功能,在硬碟某些目錄上作個集體備出的機制。在移資料庫時,你可以用Insert轉非Blob的其他表其他欄位,再由AP到某個t儲存媒體上批次將這些附檔資料批次刷回新資料庫及作必要的相關欄位更新。
此時你的DB-Stru就要有適當的表格作這些作業,而有Blob的資料的亦要有相關的取回控制。
如原先你的Blob資料有PK欄值為20-10-23參個欄之值,那你的儲存媒體的相對檔名就該是『20-10-23-ThisIsMySourceFileNameNotIncludePath』
應該可以了,自己試試啦。
------
Kevin
limary
初階會員


發表:41
回覆:109
積分:30
註冊:2007-01-11

發送簡訊給我
#7 引用回覆 回覆 發表時間:2007-06-09 18:39:39 IP:61.219.xxx.xxx 訂閱
謝謝兩位前輩的分享與指導。

謝謝。
limary
初階會員


發表:41
回覆:109
積分:30
註冊:2007-01-11

發送簡訊給我
#8 引用回覆 回覆 發表時間:2007-06-09 18:44:27 IP:61.219.xxx.xxx 訂閱
請問Kevin2004前輩,你這些有關ByteA的資料是從那裏找到的。可否告知一下。後面有提到對Blob為主的DB轉移的方法,應該是很良好的解決方案,細節容小妹自己思考思考。提示應該是已經足夠了,試作如有問題,再煩請前輩指點一二。

小妹拜謝。
懷舊的人
高階會員


發表:28
回覆:152
積分:141
註冊:2003-01-08

發送簡訊給我
#9 引用回覆 回覆 發表時間:2007-06-10 12:55:50 IP:211.78.xxx.xxx 訂閱
有關 BLOB FIELD 請參考HELP TADOBlobStream;TMemoryStream
如果您想用 INSERT 的方式必須用 Parameter 的方式
with TQ do begin
Close;
SQL.Clear;
SQL.Add('INSERT INTO BLOBFILE VALUES (:CODE, :GRAPHFIELD)');
Parameters.ParamByName('CODE').Value := '001';
// 方式一 將來源檔的 BLOB 存成外部檔案 (GraphName)
Parameters.ParamByName('GRAPHFIELD').LoadFromFile(GraphName,ftBLOB);
// 方式二 將來源檔的 BLOB 放到 TMemoryStream
// var BF: TADOBlobStream;
BF := TADOBlobStream.Create(TBlobField(來源檔的.FieldByName('GRAPHFIELD')), bmRead);
BF.Position := 0;

//Parameters.ParamByName('GRAPHFIELD').DataType := ftBLOB; 如果有錯加入這行
Parameters.ParamByName('GRAPHFIELD').LoadFromStream(BF,ftBLOB);
try
ExecSQL;
except
end;

limary
初階會員


發表:41
回覆:109
積分:30
註冊:2007-01-11

發送簡訊給我
#10 引用回覆 回覆 發表時間:2007-06-13 17:57:41 IP:61.219.xxx.xxx 訂閱
謝謝前輩指點。很好用的功能。謝謝。
===================引 用 懷舊的人 文 章===================
有關 BLOB FIELD 請參考HELP TADOBlobStream;TMemoryStream
如果您想用 INSERT 的方式必須用 Parameter 的方式

系統時間:2024-05-09 3:43:07
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!