Возможный дубликат:
Почему 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
. Почему это так?
Это происходит потому, что Oracle внутренне изменяет пустую строку на значения NULL. Oracle просто не позволит вставить пустую строку.
С другой стороны, SQL Server позволит вам делать то, что вы пытаетесь достичь.
Здесь есть 2 способа обхода:
Оба, конечно, глупые обходные пути:)
В оракуле пустой varchar2 и null обрабатываются одинаково, и ваши наблюдения показывают это.
когда вы пишете:
select * from table where a = '';
это то же самое, что и запись
select * from table where a = null;
а не a is null
который никогда не будет равен true, поэтому никогда не возвращайте строку. то же самое на вставке, NOT NULL означает, что вы не можете вставить нулевую или пустую строку (которая рассматривается как нуль)
where not(a = '')
также никогда не является истинным, поскольку a = ''
является a = null
, что оценивается как UNKNOWN
, а not(UNKNOWN)
является UNKNOWN
, что не соответствует действительности. Подробнее о НЕИЗВЕСТНОМ см. Также ответ на stackoverflow.com/questions/2692046/…
INSERT
, так как я не знал, что пустые строки''
преобразуются вnull
значения, извините.