Akisame's Diary
ノンジャンル何でも書いちゃうブログ

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

2017/04/16 カテゴリ: 技術系 タグ: PHP
目次

っていう覚書

table構造

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

🔑id name bpm
1 Elemental Creation 212
2 HAELEQUIN 172
3 秋風に靡く追憶は彼女なのか 190
<?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) で呼び出せます。

修正したコード

<?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クリアつきません。