Подтвердить что ты не робот

Null vs пустая строка в Oracle

Возможный дубликат:
Почему Oracle 9i обрабатывает пустую строку как NULL?

У меня есть таблица в Oracle 10g с именем TEMP_TABLE с двумя столбцами - id и description только для демонстрации.

Столбец id представляет собой первичный ключ сгенерированный последовательностью типа NUMBER(35, 0) not null, а столбец description является типом VARCHAR2(4000) not null.

Основная структура таблицы в этом случае будет выглядеть примерно так:

+--------------+-----------+---------------+
|Name          | Null?     | Type          |
+--------------+-----------+---------------+
|ID            | NOT NULL  | NUMBER(35)    |
|DESCRIPTION   | NOT NULL  | VARCHAR2(4000)|
+--------------+-----------+---------------+

После создания этой таблицы я пытаюсь вставить следующие команды INSERT.

INSERT INTO temp_table (id, description) VALUES (1, null); ->unsuccessful
INSERT INTO temp_table (id, description) VALUES (2, '');   ->unsuccessful

Оба они безуспешны как очевидные, потому что ограничение not null применяется в столбце description.

В обоих случаях Oracle жалуется

ORA-01400: cannot insert NULL into ("WAGAFASHIONDB"."TEMP_TABLE"."DESCRIPTION")

Пустая строка рассматривается как значение NULL в Oracle.


Если я опустил ограничение not null в столбце description, тогда основная структура таблицы выглядела бы следующим образом

+--------------+-----------+---------------+
|Name          | Null?     | Type          |
+--------------+-----------+---------------+
|ID            | NOT NULL  | NUMBER(35)    |
|DESCRIPTION   |           | VARCHAR2(4000)|
+--------------+-----------+---------------+

и обе команды INSERT, как указано, будут успешными. Они создавали бы две строки с параметром NULL, а другую с пустой строкой '' в столбце description TEMP_TABLE.

Теперь, если я выдаю следующую команду SELECT,

SELECT * FROM temp_table WHERE description IS NULL;

то он выбирает строки, в которых есть значение NULL, а другое имеет пустую строку '' в столбце description.

Следующий оператор SELECT, однако, не извлекает строки из TEMP_TABLE

SELECT * FROM temp_table WHERE description='';

Он даже не извлекает строку с пустой строкой в ​​столбце description.


Предположительно, похоже, что Oracle рассматривает значение NULL и пустую строку '' по-другому здесь, но, как представляется, это не так с оператором INSERT, в котором значение a NULL и пустая строка '' не может быть вставлена ​​в столбец с ограничением not null. Почему это так?

4b9b3361

Ответ 1

Это происходит потому, что Oracle внутренне изменяет пустую строку на значения NULL. Oracle просто не позволит вставить пустую строку.

С другой стороны, SQL Server позволит вам делать то, что вы пытаетесь достичь.

Здесь есть 2 способа обхода:

  • Использовать другой столбец, который указывает, является ли поле "описание" действительным или нет
  • Используйте некоторое фиктивное значение для поля описания, в котором вы хотите сохранить пустую строку. (т.е. установите поле "stackoverflowrocks", если ваши реальные данные никогда не будут сталкиваться с таким значением описания)

Оба, конечно, глупые обходные пути:)

Ответ 2

В оракуле пустой varchar2 и null обрабатываются одинаково, и ваши наблюдения показывают это.

когда вы пишете:

select * from table where a = '';

это то же самое, что и запись

select * from table where a = null;

а не a is null

который никогда не будет равен true, поэтому никогда не возвращайте строку. то же самое на вставке, NOT NULL означает, что вы не можете вставить нулевую или пустую строку (которая рассматривается как нуль)