Раньше я использовал стандартные операторы mysql_connect(), mysql_query() и т. д. для работы с MySQL из PHP. В последнее время я переключился на использование замечательного класса MDB2. Наряду с этим я использую подготовленные операторы, поэтому мне не нужно беспокоиться о том, чтобы избежать атак ввода и SQL-инъекций.
Однако есть одна проблема, с которой я столкнулся. У меня есть таблица с несколькими столбцами VARCHAR, которые указаны как ненулевые (то есть не допускают значений NULL). Используя старые PHP-команды MySQL, я мог без проблем делать такие вещи:
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ожидаемого.
Решение проблемы
Благодаря некоторым ответам я понял, что проблема может быть в MDB2 API, а не в самих командах PHP или MYSQL. Конечно же, я нашел это в FAQ по MDB2:
- Почему пустые строки заканчиваются как NULL в базе данных? Почему я получаю значение NULL, не разрешенное в текстовых полях NOT NULL, хотя значение по умолчанию равно ""?
- Проблема в том, что для некоторых РСУБД (в первую очередь для Oracle) пустая строка равна NULL. Поэтому MDB2 предоставляет возможность переносимости, чтобы обеспечить одинаковое поведение для всех СУБД.
- Поскольку все параметры переносимости включены по умолчанию, вам придется отключить эту функцию, если вы не хотите иметь такое поведение: $mdb2->setOption('portability', MDB2_PORTABILITY_ALL ^ MDB2_PORTABILITY_EMPTY_TO_NULL);
Спасибо всем, кто давал вдумчивые ответы.
Комментариев нет:
Отправить комментарий