見出し

phpのPDOで”ON DUPLICATE KEY UPDATE”が失敗するので調べたら同じパラメーターは使いまわせなかった

っていう覚書

table構造

説明用としてこんな感じにしてみました。

🔑idnamebpm
1Elemental Creation212
2HAELEQUIN172
3秋風に靡く追憶は彼女なのか190
1
2
3
4
5
<?php
$stmt = $pdo->prepare("INSERT INTO `musics` (`id`, `name`, `bpm`) VALUES (:id, :name, :bpm) ON DUPLICATE KEY UPDATE `name`=:name, `bpm`=:bpm;");
$stmt->bindParam(':name', '秋風に靡く追憶は彼女なのか?');
$stmt->bindParam(':bpm', 192);
$stmt->execute();

この内容だと以下のエラーが発生します。

PDOException: SQLSTATE[HY093]: Invalid parameter number in C:\path\to\music.php on line 4

マニュアルを読む

マニュアルをしっかり読んでみるとこんなことが書いてありました。

PDOStatement::execute() をコールする際には、 文に渡すパラメータにはそれぞれ固有のパラメータマークを設定する必要があります。 エミュレーションモードが有効になっていない限り、 ひとつのプリペアドステートメントの中で、同じ名前のパラメータマークを 複数使用することはできません。 http://php.net/manual/ja/pdo.prepare.php

要するにinsertで使った:nameは、updateでもう一度使うことはできないってことらしいです。同じパラメーターを複数回定義できないってことだと勘違いしていました。

上の例だとnameは VALUES(name) で呼び出せます。

修正したコード

1
2
3
4
5
<?php
$stmt = $pdo->prepare('INSERT INTO `musics` (`id`, `name`, `bpm`) VALUES (:id, :name, :bpm) ON DUPLICATE KEY UPDATE `name`=VALUES(`name`), `bpm`=VALUES(`bpm`);');
$stmt->bindParam(':name', '秋風に靡く追憶は彼女なのか?');
$stmt->bindParam(':bpm', 192);
$stmt->execute();

しっかりとupdateできました。 これにて完了です。

因みに秋風に靡く追憶は彼女なのか?はオススメなんで聞いてみてください。譜面も楽しいですがHARDクリアつきません。