Вопрос

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

Однако есть одна проблема, с которой я сталкиваюсь.У меня есть таблица с несколькими столбцами VARCHAR, которые указаны как ненулевые (то есть не допускают нулевых значений).Используя старые команды 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 как и следовало ожидать.

Это было полезно?

Решение

Это звучит как проблема с API-интерфейсом MDB2. Поскольку пустая строка в 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 row=@EMPTY_STRING;

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

Другие советы

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

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

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

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

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

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

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

Если пустая ячейка действительно означает НЕ НЕДЕЙСТВИТЕЛЬНО, вы можете подумать о другом способе ее выражения. Одним глупым и очевидным способом является фраза «Не NULL». Но у меня есть предположение, что NULL означает что-то вроде "вообще не входит в эту группу". в то время как пустая строка означает что-то вроде "этот парень классный, он просто еще не получил свои бандитские татуировки". В этом случае я бы предложил термин / имя / идею для этой ситуации, например " default " или "новобранец" или "В ожидании".

Теперь, если по какой-то безумной случайности вы действительно хотите, чтобы пустая строка представляла собой то, что даже не достойно 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 * из таблицы, где mything NULL , чем пытаться запросить пустые строки: /

Разве это не пустой набор кавычек, " " ?

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

$query = "INSERT INTO mytable SET somevarchar = ?";
$value = "";
$prepared = $db->prepare($query);
$prepared->bind_param("s", $value);
$result = $prepared->execute();
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top