「例」というテーブルがあります
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);
上記のクエリを実行すると、テーブルは次のようになります。
もう一度上記のステートメントを実行すると、結果は次のようになります。
私の声明の何が問題になっていますか?
元のクエリ
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);
クエリは単純で、最終結果は同じです。
まあこれはあなたが使用している挿入ビットです:
INSERT INTOの例(a、b、c)VALUES(1,2,3)....
ここでは、id
(重複をチェックする主キー)を指定していません。自動インクリメントに設定されているため、列a
、b
、および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
が重複している場合、行が更新されます。