33

我有一个包含列record_id(auto inc)、sendersent_time的表status

如果没有特定发件人的任何记录,例如“sender1”,我必须插入一条新记录,否则我必须更新属于“user1”的现有记录。

所以如果没有任何记录已经存储,我会执行

# record_id is AUTO_INCREMENT field
INSERT INTO messages (sender, sent_time, status)
VALUES (@sender, time, @status)

否则我会执行 UPDATE 语句。

无论如何..如果没有字段发件人值为“user1”的任何记录,是否有人知道如何组合这两个语句以插入新记录,否则更新现有记录?

4

6 回答 6

47

MySQL 支持insert-on-duplicate语法 fe:

INSERT INTO table (key,col1) VALUES (1,2)
  ON DUPLICATE KEY UPDATE col1 = 2;
于 2009-12-23T13:52:34.677 回答
13

如果您对表格有严格的约束,那么您也可以使用REPLACE INTO。这是来自 MySQL 的引用:

REPLACE 的工作方式与 INSERT 完全相同,只是如果表中的旧行与 PRIMARY KEY 或 UNIQUE 索引的新行具有相同的值,则在插入新行之前删除旧行。

语法与 基本相同INSERT INTO,只是替换INSERTREPLACE

INSERT INTO messages (sender, sent_time, status) VALUES (@sender, time, @status)

那么将是

REPLACE INTO messages (sender, sent_time, status) VALUES (@sender, time, @status)

请注意,这是一个特定于 MySQL 的命令,不会出现在其他数据库中,因此请记住可移植性。

于 2009-12-23T14:52:43.047 回答
3

正如其他人所提到的,您应该使用“插入...重复密钥更新”,有时也称为“更新插入”。但是,在您的特定情况下,您不想在更新中使用静态值,而是您传递给 insert 语句的 values 子句的值。

具体来说,如果该行已经存在,我认为您想更新两列:

1) sent_time
2) status

为了做到这一点,您将使用这样的“upsert”语句(使用您的示例):

INSERT INTO messages (sender, sent_time, status) 
VALUES (@sender, time, @status)
ON DUPLICATE KEY UPDATE 
  sent_time = values(sent_time),
  status = values(status);
于 2009-12-23T14:42:25.333 回答
2

查看“插入重复密钥更新”

INSERT INTO table (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE c=c+1;

UPDATE table SET c=c+1 WHERE a=1;
于 2009-12-23T13:51:28.857 回答
1

一种选择是使用重复更新语法

http://dev.mysql.com/doc/refman/5.1/en/insert-on-duplicate.html

其他选项是选择以确定记录是否存在,然后相应地进行插入/更新。请注意,如果您使用事务选择,则不会显式终止事务,因此使用它是安全的。

于 2009-12-23T13:53:34.000 回答
-1
use merge statement :

merge into T1
          using T2
          on (T1.ID = T2.ID)
    when  matched
    then  update set  
                      T1.Name = T2.Name
    when  not matched
    then  insert values (T2.ID,T2.Name);
于 2013-07-05T12:48:16.180 回答