пустая или пустая строка в Oracle

58

Возможный дубликат:
Почему 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. Почему это так?

  • 1
    Как вы видите, что в одном из полей описания есть пустая строка, а в другом пустая строка?
  • 0
    @ Flansch - Предположительно, я предположил с этими операторами INSERT , так как я не знал, что пустые строки '' преобразуются в null значения, извините.
Показать ещё 1 комментарий
Теги:
string
null
oracle10g

2 ответа

63
Лучший ответ

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

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

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

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

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

  • 2
    Это относится только к строке или к другим типам данных?
25

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

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

select * from table where a = '';

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

select * from table where a = null;

а не a is null

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

  • 0
    Это особенно интересно, если вы сравниваете 7.3 (без Java) и> = 8,0 (с Java).
  • 3
    Кроме того, предложение, where not(a = '') также никогда не является истинным, поскольку a = '' является a = null , что оценивается как UNKNOWN , а not(UNKNOWN) является UNKNOWN , что не соответствует действительности. Подробнее о НЕИЗВЕСТНОМ см. Также ответ на stackoverflow.com/questions/2692046/…

Ещё вопросы

Сообщество Overcoder
Наверх
Меню