如果存在具有2个特定列的行,则MYSQL为UPDATE表;如果不存在,则插入新行

时间:2014-05-28 21:05:00

标签: mysql replace insert sql-update unique-key

我有一个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 = 2id_partido = 1,那么它应该只是更新现有行使用我发送的新team1和team2值。并且不要复制该行。

但是,如果我的条目 id_jugador = 2 id_partido = 3 ,由于此组合尚不存在,因此应添加新行。

我读到了REPLACE INTO,但似乎无法检查UNIQUE KEYS的组合。

1 个答案:

答案 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

语句执行后,测试受影响的行数。如果它为零,我们知道没有插入行,所以我们可以继续更新。