如果您在(id_jugador, id_partido) 的两列上定义了一个 UNIQUE KEY,那么您可以使用:
INSERT ... ON DUPLICATE KEY ...
例如
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 将尝试插入(使用 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,因此 MySQL 确实会用完 AUTO_INCREMENT 值,即使 INSERT 抛出 DUPLICATE KEY 异常也是如此。
我通常避免使用REPLACE,因为我通常有很多外键,并且我不想要DELETE 操作。 REPLACE 执行的 DELETE 操作是“真正的”DELETE;如果存在外键引用,则将遵守与外键关联的 DELETE 规则...如果 DELETE 规则为 RESTRICT 或 NO ACTION 并且存在引用行,或者如果 DELETE 规则为 CASCADE 或 SET NULL,则删除将失败,引用行将被删除或更新。我也相信任何 BEFORE/AFTER DELETE 触发器也会被触发。
除了这些选项之外,您还必须运行两个单独的语句。
当我需要在没有定义唯一键的情况下避免插入时,我通常会执行以下操作:
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
语句执行后,测试受影响的行数。如果它为零,我们知道该行没有插入,所以我们可以继续进行更新。