1

シナリオは次のとおりです。

Oracle A:文字セットWE8ISO8859P1

Oracle B:文字セットWE8MSWIN1252

Oracle A <-dblink-> Oracle B

Oracle Bに直接アクセスできません、ファイアウォールの問題:(

OracleBからいくつかのバイナリファイルを取得する必要があり、これらのファイルはCLOB型の列にあります(理由を聞かないでください。BLOBに変更できません)。

「selectinsert」を使用してファイルをBからAに取得し、ここにあるclob_to_blob関数を使用してファイルをバイナリに変換しています。

破損したファイルがいくつかありますが、これはOracleがdblinkを介してWE8MSWIN1252をWE8ISO8859P1に自動的に変換しているためだと思います(列はCLOBなので、テキストですよね?)。

データベースの文字セットを変更することはできません。

これに対する回避策はありますか?

前もって感謝します

4

3 に答える 3

1

DBMS_LOB.CONVERTTOBLOB @ remote(....)を使用しようとしましたか

ただし、リモートCLOBのある種のチェックサムを取得して、元の外部ソースから挿入/更新されたときに文字セット変換を取得しているかどうかを確認することをお勧めします。つまり、挿入が行われたときにクライアントの文字セットがデータベースの文字セットと異なる場合は、選択を行う前に問題がすでに発生している可能性があります。


追加するために編集しました。

私が思いつくことができる最も近いものは、リンクのもう一方の端にいくつかのオブジェクトを必要とします。まず、リモートエンドで変換を行う関数。次に、データの「BLOB」ビューを表示するビュー。これはダミーテーブルを使用します(これは私が見つけた最初のCLOBであったためv $ sqlに基づいています)。CLOBをパラメーターとして関数に単純に渡すことができないことがわかる理由はありません。

create or replace function ret_blob return blob is
  cursor c_1 is 
  select sql_fulltext, sql_id, length(sql_fulltext) 
  from v_sql
  where sql_id = 'bzmb01whp36wt';
  rec_c1 c_1%rowtype;
  --
  v_blob  blob;
  v_dest  number := 1;
  v_src   number := 1;
  v_lang  number := 0;
  v_warn  number;
  --
begin
  open c_1;
  fetch c_1 into rec_c1;
  close c_1;
  dbms_lob.createtemporary(v_blob, TRUE);
  --
  dbms_lob.CONVERTTOBLOB (v_blob, rec_c1.sql_fulltext, DBMS_LOB.LOBMAXSIZE, 
        v_dest, v_src, DBMS_LOB.DEFAULT_CSID, v_lang, v_warn);
  --
  dbms_output.put_line(':'||v_warn||'>'||length(v_blob));
  --
  return v_blob;
end;
/

create view rblob as select ret_blob from dual;

次に、ローカルデータベースから、

create table t as select ret_blob from rblob@remote
于 2010-08-03T23:05:29.587 に答える
0

私の最善の提案は、DBリンクを使用せず、代わりにこれを行うことです:

  1. スタンドアロンまたは独自のクライアント プログラムを入手して、Oracle B から CLOB を抽出し、正しいバイナリ データを含む「テキスト」ファイルとしてデータを書き出します。
  2. そのファイルを BLOB にバイナリ ファイルとして Oracle A にインポートします。
于 2010-08-03T18:44:06.587 に答える
0

まったく異なる代替手段。B と同じ文字セットでデータベース C を作成します。データを B から C に (変換せずに) プルすると、データを A に移動する前に C で操作できます。

于 2010-08-05T23:01:56.190 に答える