2014-12-16 2 views
1

Я пытаюсь вставить запись в автомобильный стол. Вот отрегулированная версия таблицы.Почему PDO обрабатывает пустое значение как null?

ПРИМЕЧАНИЕ: это не рабочая модель реального времени, ее нельзя использовать или оценивать как таковую. Я просто показываю проблему, которую я имею упрощенным способом.

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, в противном случае пустые значения будут вставлены как ... пустые значения.

Ex:

$stmt->bindValue(':automobile_name', !empty($automobile_name) ? $automobile_name : NULL, PDO::PARAM_STR);

Я не нуждаясь для вставки NULLs в данном случае - мне нужно бросить пустой, ненулевое значение в данном поле.

Вопрос:

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

+0

Вы подразумеваете 'IS NULL', работающий с mysql_query()? Поскольку PDO не влияет на выражения MySQL.Что касается вставки, вы связываете это значение с «PDO :: PARAM_STR», который превратит значения NULL в пустые строки. – mario

+0

@mario Моя реакция тоже, но в верхней части находится '$ car_name = ''; ', явно устанавливая ее в пустую строку. –

+0

@mario, перед этим запрос вставки выглядел как '$ q =" INSERT INTO desc_autos (автомобильное имя) VALUES ($ car_name) ";' then with 'mysqli_query ($ dbx, $ q);' Если '$ car_name' было пустой (или даже нулевой), он будет вставлен как пустое значение в MySQL. –

ответ

4

Похоже, вам необходимо установить 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 connection attributes

Примечание: Согласно моей быстрой проверки, 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); 
+0

Хотя я не знаю, почему это было бы названо так, я могу подтвердить, что в oracle db, 'NULL == '''. Раздражает время, когда вы привыкли к другим базам данных. –

+0

Просто попробовал это и продолжаю получать ошибку - см. Мой комментарий к Вопросу о том, что я использовал раньше. Похоже, мне нужно изменить схему таблицы на @mario. –

+0

@acoder Вы используете эмулированные готовые или настоящие? С эмуляцией я мог бы получить NULL для преобразования в пустую строку, изменив этот attr, но не наоборот (это то, что вы хотите). С реальными, неэмулируемыми препаратами я не могу ни изменить ситуацию. Но, глядя на вашу таблицу, похоже, что у вас уже есть значение '' '' как значение по умолчанию. Можете ли вы опубликовать 'SHOW CREATE TABLE desc_autos'? –

Смежные вопросы