Почему PDO рассматривает пустое значение как ноль?

Я пытаюсь вставить запись в автомобильную таблицу. Вот урезанная версия таблицы.

НОТА: это не реальная рабочая модель, ее не следует использовать или оценивать как таковую. Я просто показываю проблему, которую я имею в упрощенном виде.

mysql> describe desc_autos;
+-----------------+------------------+------+-----+---------------------+----------------+
| Field           | Type             | Null | Key | Default             | Extra          |
+-----------------+------------------+------+-----+---------------------+----------------+
| car_id          | int(10) unsigned | NO   | PRI | NULL                | auto_increment |
| automobile_name | varchar(25)      | NO   | MUL |                     |                |
+-----------------+------------------+------+-----+---------------------+----------------+
7 rows in set (0.00 sec)

mysql> select count(*) FROM desc_autos WHERE automobile_name IS NULL;
+----------+
| count(*) |
+----------+
|        0 |
+----------+
1 row in set (0.00 sec)

mysql> select count(*) FROM desc_autos WHERE automobile_name = '';
+----------+
| count(*) |
+----------+
|    19322 |
+----------+
1 row in set (0.02 sec)

+-------------+
CREATE TABLE `desc_autos` (
`car_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`automobile_name` varchar(15) NOT NULL,
PRIMARY KEY (`car_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 |
+-------------+
1 row in set (0.00 sec)

Итак, вы видите automobile_name поле NOT NULLи пустые значения отображаются для многих записей. (Не обращайте внимания на имена полей — просто примите, что есть поле с ненулевыми значениями)

Я конвертирую из нативных функций MySQL в PDO. Если я вставлю запись с непустым automobile_name ценность, без проблем — работает отлично. Если automobile_name пусто, PDO не работает

    $automobile_name = '';
try
{
$q = "INSERT INTO
desc_autos
(
automobile_name
)
VALUES
(
:automobile_name
)
";
$stmt = $dbx_pdo->prepare($q);
$stmt->bindParam(':automobile_name',    $automobile_name,   PDO::PARAM_STR);
$stmt->execute();
return true;
} catch(PDOException $err) {
log_error();
return false;
}
}

Это приводит к следующей ошибке:

Error: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'automobile_name' cannot be null

Я думал, что должен был неявно сказать PDO, чтобы вставить значение NULL, иначе пустые значения будут вставлены как … пустые значения.

Пример:

$ stmt-> bindValue (‘: automotive_name’,! empty ($ vehicle_name)?
$ автомобильное_имя: NULL, PDO :: PARAM_STR);

Мне не нужно вставлять NULL в этом случае — мне нужно оставить пустое, ненулевое значение в данном поле.

Вопрос:

Почему PDO рассматривает пустое значение как ноль?

1

Решение

Похоже, вам нужно установить ATTR_ORACLE_NULLS (не обращайте внимания на имя) на соответствующий параметр, чтобы он не преобразовывал пустые строки в NULL, Видимо ваше текущее значение PDO::NULL_EMPTY_STRING вызывая пустую строку '' быть обнуленным.

// Set it to "natural" mode so NULLs and empty strings aren't modified
$dbx_pdo->setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_NATURAL);

Документация: Атрибуты подключения PDO

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

На основании вашего SHOW CREATE TABLE выход, automobile_name столбец NOT NULL но явно не определены по умолчанию. Я бы, вероятно, воспользовался подходом установки по умолчанию для пустой строки '' и позволяя PDO вставить NULL, Как Марио намекает в основной ветке комментариев:

ALTER TABLE desc_autos MODIFY `automobile_name` varchar(15) NOT NULL DEFAULT '';

В PDOStatement bindParam(), вы можете использовать либо PHP null или пустая строка '' заставить базу данных использовать ее по умолчанию. Это не потребует никаких изменений в вашей текущей строке:

$stmt->bindParam(':automobile_name',    $automobile_name,   PDO::PARAM_STR);
5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]