私は、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問題についてはアッシュ
Oracle 9は完全にサポートされなくなりました。プレミアサポートは終了しました。 – Theo
返信Macをありがとう。 はい私は、輸出を処理するアプリを書く必要があるかもしれないと思います。私たちは.NETのショップですので、ODP.NETがそれを処理できるようになりました!それ以外の場合は、Javaソリューションを検討しています。 – Ashby