如果记录已存在,如何插入记录或更新?

Nik*_*lin 32 mysql insert insert-update

我有一个表格列record_id(自动公司)sender,sent_timestatus.

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

因此,如果没有任何记录存储,我会执行

# record_id is AUTO_INCREMENT field
INSERT INTO messages (sender, sent_time, status)
VALUES (@sender, time, @status)
Run Code Online (Sandbox Code Playgroud)

否则我会执行UPDATE语句.

无论如何..有没有人知道如何组合这两个语句,以便插入一个新的记录,如果没有任何记录,其中字段发送者值是"user1"否则更新现有的记录?

And*_*mar 48

MySQL支持重复插入语法,fe:

INSERT INTO table (key,col1) VALUES (1,2)
  ON DUPLICATE KEY UPDATE col1 = 2;
Run Code Online (Sandbox Code Playgroud)

  • 语法甚至比这更强大:"ON DUPLICATE KEY UPDATE col1 = VALUES(col1)是一种更优雅的方式来执行你所描述的(并且它适用于多行插入).你也可以使用col1的值,如ON DUPLICATE KEY UPDATE col1 = col1 + 1. (2认同)

Bal*_*usC 12

如果您对表有严格的约束,那么您也可以使用REPLACE INTOfor.这是MySQL的一个引用:

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

语法基本相同INSERT INTO,只需替换INSERTREPLACE.

INSERT INTO messages (sender, sent_time, status) VALUES (@sender, time, @status)
Run Code Online (Sandbox Code Playgroud)

那会是

REPLACE INTO messages (sender, sent_time, status) VALUES (@sender, time, @status)
Run Code Online (Sandbox Code Playgroud)

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

  • 当行是许多其他表的父级时,删除旧行将导致复杂化.具有级联删除的那些将删除所有关系.我们真的只想做更新. (3认同)

Ike*_*ker 5

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

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

1) sent_time
2) status
Run Code Online (Sandbox Code Playgroud)

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

INSERT INTO messages (sender, sent_time, status) 
VALUES (@sender, time, @status)
ON DUPLICATE KEY UPDATE 
  sent_time = values(sent_time),
  status = values(status);
Run Code Online (Sandbox Code Playgroud)