пустое значение вставляется, когда параметр ложен - PullRequest
5 голосов
/ 17 января 2012

Я пытаюсь вставить значение FALSE в базу данных, но безуспешно - он вставляет пустую строку. Колонна varchar. Если я вставлю ИСТИННОЕ значение, оно вставит 1.

Я использую mysql, PDO и php.

Я также использую класс DB, который ничего не делает с запросом, кроме его подготовки и выполнения с использованием подготовленных операторов PDO.

Запрашиваемый запрос очень простой:

$sql = 'INSERT INTO api_logs_values (value) VALUES (?)';

, а затем:

$this->_db->query($sql, array(FALSE));

есть идеи, что происходит?

EDIT:

Добавлена ​​структура таблицы:

api_logs_values | CREATE TABLE `api_logs_values` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`log_id` int(10) unsigned NOT NULL,
`name` varchar(255) DEFAULT NULL,
`value` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `log_id` (`log_id`,`name`)
ENGINE=MyISAM AUTO_INCREMENT=26 DEFAULT CHARSET=utf8

EDIT2:

Я нашел сообщение об ошибке здесь https://bugs.php.net/bug.php?id=33876,, но, похоже, нет правильного, хорошего решения для этого. За исключением, может быть, установки атрибута PDO_PARAM_BOOL.

EDIT3:

Я обнаружил, что класс DB, который я использую, не привязывает параметры отдельно, а выполняет ($ param), и, глядя здесь http://php.net/manual/en/pdostatement.execute.php,, он обрабатывает все параметры как PDO :: PARAM_STR, что не правильно.

Ответы [ 6 ]

3 голосов
/ 17 января 2012

MySQL вставит значения, которые оцениваются как ложные, в столбцы.В зависимости от типа данных фактическое значение будет отличаться.Для символьных типов данных будет вставлена ​​пустая строка.Для числовых типов будет вставлено 0. Вы должны использовать соответствующий тип данных.(FYI, хотя MySQL распознает ключевое слово BOOL для определений типов данных, столбец будет фактически создан как TINYINT. В этом случае он будет хранить 1 для true и 0 для false)

Если вы хотите сохранить строку буквально«ложь», то вам нужно использовать строковый литерал вместо логического ложного.

3 голосов
/ 17 января 2012

Если вы хотите вставить строку «ложь», то $this->_db->query($sql, array("FALSE"));

Для типа данных varchar значение php false считается пустой строкой.

Если вы хотите, чтобы TRUE было 1, а FALSE было 0, задайте тип данных столбца tinyint.

2 голосов
/ 17 января 2012

MySQL реализует логические значения следующим образом:

BOOL, BOOLEAN Эти типы являются синонимами для TINYINT (1). Нулевое значение считается ложным. Ненулевые значения считаются истинными.

(от: http://dev.mysql.com/doc/refman/5.0/en/numeric-type-overview.html)

1 голос
/ 20 января 2012

Это может быть проблема «строгого режима» mysql. Я знаю, что клиент командной строки изящно помогает "преобразовать" строку 'false' в 0 для типа данных TINYINT (1). Это выдаст предупреждение, но оно войдет. Это не тот случай, когда JDBC этого не делает. ЗОП может быть в стиле фанк ..

См. Отчет об ошибке JDBC: http://bugs.mysql.com/bug.php?id=24526

См. MySQL SQLMode Strict: http://dev.mysql.com/doc/refman/5.1/en/server-sql-mode.html#sqlmode_strict_all_tables

0 голосов
/ 20 января 2012

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

$stmt = $this->pdo->prepare($query);
$stmt->execute($param);

Но с указанием http://lt.php.net/manual/en/pdostatement.execute.php: Он принимает параметр:

input_parameters Массив значенийс таким количеством элементов, сколько связанных параметров в выполняемой инструкции SQL.Все значения обрабатываются как PDO :: PARAM_STR.

Класс базы данных должен был сначала вызвать bindValue () с соответствующим параметром data_type (константа PDO).Этот комментарий хорошо подводит итог: http://lt.php.net/manual/en/pdostatement.bindvalue.php#104939

0 голосов
/ 20 января 2012

Вы должны действительно попытаться соответствовать типам данных. Одно простое, если этого достаточно. Код будет выглядеть так:

$sql = 'INSERT INTO api_logs_values (value) VALUES (?)';
$value = false;
$value = ($value === false? '0':'1');
$this->_db->query($sql, array($value));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...