我有一个MYSQL表,如下所示:
id id_jugador id_partido team1 team2
1 2 1 5 2
2 2 2 1 1
3 1 2 0 0
我需要创建一个查询来INSERT表中的新行或UPDATE表。该条件基于 id_jugador 和 id_partido ,这意味着如果我想插入id_jugador = 2
和id_partido = 1
,那么它应该只是更新现有行使用我发送的新team1和team2值。并且不要复制该行。
但是,如果我的条目 id_jugador = 2 且 id_partido = 3 ,由于此组合尚不存在,因此应添加新行。
我读到了REPLACE INTO,但似乎无法检查UNIQUE KEYS的组合。
答案 0 :(得分:1)
如果您在两列(id_jugador, id_partido)
上定义了UNIQUE KEY,那么您可以使用:
INSERT ... ON DUPLICATE KEY ...
e.g。
INSERT INTO mytable (id_jugador, id_partido, team1, team2)
VALUES (?, ?, ?, ?)
ON DUPLICATE KEY
UPDATE team1 = VALUES(team1)
, team2 = VALUES(team2)
(显然,我假设id
是一个AUTO_INCREMENT PRIMARY KEY,或者有一个BEFORE INSERT触发器,当它未提供时会生成id
的值。)
MySQL将尝试INSERT(使用auto_increment id值)。如果INSERT成功,MySQL就完成了,它只是一个常规插入。但是如果INSERT抛出DUPLICATE KEY异常,那么MySQL将执行更新操作,相当于:
UPDATE mytable SET team1 = ?, team2 = ? WHERE id_jugador = ? AND id_partido = ?
请注意,表上可以定义多个UNIQUE KEY约束。对于UPDATE操作的谓词,MySQL将使用DUPLICATE KEY异常中标识的唯一(或主)键的列/值。
另请注意,MySQL确实尝试INSERT,因此即使INSERT抛出DUPLICATE KEY异常,MySQL也会使用AUTO_INCREMENT值。
我通常会避免REPLACE
,因为我通常有很多外键,而且我不想要DELETE
动作。 REPLACE
执行的DELETE操作是“真正的”DELETE;如果有外键引用,则将遵循与外键关联的DELETE规则...如果DELETE规则为RESTRICT或NO ACTION并且存在引用行,或者如果DELETE规则为CASCADE或SET NULL,则删除将失败,引用行将被删除或更新。我也相信任何BEFORE / AFTER DELETE触发器也会被触发。
除了这些选项之外,您还必须运行两个单独的语句。
当我需要在没有定义UNIQUE KEY的情况下避免INSERT时,我通常会做类似的事情:
INSERT INTO mytable (id_jugador, id_partido, team1, team2)
SELECT i.*
FROM (SELECT ? AS id_jugador, ? AS id_partido, ? AS team1, ? AS team2) i
LEFT
JOIN mytable s
ON s.id_jugador <=> i.id_jugador
AND s.id_partido <=> i.id_partido
WHERE s.id IS NOT NULL
语句执行后,测试受影响的行数。如果它为零,我们知道没有插入行,所以我们可以继续更新。