2009-07-29 14 views
1

私は、BLOBを含むOracle9iの表にデータをアーカイブするデータベース・プロシージャを作成しています。データベースのサイズが大きくなりすぎたため、BLOBをファイルシステム(Windows 2000サーバー)にエクスポートし、テープ上にバックアップしてからデータベーステーブルを切り捨てることをお勧めします。BLOBにutl_file.putraw()を使用する場合、Oracle 9iがCRLFを出力するための回避策はありますか?

ここでディスクにBLOBを保存し、私の手順です:

 
    PROCEDURE archive_letter_table 
     (
       -- Name of Oracle Directory object 
       pi_oracle_directory_name IN VARCHAR2 
    ) 
     IS 

     v_out_filename NVARCHAR2(100); 
     v_blob   BLOB; 

     CURSOR letter_cursor IS 
      SELECT 
      letter_id 
      ,template_ref 
      ,rtf 
      ,xml_data 
      ,row_version 
      ,file_name 
      ,document_type 
      ,document 
      ,business_entity_id 
      ,entity_type 
      ,date_created 
      ,sec_function_ref 
      ,user_account_ref 
      ,hsp 
      FROM 
      fusion.lms_letter; 

     BEGIN 

     FOR letter_cursor_row in letter_cursor LOOP 

      IF letter_cursor_row.document IS NOT NULL THEN 

      -- Retrieve BLOB and determine its size 
      v_blob := letter_cursor_row.document; 
      v_out_filename := CAST(letter_cursor_row.letter_id AS VARCHAR2) || '_' || letter_cursor_row.file_name; 

      -- Call procedure to write the BLOB to file   
      FILE_UTILS.blob_to_file(v_blob, pi_oracle_directory_name, v_out_filename); 

      END IF; 

     END LOOP; 

     TRUNCATE fusion.lms_letter; 

     END archive_lms_letter_table; 

私の2の問題は、次のとおりです:

 
     PROCEDURE blob_to_file 
     (
      -- BLOB to be written to file 
      pi_blob      IN BLOB, 

      -- Name of Oracle Directory object 
      pi_oracle_directory_name IN VARCHAR2, 

      -- Destination filename 
      pi_file_name    IN VARCHAR2 
    ) 
     IS 

     v_out_file  UTL_FILE.FILE_TYPE; 
     v_blob_len  INTEGER; 

     v_buffer   RAW(32767); 
     v_amount   BINARY_INTEGER := 32767; 
     v_pos    INTEGER := 1; 

     BEGIN 

     v_out_file := utl_file.fopen(
      location  => pi_oracle_directory_name, 
      filename  => pi_file_name, 
      open_mode  => 'W', 
      max_linesize => 32767); 

     v_blob_len := dbms_lob.getlength(pi_blob); 

     WHILE (v_pos < v_blob_len) LOOP 

     -- Ensure amount read is not less than remaining BLOB amount 
     IF (v_pos + v_amount) > (v_blob_len + 1) THEN 
      v_amount := v_blob_len - v_pos; 
     END IF; 

     -- Read chunk of BLOB into buffer 
     DBMS_LOB.read(
      lob_loc => pi_blob, 
      amount => v_amount, 
      offset => v_pos, 
      buffer => v_buffer); 

     -- Output the buffer as raw data into the file stream 
     utl_file.put_raw(
      file  => v_out_file, 
      buffer => v_buffer, 
      autoflush => true); 

     v_pos := v_pos + v_amount; 

     END LOOP; 

     -- Close the file 
     UTL_FILE.FCLOSE(v_out_file); 

     EXCEPTION 

     WHEN OTHERS THEN 
      -- Close the file if something goes wrong. 
      IF UTL_FILE.is_open(v_out_file) THEN 
      UTL_FILE.fclose(v_out_file); 
      END IF; 
      RAISE; 

    END blob_to_file; 

そしてここでは、テーブルやアーカイブそれらでのBLOBを反復処理は私の手順です

1) "archive_letter_table"手順を実行した後、ディスクに保存されたファイルには、LF文字の代わりにCRとLF文字が含まれます。グローバルな検索/置換を手動で行うことはできますが、自動化されたPL/SQLソリューションが必要です。どうやら、Oracleバグ#2546782があります。ここでは、 "utl_file.put_raw()"の出力がCRとLFを挿入するために間違っています。これは私の問題の原因となっているようです。それは、このページの下部を下に述べています: http://www.oracle.com/technology/sample_code/tech/pl_sql/htdocs/x/Utl_File/start.htm

誰もが、私は私のPL/SQLプロシージャ内でこれらのCRLF年代を取り除くことができる方法を知っていますか?

2)ファイルはPDFでもRTFでもかまいません。 PDFファイルを保存する(CRLF問題を除いて)うまく動作しますが、RTFsは次のエラーで失敗する:RTF 633キロバイトである必要があり、一方、

Error starting at line 5 in command: 
begin 
fusion.FUSION_ARCHIVE.archive_lms_letter_table('LMS_Letter_Archive_Dir'); 
end; 
Error report: 
ORA-29285: file write error 
ORA-06512: at "FUSION.FILE_UTILS", line 73 
ORA-06512: at "FUSION.FUSION_ARCHIVE", line 59 
ORA-06512: at line 2 
29285. 00000 - "file write error" 
*Cause: Failed to write to, flush, or close a file. 
*Action: Verify that the file exists, that it is accessible, and that 
      it is open in write or append mode.

PDFファイルは、219キロバイトに69キロバイトの間の範囲のサイズです。しかし、上記のエラーのために、ディスク上で7KBになり、明らかに読み取ることができません。オリジナルのRTFを私の手続きがディスクに保存しようとしているものと比較することで、私の手続きが文書の最後の行を保存するのに失敗することがわかりました(これは明らかに非常に長い... 626KB)。私はこれがput_rawで行をあまり長く扱わないこととは別のものだと思っています。

誰もこの問題を回避する方法についての手がかりはありますか?

問題の解決方法が1つしかない場合は、お気軽にご返信ください。どんな助けでも大歓迎です。

あなたのCR/LF問題についてはアッシュ

答えて

1

、それは(...明らかに悪いことで、)you have been Oracledように思える:

At the time of this writing, there are no workarounds nor is Oracle considering back-porting a fix for Oracle9i.

あなたはこれらのAsk Tom answers掘り下げることにより、より多くの洞察を得ることができました。あなたのケースでは、Javaパッケージの開発を検討する価値のある選択肢になると思います。

+0

Oracle 9は完全にサポートされなくなりました。プレミアサポートは終了しました。 – Theo

+0

返信Macをありがとう。 はい私は、輸出を処理するアプリを書く必要があるかもしれないと思います。私たちは.NETのショップですので、ODP.NETがそれを処理できるようになりました!それ以外の場合は、Javaソリューションを検討しています。 – Ashby

0

テーブルを(BLOBとして)後のデータベースバージョン(またはLinuxまたは他の非Windowsバージョン)にコピーする可能性は何ですか? 。 そこから抽出を実行できます。

+0

ゲーリーの提案に感謝します。これは、私が検討するものです...バージョン10または11のOracleサーバーが使用中で利用可能かどうかの問題です。容疑者私はアプリを書く道を追い払われます。 – Ashby

1

私たちはこれを使ってMAC出力を処理しようとしましたが、これは単にCRを使用していました。

CRだけのファイルをBLOBとしてデータベースにロードしましたが、これは問題ありませんでした。

BLOBから書き出しようとしたときに、同じコードでエラーが発生しました。

ブラブに挿入する前のソリューションは、すべてのCRをCR LFに置き換えました。

興味深いことに、Oracleがそれを書き出すと(DBはUNIX上にあります)、LFを書き出すだけです。

次に、実際の出力ファイルでLFをCRに置き換えてから、ユーザーに配信します。

関連する問題