Разница между NVARCHAR в Oracle и SQL Server?

Мы переносим некоторые данные с сервера sql на oracle. Для столбцов, определенных как NVARCHAR в SQL-сервере, мы начали создавать NVARCHAR столбцы в Oracle, считая их похожими ... Но похоже, что это не так.

Я прочитал пару сообщений о stackoverflow и хочу подтвердить свои выводы.

Oracle VARCHAR2 уже поддерживает Unicode, если набор символов базы данных, скажем, AL32UTF8 (что верно для нашего случая).

SQLServer VARCHAR не поддерживает юникод. SQLServer явно требует, чтобы столбцы были в типе NCHAR/NVARCHAR для хранения данных в Unicode (особенно в 2-байтовом формате UCS-2).

Следовательно, было бы правильно сказать, что столбцы SQL Server NVARCHAR могут / должны быть перенесены как столбцы Oracle VARCHAR2?


person Zenil    schedule 20.08.2013    source источник
comment
Microsoft подтверждает Oracle NVARCHAR2 ‹==› SQLServer NVARCHAR .. Но то, что я хотел подтвердить, было Oracle VARCHAR2 ‹==› SQLServer NVARCHAR? (поскольку oracle VARCHAR2 готов к юникоду)   -  person Zenil    schedule 20.08.2013


Ответы (1)


Да, если ваша база данных Oracle создана с использованием набора символов Unicode, NVARCHAR в SQL Server следует перенести на VARCHAR2 в Oracle. В Oracle существует тип данных NVARCHAR, позволяющий приложениям хранить данные с использованием набора символов Unicode, когда набор символов базы данных не поддерживает Unicode.

Однако при миграции следует помнить о семантике длины символа. В SQL Server NVARCHAR(20) выделяет место для 20 символов, что требует до 40 байтов в UCS-2. В Oracle по умолчанию VARCHAR2(20) выделяет 20 байт памяти. В наборе символов AL32UTF8 этого потенциально достаточно места только для 6 символов, хотя, скорее всего, он будет обрабатывать гораздо больше (для одного символа в AL32UTF8 требуется от 1 до 3 байтов. Вероятно, вы захотите объявить свои типы Oracle как VARCHAR2(20 CHAR), что означает, что вы хотите выделить место для 20 символов, независимо от того, сколько байтов для этого требуется. Это, как правило, намного проще объяснить, чем пытаться объяснить, почему некоторые строки из 20 символов разрешены, а другие строки из 10 символов отклоняются.

Вы можете изменить семантику длины по умолчанию на уровне сеанса, чтобы любые таблицы, которые вы создаете без указания какой-либо семантики длины, будут использовать семантику символов, а не байтов.

ALTER SESSION SET nls_length_semantics=CHAR;

Это позволяет вам не набирать CHAR каждый раз, когда вы определяете новый столбец. Также можно установить это на системном уровне, но это не рекомендуется командой NLS - очевидно, не все сценарии, предоставляемые Oracle, были тщательно протестированы с базами данных, где NLS_LENGTH_SEMANTICS был изменен. И, наверное, очень мало сторонних скриптов было.

person Justin Cave    schedule 20.08.2013
comment
Отличный ответ ... У меня было несколько вопросов ... Когда мы действительно выполняем миграцию, должны ли мы беспокоиться об усечении данных? Предположим, мы создаем все столбцы Oracle как VARCHAR2. Тогда любые данные из столбца VARCHAR SQL Server должны быть правильно перенесены. А как насчет данных из сообщения SQL Server NVARCHAR? SQL Server NVARCHAR хранит данные в UTF-16, а oracle VARCHAR2 - в UTF-8. Инструмент миграции должен как-то об этом позаботиться? Добавьте, пожалуйста, свои мысли к основному ответу .. - person Zenil; 20.08.2013
comment
@Zenil - Думаю, я уже говорил об этом в своем ответе. Предполагая, что вы используете семантику длины символа при определении столбцов в Oracle, ваш Oracle varchar2(20 char) и ваш SQL Server nvarchar(20) будут иметь пространство для 20 символов. Если в каждом из них есть место для 20 символов, вам не нужно беспокоиться о проблемах с усечением. - person Justin Cave; 20.08.2013
comment
Я думаю, вы обратились к проблеме усечения, но не к проблеме кодирования. Столбец NVARCHAR SQL-сервера закодирован в UTF-16, а столбец Oracle VARCHAR2 будет закодирован в UTF-8 .. Итак, я предполагаю, что инструмент миграции должен знать об этом факте и выполнять соответствующие преобразования. Я должен это выяснить, когда мы дойдем до этой стадии ... - person Zenil; 20.08.2013
comment
@Zenil - внутренняя кодировка не играет роли. Что ж, существуют различные версии стандарта Unicode, которые увеличили количество символов, которые определены с течением времени, поэтому, если вам случится перейти из базы данных, поддерживающей Unicode 6.2, где некоторый символ определен в базе данных, которая поддерживает более раннюю версию этого стандарт, где этот символ не существует, у вас возникнут проблемы, но они возникнут независимо от того, были ли данные сохранены в UTF-8 или UTF-16, UTF-32 или USC-2. Однако, как правило, это не имеет практического значения. - person Justin Cave; 20.08.2013
comment
In SQL Server, a NVARCHAR(20) allocates space for 20 characters: @JustinCave, это не правильно. Число 20 представляет не количество символов, а размер строки в парах байтов. Это очень сбивает с толку, и многие люди совершают эту ошибку, поскольку если вы используете символы в диапазоне кодовых точек 0-65535, то размер каждого символа составляет 2 байта, а количество равно количеству символов. Но если вы используете символы в диапазоне 65536-1114111, то размер каждого символа составляет 4 байта, а использование NVARCHAR (20) выделяет место только для 10 символов. - person Ronen Ariely; 05.08.2019