web-dev-qa-db-ja.com

INSERT ... ON DUPLICATE KEY UPDATEが期待どおりに機能しない

「例」というテーブルがあります

CREATE TABLE IF NOT EXISTS `example` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `a` int(11) NOT NULL,
  `b` int(11) NOT NULL,
  `c` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;

存在しない場合は値を挿入し、値が存在する場合は更新したいので、次のステートメントを使用しています。

INSERT INTO example (a, b, c) VALUES (1,2,3) 
  ON DUPLICATE KEY UPDATE a = VALUES(a), b = VALUES(b), c = VALUES(c);

上記のクエリを実行すると、テーブルは次のようになります。

enter image description here

もう一度上記のステートメントを実行すると、結果は次のようになります。

enter image description here

私の声明の何が問題になっていますか?

7
Relax

元のクエリ

INSERT INTO example (a, b, c) VALUES (1,2,3) ON DUPLICATE KEY
UPDATE a = VALUES(a), b = VALUES(b), c = VALUES(c);

(a,b,c)を一意のキーと考える場合、2つのことを行う必要があります

まず、一意のインデックスを追加します

ALTER TABLE example ADD UNIQUE KEY abc_ndx (a,b,c);

したがって、テーブル構造は次のようになります

CREATE TABLE IF NOT EXISTS `example` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `a` int(11) NOT NULL,
  `b` int(11) NOT NULL,
  `c` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY abc_ndx (a,b,c)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;

次に、クエリを完全に変更する必要があります。どうして ?

(a,b,c)が一意の場合、実行中

INSERT INTO example (a, b, c) VALUES (1,2,3) ON DUPLICATE KEY
UPDATE a = VALUES(a), b = VALUES(b), c = VALUES(c);

(a,b,c)の値をまったく同じに保ちます。何も変わりません。

したがって、クエリを次のように変更することをお勧めします

INSERT IGNORE INTO example (a, b, c) VALUES (1,2,3);

クエリは単純で、最終結果は同じです。

7
RolandoMySQLDBA

まあこれはあなたが使用している挿入ビットです:

INSERT INTOの例(a、b、c)VALUES(1,2,3)....

ここでは、id(重複をチェックする主キー)を指定していません。自動インクリメントに設定されているため、列ab、およびcの値のみを使用して、次の行のIDが自動的に設定されます。

この場合の行は、残りの行データとともに主キー(確認するものが重複しているかどうか)を指定すると更新されます。レコードIDに従って確認および更新する必要がある場合は、KEYも提供する必要があります。この場合はidです。

このようなものを試してください:

INSERT INTO example (id, a, b, c) VALUES (1,1,2,3) ON DUPLICATE KEY UPDATE a = VALUES(a), b = VALUES(b), c = VALUES(c);

これで、idが重複している場合、行が更新されます。

8
Shaheer Ahmed