【问题标题】:MySQL: how to overrride a row with same Primary keyMySQL:如何覆盖具有相同主键的行
【发布时间】:2019-04-30 17:06:35
【问题描述】:

假设我创建了下表:

CREATE TABLE `my_table` (
  num1 INT PRIMARY KEY,
  num2 INT,
  num3 INT
) NGINE=InnoDB DEFAULT CHARSET=utf8;

假设我想在表中插入一个新行,如果新行与表中现有行之一具有相同的主键,我希望新行覆盖对应的行。

目前,以下 SQL 查询将完成这项工作:

INSERT INTO my_table (num1, num2, num3) VALUES (1, 2, 3)
ON DUPLICATE KEY UPDATE num1 = num1, num2 = num2, num3 = num3;

这个查询的问题是它很麻烦。想象一个有 20 列的表。我将不得不再次编写所有列名。

你知道任何优雅的方式来实现这一点吗?

【问题讨论】:

  • 你试过REPLACE吗?
  • “这个查询的问题是它很麻烦。想象一个有 20 列的表。我将不得不重新编写所有列名。” 事实上,这就是为什么你应该规范化为像您一样递增的列名是规范化的绝佳候选者......如果这是“伪”代码,您应该提供更好的用户案例,更好地匹配您的问题和/或更好的用户案例

标签: mysql


【解决方案1】:

向 MySQL 的 REPLACE 打个招呼。

根据 mySQL 文档:

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

因此,您可以简单地

REPLACE INTO my_table (num1, num2, num3) VALUES (1,2,3);

如果该行不存在,它将作为常规INSERT 工作。如果它确实存在,它将被删除+插入(在你的眼中,它看起来像一个UPDATE

请注意。无论您在做什么,您都会很想始终使用REPLACE 而不是INSERT。这会很不方便(我学得很辛苦),因为 Replace 的开销要大得多

【讨论】:

    【解决方案2】:

    好吧,您可以跳过主键,因为根据定义,它与现有行具有相同的值,否则它不会是重复行。

    请注意,您使用 VALUES(columname),否则您将不会使用 VALUES 列表中的值覆盖这些值。

    INSERT INTO my_table (num1, num2, num3) VALUES (1, 2, 3)
    ON DUPLICATE KEY UPDATE num2 = VALUES(num2), num3 = VALUES(num3);
    

    或者如上面提到的评论,使用REPLACE:

    REPLACE INTO my_table (num1, num2, num3) VALUES (1, 2, 3);
    

    (请注意,它们做两件不同的事情。您可能想阅读我对"INSERT IGNORE" vs "INSERT ... ON DUPLICATE KEY UPDATE" 的回答。)

    这个查询的问题是它很麻烦。想象一个有 20 列的表。我得把所有的列名都写一遍。

    嗯。您计算机上的复制和粘贴按钮是否损坏?

    也许您希望我们为您去除面包皮? (开玩笑)

    老实说,有时软件开发涉及一些工作。键入 20 个列名并不是您本周要做的最无聊的事情。

    【讨论】:

    • “键入 20 个列名并不是你这周要做的最无聊的事情。” 他们是时候实现一个语音到文本的 IDE,这样你就可以交谈了书呆子(编程)语言..我想知道这在繁忙的办公室如何工作......
    • @RaymondNijland 这对于语音到代码轰炸的恶作剧会很有趣......想象在 devops 周围走来走去的家伙背诵“sudo ar em space hyphen ar ef space slash”然后像疯了一样跑掉他们宰了你:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-31
    • 2022-01-18
    • 1970-01-01
    • 2015-05-06
    • 2022-12-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多