MySQL - 如果存在则更新,否则插入两个键值对

5
我有一个表,包含外键ID、值1和值2字段。如果我有一个与外键ID和值1匹配的记录,我想要更新值2。如果外键ID或值1不存在,则我想要插入一行新记录。除了使用PHP执行SELECT语句并分别转向UPDATE或INSERT之外,是否有更好的方法来实现这个功能?
注:值2可以与数据库中的值相同,因此我不能运行UPDATE,查看affected_rows是否为0,然后运行INSERT。

foreign_key_id 是唯一的还是主键?使用的 MySQL 版本是哪个? - Joel B Fant
我目前没有将其设置为键。foreign_key_id和value1都不是唯一的。MySQL版本为v5.1.36。 - Anonymous1
4个回答

8
尝试使用IF EXISTS语句来确定是否执行UPDATEINSERT语句。您可以在一个PHP语句/查询中完成此操作。
IF EXISTS(SELECT 1 FROM Mytable WHERE foreign_key_id = f1 AND value1 = v1)
BEGIN
    UPDATE Mytable SET value2 = v2
    WHERE foreign_key_id = f1 AND value1 = v1;
END
ELSE
BEGIN
      INSERT INTO Mytable(foreign_key_id,value1,value2)
      VALUES (f1,v1,v2);
END IF;

太好了。谢谢你的回答。对我也很有用。 - Sujit Agarwal
1
我需要扩展程序才能在MySQL中运行这段代码吗?它对我来说不起作用,而且IF EXISTS(SELECT 1 FROM Mytable WHERE foreign_key_id = f1 AND value1 = v1) END IF; 也没用。 - Anonymous1

4
是的,您可以直接运行更新,然后获取受影响的行数。如果这个数字为0,则运行插入操作。这将节省一个select查询,因为它已经包含在更新中。
[编辑]
评论中发布的查询。使用选择插入。这将节省一个前置select查询。您可以使用mysql_affected_rows获取插入的行数。如果它返回0,则可以进行更新。它实际上包含了select查询,所以我不确定它是否更快(mysql和子查询并不是很友好)。但它将为您节省一次到数据库的往返,这可能会弥补这一点。
insert into yourtable(f1, f2, fr) 
select 'value1', 'value2', 'value3' 
from dual /* yeah, I'm an Oracle dude */
where 
  not exists (
      select 'x' 
      from yourtable 
      where f1 = 'value1' and f2 = 'value2')

我不能这样做,因为value2在之前和之后可能是相同的值,这将创建重复的行。我会编辑我的帖子以反映这个信息。 - Anonymous1
在这种情况下,您可以使用其他答案中的程序块,或者您可以使用REPLACE语句。Replace类似于INSERT,但如果记录已经存在,则替换该记录。http://dev.mysql.com/doc/refman/5.0/en/replace.html 不确定这是否正是您想要的。直到现在才知道有关replace的信息。;) - GolezTrol
我无法使用替换,因为两个键都不是唯一的 - 只有 foreign_key_id 和 value1 的组合是唯一的。 - Anonymous1
那么,在这种情况下,没有太多其他的解决方案。你可以使用一个选择插入insert into yourtable(f1, f2, fr) select 'value1', 'value2', 'value3' where not exists (select 'x' from yourtable where f1 = 'value1' and f2 = 'value2' 这将为您节省一个选择。您只需更新数据库,并在插入语句中添加此条件。但是,您需要尝试一下看看它是否更快。 - GolezTrol
将上述语句放在答案中以提高可读性。 - GolezTrol

1

如果您无法使p.campbell的解决方案起作用,请尝试这个轻微的修改

IF EXISTS(SELECT 1 FROM Mytable WHERE foreign_key_id = f1 AND value1 = v1) THEN
    UPDATE Mytable SET value2 = v2
    WHERE foreign_key_id = f1 AND value1 = v1;
ELSE
    INSERT INTO Mytable(foreign_key_id,value1,value2)
    VALUES (f1,v1,v2);
END IF;

0
最佳选项:使用{{link1:REPLACE}}代替INSERTUPDATE。这取决于使用主键或唯一键。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接