Oracle перекрывает dblink с другой кодировкой

Вот сценарий:

Oracle A: кодировка WE8ISO8859P1

Oracle B: кодировка WE8MSWIN1252

Oracle A ‹- dblink -> Oracle B

Я не могу напрямую получить доступ к Oracle B, проблемы с брандмауэром :(

Мне нужно получить несколько бинарных файлов от OracleB, и эти файлы находятся в столбце типа CLOB (не спрашивайте меня, почему, и я не могу перейти на BLOB).

Я использую «выбрать вставку», чтобы получить файлы из B в A, и они преобразовывают их в двоичные файлы с помощью функции clob_to_blob, найденной здесь.

Я получаю несколько поврежденных файлов, и я полагаю, что это потому, что Oracle автоматически преобразует WE8MSWIN1252 в WE8ISO8859P1 через dblink (ну, столбец CLOB, так что это текст, верно?).

Я никак не могу изменить кодировку базы данных.

Есть ли обходной путь для этого?

заранее спасибо


person andrecarlucci    schedule 03.08.2010    source источник


Ответы (3)


Вы пытались использовать DBMS_LOB.CONVERTTOBLOB@remote(....)

Но вы, вероятно, захотите получить какую-то контрольную сумму удаленного CLOB, чтобы увидеть, получают ли они преобразование набора символов, когда они вставляются/обновляются из любого исходного внешнего источника. То есть, если набор символов клиента при выполнении вставки отличается от набора символов базы данных, возможно, проблема уже возникла до того, как вы сделаете свой выбор.


Отредактировано, чтобы добавить.

Самое близкое, что я могу придумать, требует некоторых объектов на другом конце ссылки. Во-первых, функция, которая выполняет преобразование на удаленном конце. Во-вторых, представление, которое представляет данные в виде «BLOB». Здесь используется фиктивная таблица (основанная на v$sql, поскольку это был первый CLOB, который я смог найти). Я не вижу причин, по которым вы не можете просто передать 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
person Gary Myers    schedule 03.08.2010
comment
Привет Гэри, нет, если я использую функцию из своего клиента (даже с @dblinkname), я все равно получаю ORA-22992 :( Я думаю, что единственное, что вы можете сделать с LOBS поверх dblinks, это вставка/выбор. Файлы в порядке в удаленной системе :( Ненавижу, когда приходится платить за чье-то плохое решение в прошлом (бинарные файлы как clobs...). - person andrecarlucci; 05.08.2010
comment
Наконец мне удалось создать представление на удаленной стороне. Это представление преобразует clob в blob все еще на удаленной стороне, а затем я могу использовать вставку/выбор из локальной базы данных в любое время, когда захочу. Это сработало! Спасибо за идею просмотра. - person andrecarlucci; 12.08.2010

Мое лучшее предложение было бы не использовать ссылку БД, а вместо этого сделать это:

  1. Получите клиентскую программу, автономную или вашу собственную, для извлечения CLOB из Oracle B и записи данных в виде «текстового» файла, который содержит правильные двоичные данные.
  2. Импортируйте этот файл в Oracle A как двоичный файл в BLOB.
person Dan    schedule 03.08.2010
comment
Привет Дэн, спасибо за ответ. Я не могу получить доступ к B напрямую, проблемы с брандмауэром :( - person andrecarlucci; 03.08.2010

Совсем другая альтернатива. Создайте базу данных C с тем же набором символов, что и B. Извлеките данные из B в C (без преобразования), затем вы можете выполнить манипуляции в C, прежде чем перемещать данные в A.

person Gary Myers    schedule 05.08.2010