Пустая строка в столбце not-null в MySQL?

я использовал стандартные операторы mysql_connect(), mysql_query () и т. д. Для выполнения MySQL из PHP. В последнее время я переключаюсь на использование замечательного класса MDB2. Наряду с этим я использую подготовленные операторы, поэтому мне не нужно беспокоиться о том, чтобы избежать атак ввода и SQL-инъекций.

тем не менее, есть одна проблема, с которой я сталкиваюсь. У меня есть таблица с несколькими столбцами VARCHAR, которые указаны как not-null (то есть не разрешают значения NULL). Используя старый Команды MySQL PHP, я мог бы делать такие вещи без каких-либо проблем:

INSERT INTO mytable SET somevarchar = '';

теперь, однако, если у меня есть запрос:

INSERT INTO mytable SET somevarchar = ?;

а потом в PHP у меня:

$value = "";
$prepared = $db->prepare($query, array('text'));
$result = $prepared->execute($value);

это вызовет ошибку"null value violates not-null constraint"

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

как я должен вставлять пустые строки с подготовленные операторы, без попытки вместо этого вставить NULL?

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

обратите внимание, что "" и NULL являются не то же самое. Для Пример,SELECT NULL = ""; возвращает NULL вместо 1 как и следовало ожидать.

7 ответов


это звучит как проблема с MDB2 API, неуклюже набирающим семантику утки PHP. Поскольку пустая строка в PHP эквивалентна NULL, MDB2, вероятно, неправильно обрабатывает ее как таковую. Идеальным решением было бы найти обходной путь для него в его API, но я не слишком хорошо знаком с ним.

mysql> CREATE TABLE tbl( row CHAR(128) NOT NULL );
Query OK, 0 rows affected (0.05 sec)

mysql> INSERT INTO tbl VALUES( 'not empty' ), ( '' );
Query OK, 2 rows affected (0.02 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> SELECT row, row IS NULL FROM tbl;
+-----------+-------------+
| row       | row IS NULL |
+-----------+-------------+
| not empty |           0 | 
|           |           0 | 
+-----------+-------------+
2 rows in set (0.00 sec)

mysql> INSERT INTO tbl VALUES( NULL );
ERROR 1048 (23000): Column 'row' cannot be null

Если вы не можете найти (или реализовать) обходной путь в API MDB2, одним из хакерских решений (хотя и немного лучше, чем тот, который вы используете в настоящее время) может быть определение переменные пользователя для пустой строки --

SET @EMPTY_STRING = "";
UPDATE tbl SET row=@EMPTY_STRING;

наконец, если вам нужно использовать пустую строку в инструкции INSERT, но не можете, значением по умолчанию для типов строк в MySQL является пустая строка. Таким образом, вы можете просто опустить столбец из INSERT оператор, и он автоматически будет установлен в пустую строку (при условии, что столбец имеет ограничение NOT NULL).


благодаря некоторым ответам я понял, что проблема может быть в API MDB2, а не в самих командах PHP или MYSQL. Конечно, я нашел это в MDB2 FAQ:

  • Почему пустые строки заканчиваются как NULL в базе данных? Почему я получаю NULL не допускается в текстовых полях NOT NULL eventhough значение по умолчанию""?
    • проблема в том, что для некоторых СУБД (наиболее примечательно Oracle) пустой строка имеет значение NULL. Поэтому базы данных mdb2 предоставляет возможность переносимости обеспечить одинаковое поведение для всех СУРБД.
    • так как все параметры переносимости включены по умолчанию у вас будет чтобы отключить функцию, если вы не хотите иметь такое поведение: $mdb2 - >setOption ('переносимость', MDB2_PORTABILITY_ALL ^ MDB2_PORTABILITY_EMPTY_TO_NULL);

спасибо всем, кто предоставил продуманные ответы.


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

Не зная, к чему относится столбец NULL/"", я не могу знать, как истинное значение пустой строки. Означает ли пустая строка что-то сама по себе (например, если бы я убедил судью позволить мне изменить свое имя на просто ничего, я был бы очень раздражен, если бы мое имя появилось на моем водителе Лицензия как NULL. Меня бы так звали !

однако пустая строка (или пустая, или Ничто, которое является чем-то, а не просто отсутствием чего-либо (например, NULL)) также может просто означать "не NULL" или "Nothing, но все же не Null". Вы даже можете пойти в другом направлении и предположить, что отсутствие значения NULL делает его еще меньше, чем Null, потому что по крайней мере Null имеет имя, которое вы можете сказать вслух!

Я имею в виду, что если пустая строка является прямой представление некоторых данных (например, имя или то, что я предпочитаю вставлять между номерами в моем номере телефона и т. д.), то ваши варианты либо спорить, пока вы не будете болеть за законное использование пустой строки, либо использовать что-то, что представляет пустую строку, которая не является нулевой (например, символ управления ASCII или какой-то эквивалент Юникода, значение регулярного выражения или, что еще хуже, произвольный, но совершенно неиспользуемый токен, например: ◘

Если пустая ячейка действительно означает NOT NULL, тогда вы могли бы придумать какой-нибудь другой способ выразить это. Один глупый и очевидный способ-это фраза "Not NULL". Но у меня есть предчувствие, что NULL означает что-то вроде "не часть этой группы вообще", а пустая строка означает что-то вроде "Этот парень классный, он просто еще не получил свои бандитские татуировки". В этом случае я бы придумал термин/имя/идею для этой ситуации, например "default" или "rookie" или "Pending".

теперь, если по какой-то сумасшедшей случайности вы действительно хотите, чтобы пустая строка представьте то, что даже не достойно NULL, опять же, придумайте для этого более значимый символ, такой как "-1" или "SUPERNULL" или "UGLIES".

в индийской кастовой системе самой низкой кастой являются шудры: фермеры и рабочие. Под этой кастой находятся далиты: "Неприкасаемые". Они не считаются низшей кастой, потому что их отнесение к низшей касте считалось бы загрязнением всей системы.

Так что не называйте меня сумасшедшим за пустые мысли строки могут быть хуже, чем NULL!

до следующего раза.


Я нашел решение!

MDB2 преобразует пустые строки в NULL, потому что опция переносимости MDB2_PORTABILITY_EMPTY_TO_NULL включена по умолчанию (благодаря Oracle, который считает пустые строки нулевыми).

выключите эту опцию при подключении к базе данных:

$options = array(
    'portability' => MDB2_PORTABILITY_ALL ^ MDB2_PORTABILITY_EMPTY_TO_NULL
);
$res= & MDB2::connect("mysql://user:password@server/dbase", $options);

в то время как 0 и пустые строки являются переменными NULL-это отсутствие данных. И поверьте мне, намного проще написать запрос на

SELECT * from table where mything IS NULL чем пытаться запросить пустые строки :/


не пустой набор цитат, "" Что делать?


Я в замешательстве. Похоже, вы используете mysqli OO (из тегов и стиля), но синтаксис отличается от руководство on php.net, который говорит сделать это вместо этого:

$query = "INSERT INTO mytable SET somevarchar = ?";
$value = "";
$prepared = $db->prepare($query);
$prepared->bind_param("s", $value);
$result = $prepared->execute();