5

PHP PDO for mysql を使用して null 非許容フィールドを null 値で更新するときに、エラーまたは例外を生成できません。ストレートSQLを実行すると、予想されるエラーが発生します。

フィールドが null を許可しないことを示す例外またはエラーではなく、 PDO からのすべての値がstatus_idフィールドの値に 0 に設定されます。

$stmt_handler = $this->db_handler->prepare(
  "UPDATE faxes SET metadata = :metadata, status_id = :status_id, 
  created = :created, updated = :updated, content = :content, 
  vendor_fax_id = :vendor_fax_id WHERE id = :id");
$stmt_handler->bindParam(':id', $fax->id);
$stmt_handler->bindParam(':metadata', $fax->metadata);
$stmt_handler->bindParam(':status_id', $fax->status_id); // tried different combinations
$stmt_handler->bindParam(':created', $fax->created);
$stmt_handler->bindParam(':updated', $fax->updated);
$stmt_handler->bindParam(':content', $fax->content);
$stmt_handler->bindParam(':vendor_fax_id', $fax->vendor_fax_id);
$stmt_handler->execute();

さまざまな組み合わせを試し、PDO::ATTR_EMULATE_PREPARES を false に設定しました (この質問で示唆されているように、PHP mysql PDO は NULL 値の設定を拒否しています) 。

私の元のバインディング:

bindParam(':status_id', $fax->status_id);

で試した

bindValue(':status_id', null, PDO::PARAM_INT);
bindValue(':status_id', null, PDO::PARAM_NULL);
bindValue(':status_id', 'NULL', PDO::PARAM_INT);
bindValue(':status_id', 'NULL', PDO::PARAM_NULL);
bindValue(':status_id', null);
bindValue(':status_id', 'NULL');

PHP バージョン: PHP 5.3.10-1ubuntu3

MySQL サーバーのバージョン: 5.5.28-0ubuntu0.12.10.1

コメントごとに編集

mysql> show columns from faxes;
+---------------+--------------+------+-----+-------------------+-----------------------------+
| Field         | Type         | Null | Key | Default           | Extra                       |
+---------------+--------------+------+-----+-------------------+-----------------------------+
| id            | char(36)     | NO   | PRI | NULL              |                             |
| vendor_fax_id | char(36)     | YES  | UNI | NULL              |                             |
| metadata      | varchar(255) | NO   |     | NULL              |                             |
| status_id     | int(10)      | NO   | MUL | NULL              |                             |
| created       | datetime     | NO   |     | NULL              |                             |
| updated       | timestamp    | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| content       | mediumblob   | NO   |     | NULL              |                             |
+---------------+--------------+------+-----+-------------------+-----------------------------+
7 rows in set (0.00 sec)
4

2 に答える 2

2

更新時にこのエラーが発生するのは、mysql で厳密モードを有効にしている場合のみです。.ini ファイルで、次を確認します。

[mysqld]
..snipped..
sql_mode="some values here"

存在しない場合は追加し、次のような厳格な設定が適用されていることを確認します。

[mysqld]
..snipped..
sql_mode="STRICT_TRANS_TABLES"

サーバーを再起動し、新しいエラーを見てください:)

これがないときに問題を再現しました。mysql を追加して再起動するとすぐに、エラーが表示され始めました。

Mysql は、null 非許容フィールドに値が既に存在する場合でも機能するため、ハード エラーは発生しません。厳密モードのみが強制的にスローされます。

于 2012-12-21T23:39:53.943 に答える
1

この小さな例を試しました

$host = 'localhost';
$database = 'test';
$dbuser = 'USER';
$dbpasswd = '****';
$dsn = "mysql:host=$host;dbname=$database";
$pdo = new PDO($dsn, $dbuser, $dbpasswd);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$sth = $pdo->prepare('insert into test values(?, ?)');
$id = 2;
$name = null;
$sth->bindParam(1, $id);
$sth->bindParam(2, $name);
$sth->execute() or die(implode(';', $sth->errorInfo()));

この試験台

create table test (
id int not null,
name text not null);

そしてそれは私に与えます

PHP Fatal error:  Uncaught exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'name' cannot be null' in /tmp/a.php:15
Stack trace:
#0 /tmp/a.php(15): PDOStatement->execute()
#1 {main}
  thrown in /tmp/a.php on line 15

コマンドラインで。

更新

ステートメントを次のように変更する

update test set name = ? where id = ?

$id = 1
$name = null

エラーなしで実行nameされ、空の文字列に設定されます。

更新 2 :

やっと手に入れました。これは PDO とは関係ありませんが、MySQL 固有のものです。

UPDATE 構文を参照してください。「not null」を検索してください。

NOT NULLと宣言された列を NULL に設定して更新すると厳密な SQL モードが有効になっているとエラーが発生します。それ以外の場合、列は列データ型の暗黙的なデフォルト値に設定され、警告カウントが増加します。暗黙のデフォルト値は、数値型の場合は 0、文字列型の場合は空の文字列 ('')、日付と時刻の型の場合は「ゼロ」値です。セクション11.5「データ型のデフォルト値」を参照してください。

したがって、この動作は文書化されています。エラーを取得したい場合は、厳格な SQL モードを有効にする必要があります。

于 2012-12-21T22:37:50.127 に答える