如何以Insert拷出Blob欄位資料 |
答題得分者是:kevin2004
|
limary
初階會員 發表:41 回覆:109 積分:30 註冊:2007-01-11 發送簡訊給我 |
|
hua2000
中階會員 發表:102 回覆:200 積分:65 註冊:2006-11-04 發送簡訊給我 |
|
limary
初階會員 發表:41 回覆:109 積分:30 註冊:2007-01-11 發送簡訊給我 |
我寫了一個系統,主要是管一大堆Word/Access/txt等格式的附檔。我想在這個系統中設計一個除了Win-PG本身提供的備份格式與備份功能外,另一個可以將整個資料庫轉移出來到其他的資料庫如Access/MSSQL/MySQL的方法,所以我試了好久如何組這個Insert命令的功能。我成功的判斷各個欄位的FieldType,及試出在Access等資料庫中幾種常見的FieldType在insert中應如何表示的方法。可是一遇到這個關鍵的Blob欄位,就有問題了。系統裏有很多Blob欄位,涉及的附檔,雖然經壓縮存入資料庫通常只有20,30K,可是現在也已經有好幾百個附檔了。光轉其他欄位而不轉Blob欄位,是不行的。
我要如何解決這個讓人很困擾的問題? |
kevin2004
資深會員 發表:18 回覆:463 積分:416 註冊:2005-05-29 發送簡訊給我 |
你這問題不容易解決。原則上就如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 發送簡訊給我 |
如果你非要將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
資深會員 發表:18 回覆:463 積分:416 註冊:2005-05-29 發送簡訊給我 |
另一條路是由你的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 發送簡訊給我 |
|
limary
初階會員 發表:41 回覆:109 積分:30 註冊:2007-01-11 發送簡訊給我 |
|
懷舊的人
高階會員 發表:28 回覆:152 積分:141 註冊:2003-01-08 發送簡訊給我 |
有關 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 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |