BLOBを含むOracle9iテーブルにデータをアーカイブするデータベースプロシージャを作成しています。データベースのサイズが大きくなりすぎたため、BLOBをファイルシステム(Windows 2000サーバー)にエクスポートして、テープにバックアップしてから、データベーステーブルを切り捨てることをお勧めします。
BLOBをディスクに保存する手順は次のとおりです。
手順blob_to_file (( --ファイルに書き込まれるBLOB pi_blob IN BLOB、 --OracleDirectoryオブジェクトの名前 pi_oracle_directory_name IN VARCHAR2、 -宛先ファイル名 pi_file_name IN VARCHAR2 )。 は v_out_file UTL_FILE.FILE_TYPE; v_blob_len INTEGER; v_buffer RAW(32767); v_amount BINARY_INTEGER:= 32767; v_pos INTEGER:= 1; 始める v_out_file:= utl_file.fopen( 場所=>pi_oracle_directory_name、 ファイル名=>pi_file_name、 open_mode =>'W'、 max_linesize => 32767); v_blob_len:= dbms_lob.getlength(pi_blob); WHILE(v_pos <v_blob_len)LOOP -読み取られた量が残りのBLOB量以上であることを確認します IF(v_pos + v_amount)>(v_blob_len + 1)THEN v_amount:= v_blob_len-v_pos; END IF; --BLOBのチャンクをバッファに読み込みます DBMS_LOB.read( lob_loc => pi_blob、 金額=>v_amount、 オフセット=>v_pos、 buffer => v_buffer); -バッファを生データとしてファイルストリームに出力します utl_file.put_raw( ファイル=>v_out_file、 buffer => v_buffer、 自動フラッシュ=>true); v_pos:= v_pos + v_amount; ループを終了します。 -ファイルを閉じます UTL_FILE.FCLOSE(v_out_file); 例外 他の人が -問題が発生した場合はファイルを閉じます。 IF UTL_FILE.is_open(v_out_file)THEN UTL_FILE.fclose(v_out_file); END IF; 高める; END blob_to_file;
そして、これがテーブル内のBLOBを反復処理し、それらをアーカイブする私の手順です。
手順archive_letter_table (( --OracleDirectoryオブジェクトの名前 pi_oracle_directory_name IN VARCHAR2 )。 は v_out_filename NVARCHAR2(100); v_blob BLOB; CURSOR letter_cursor IS 選択する letter_id 、template_ref 、rtf 、xml_data 、row_version 、ファイル名 、ドキュメントタイプ 、資料 、business_entity_id 、entity_type 、date_created 、sec_function_ref 、user_account_ref 、hsp から Fusion.lms_letter; 始める letter_cursorLOOPのletter_cursor_rowの場合 letter_cursor_row.documentがNULLでない場合 --BLOBを取得し、そのサイズを決定します v_blob:= letter_cursor_row.document; v_out_filename:= CAST(letter_cursor_row.letter_id AS VARCHAR2)|| '_' || letter_cursor_row.file_name; --プロシージャを呼び出してBLOBをファイルに書き込みます FILE_UTILS.blob_to_file(v_blob、pi_oracle_directory_name、v_out_filename); END IF; ループを終了します。 TRUNCATEfusion.lms_letter; END archive_lms_letter_table;
私の2つの問題は次のとおりです。
1)「archive_letter_table」プロシージャを実行した後、ディスクに保存されたファイルには、LF文字だけでなくCR文字とLF文字が含まれています。グローバル検索/置換を手動で実行して修正できますが、自動化されたPL/SQLソリューションが必要です。どうやら、CRとLFを挿入したために、「utl_file.put_raw()」からの出力が正しくないOracleのバグ#2546782があります。これはほぼ間違いなく私の問題を引き起こしているようです。このページの下部に記載されています: http ://www.oracle.com/technology/sample_code/tech/pl_sql/htdocs/x/Utl_File/start.htm
PL / SQLプロシージャ内のこれらのCRLFを取り除く方法を知っている人はいますか?
2)ファイルはPDFまたはRTFのいずれかです。PDFの保存は(CRLFの問題を除いて)うまく機能しますが、RTFは次のエラーで失敗します。
コマンドの5行目からのエラー: 始める fusion.FUSION_ARCHIVE.archive_lms_letter_table('LMS_Letter_Archive_Dir'); 終わり; エラーレポート: ORA-29285:ファイル書き込みエラー ORA-06512:「FUSION.FILE_UTILS」の73行目 ORA-06512:「FUSION.FUSION_ARCHIVE」の59行目 ORA-06512:2行目 29285.00000-「ファイル書き込みエラー」 *原因:ファイルへの書き込み、フラッシュ、またはファイルのクローズに失敗しました。 *アクション:ファイルが存在すること、アクセス可能であること、およびファイルがアクセス可能であることを確認してください。 書き込みモードまたは追加モードで開いています。
PDFファイルのサイズは69KBから219KBの範囲ですが、RTFは633KBである必要があります。ただし、上記のエラーのため、ディスク上で7KBになり、明らかに読み取ることができません。元のRTFを、プロシージャがディスクに保存しようとしているRTFと比較すると、プロシージャがドキュメントの最後の行(明らかに非常に長い... 626KB)を保存できないことがわかります。これは、put_rawが行をそれほど長く処理しないことと関係があるのではないかと思います。
この問題を回避する方法について誰かが手がかりを持っていますか?
問題の1つだけの解決策がある場合は、遠慮なく対応してください。どんな助けでも大歓迎です。
灰