NLS_LENGTH_SEMANTICS и SQL Developer

В Oracle Database существует тип данных VARCHAR2, у которого можно указывать максимальную длину в скобках:

В коде выше мы указали, что максимальная длина будет 100. Только вот 100 чего?

По умолчанию для VARCHAR2 длина указывается в байтах, то есть у нас будет максимальная длина равна 100 байт, а значит, в некоторых случаях там поместится меньше 100 символов, так как в Юникоде они могут занимать больше одного байта. Мы же, разумеется, хотим указывать длину именно в символах, а не в байтах. Что же делать?

К счастью, длину можно указывать и в символах. Для этого нужно явно писать размерность CHAR:

По умолчанию же используются байты, что равносильно принудительному указанию 100 BYTE:

Как я уже писал выше, если не указывать BYTE / CHAR, то по умолчанию считается, что используются байты, но это можно изменить.

В Oracle существует настройка NLS_LENGTH_SEMANTICS. Именно она указывает, в чём будет длина строки для случая, когда в VARCHAR2 явно не указано, использовать BYTE или CHAR.

Всего она существует на трёх уровнях:

  1. Для базы.
  2. Для экземпляра.
  3. Для сессии.

Значение для базы можно получить с помощью SQL:

Значение для экземпляра можно получить с помощью:

Значение для текущей сессии:

Значение для базы указывается только в момент создания базы и НЕ может изменяться в дальнейшем.

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

Значение для сессии имеет то же самое значение, что и значение для экземпляра, но его можно изменить через ALTER SESSION:

Пока ничего страшного, всё хорошо. Однако проблема возникает, если мы не послушали официальную рекомендацию и установили значение NLS_LENGTH_SEMANTICS на уровне экземпляра. Некоторые клиенты действительно будут использовать это значение и не указывать своё, но SQL Developer согласно настройкам по умолчанию (это не ошибка, такое поведение описано в официальной документации) переопределяет значения для NLS_* на уровне сессии. Это всё указывается в ToolsPreferences…, затем в появившемя окне пункт DatabaseNLS. В этом диалоговом окне указаны значения, на которые будут переопределяться значения NLS_* для сессии:

Oracle Database SQL Developer NLS settings
SQL Developer переопределяет настройки NLS для уровня сессии

В принципе, в этом есть здравый смысл, так как все опытные разработчики Oracle ожидают, что длина будет по умолчанию указываться в байтах. Однако если же вы действительно нарушили рекомендацию и изменили настройки для уровня экземпляра, то здесь вам придётся, скорее всего, поставить галочку на Skip NLS Settings, чтобы использовать их.

Полезно знать, что в Oracle Database отсутствует тип BOOLEAN для колонок таблиц.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *