Почему Char (1) изменяется на Char (3) при копировании через Oracle DBLINK?

StackOverflow https://stackoverflow.com/questions/253971

  •  05-07-2019
  •  | 
  •  

Вопрос

У меня есть 2 базы данных, и я хочу перенести существующую таблицу, содержащую столбец CHAR, из базы данных A в базу данных B.

База данных A - это Oracle 9i, которая имеет кодировку WE8ISO8859P1 и содержит таблицу "foo" как минимум с 1 столбцом типа CHAR (1 символ). Я не могу изменить таблицу в базе данных A, поскольку она является частью сторонней установки.

База данных B - это моя собственная база данных Oracle 10g, использующая кодировку AL32UTF8 по разным причинам, и я хочу скопировать foo в эту базу данных.

Я устанавливаю ссылку на базу данных из базы данных B на базу данных A. Затем я запускаю следующую команду:

* создать панель таблиц как select * из # link # .foo; *

Данные хорошо копируются, но когда я проверяю типы столбцов, я замечаю, что CHAR (1 символ) был преобразован в CHAR (3 символа), и при запросе данных в базе данных B это все дополнены пробелами.

Я думаю, что где-то под водой, Oracle смешивает свои собственные байты и символы. CHAR (1 байт) отличается от CHAR (1 символ) и т. Д. Я читал обо всем этом.

Почему тип данных превращается в заполненный символ CHAR (3 символа) и как мне остановить это в Oracle?

Редактировать. Похоже, это связано с передачей CHAR между двумя конкретными уровнями исправлений Oracle 9 и 10. Похоже, что это действительно ошибка. как только узнаю, выложу обновление. Между тем: не пытайтесь перемещать CHAR между базами данных, как я описал. VARCHAR2 работает нормально (проверено).

Изменить 2: Я нашел ответ и разместил его здесь: Почему Char (1) изменяется на Char (3) при копировании через Oracle DBLINK? Жаль, что я не могу принять свой собственный ответ, потому что моя проблема решена.

Это было полезно?

Решение

Эта проблема вызвана тем, как Oracle (неправильно) обрабатывает преобразования символов между различными наборами символов на основе исходного определения длины столбца. Когда вы определяете размер столбца символьного типа в байтах, Oracle не знает, как выполнить преобразование, и обрабатывает его. Решение состоит в том, чтобы всегда определять длину символьного типа в символах .

Для более подробного объяснения проблемы и того, как я это понял, взгляните на http://www.rolfje.com / 2008/11 / 04 / транспортировочные-оракул-символы-над-а-DBLink /

Другие советы

Вам необходимо узнать разницу между NLS WE8ISO8859P1 (который хранит символы в одном байте) и AL32UTF8, который хранит символы в количестве до четырех байтов. Вам нужно будет потратить некоторое время на поддержку языковой поддержки Oracle (NLS) Документация . Oracle автоматически выполняет преобразование через ссылку на базу данных, пытаясь быть полезным.

Попробуйте в командной строке SQL следующее:

ALTER SESSION NLS_NCHAR WE8ISO8859P1 
create table bar as select * from #link#.foo;

Первое, что я бы попробовал, это создать таблицу НЕ как CTAS, а со списком определений столбцов и попытаться выполнить вставку первых нескольких тысяч строк. Если это не удастся, тогда будет очень ясно, почему ... и у вас будет быстрое подтверждение того, что Томас Лоу не справляется с точностью.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top