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

Я использовал стандартные инструкции mysql_connect(), mysql_query() и т.д. для работы с PHP с 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?

РЕДАКТИРОВАТЬ: Это слишком большой проект, чтобы пройти через всю мою кодовую базу, найти везде, где используется пустая строка ", и вместо этого изменить его на использование NULL. Мне нужно знать, почему стандартные запросы MySQL обрабатывают" "и NULL как две отдельные вещи (как я думаю, это правильно), но подготовленные заявления преобразуют" " в NULL.

Обратите внимание, что "" и NULL - это не то же самое. Например, SELECT NULL = ""; возвращает NULL вместо 1, как вы ожидали.

Ответ 1

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

Одна вещь, которую вы должны учитывать, заключается в том, что пустая строка в SQL не является значением NULL. Вы можете вставлять их в строки, объявленные "NOT NULL", просто отлично:

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 [email protected]_STRING;

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

Ответ 2

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

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

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

Ответ 3

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

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

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

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

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

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

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

Так что не называй меня сумасшедшим, потому что пустые строки могут быть ХОЗЯЙСТВОМ, чем NULL!

'В следующий раз.

Ответ 4

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

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

Отключить эти параметры при подключении к базе данных:

$options = array(
    'portability' => MDB2_PORTABILITY_ALL ^ MDB2_PORTABILITY_EMPTY_TO_NULL
);
$res= & MDB2::connect("mysql://user:[email protected]/dbase", $options);

Ответ 5

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

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

Ответ 6

Не делает ли пустой набор кавычек ""?

Ответ 7

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

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