【问题标题】:MYSQL: Getting existing primary key when inserting record with duplicate unique key?MYSQL:插入具有重复唯一键的记录时获取现有主键?
【发布时间】:2013-08-10 07:37:22
【问题描述】:

我有一个 mysql 数据库,其中包含一个表,该表同时具有自动增量主键和唯一字符串值键(sha-1 哈希)。

如果我尝试添加与现有记录具有相同 sha-1 哈希值的记录,我只想获取现有记录的主键。在尝试插入具有现有哈希值的记录时,我可以使用“INSERT ... ON DUPLICATE KEY UPDATE”或“INSERT IGNORE”之类的东西来防止异常。

但是,当这种情况发生时,我需要检索现有记录的主键。我找不到使用单个 SQL 语句的方法。如果重要的话,我的代码是用 Java 编写的,而且我使用的是 JDBC。

或者,我可以使用两个语句来完成(如果没有找到,则查询后跟插入,或者如果存在重复键,则插入后跟查询)。但我认为单个语句会更有效。

【问题讨论】:

  • 你需要什么“检索现有记录的主键”?
  • 你不能用一条语句来做到这一点。

标签: mysql sql jdbc


【解决方案1】:

如果我尝试添加与现有的具有相同 sha-1 哈希的记录 记录,我只想获取现有记录的主键。一世 可以使用类似“INSERT ... ON DUPLICATE KEY UPDATE”或“INSERT IGNORE" 以防止在尝试插入带有 现有的哈希值。

如果您在列上有 UNIQUE 索引,无论您尝试什么,RDMS不允许在该列中允许重复(NULL 值除外)。

正如您所说,如果附加此内容,则有防止“错误”的解决方案。在你的情况下可能是INSERT IGNORE

不管怎样,INSERTUPDATE 修改数据库。 MySQL 从不为这些语句返回值。读取数据库的唯一方法是使用 SELECT 语句。


这里的“解决方法”很简单,因为您有一个 UNIQUE 列:

INSERT IGNORE INTO tbl (pk, sha_key) VALUES ( ... ), ( ... );
SELECT pk, sha_key FROM tbl WHERE sha_key IN ( ... );
--                                             ^^^
--             Here the list of the sha1 keys you *tried* to insert

【讨论】:

  • 您关于INSERTUPDATE 永远不会返回值的断言并不完全正确。一些数据库(例如PostgreSQLFirebird)支持INSERT ... RETURNING columnname[, columnname]之类的东西,即使在UPDATE OR INSERT上也是如此
  • @MarkRotteveel 你是对的。我主要是在谈论 MySQL,因为这就是问题的标记方式。但我会编辑我的答案以使其更准确。
【解决方案2】:

实际上,INSERT...ON DUPLICATE KEY UPDATE 正是在您的情况下使用的正确语句。当您使用 ON DUPLICATE 时,如果插入没有重复,则 JDBC 返回计数 1 和新插入行的 ID。如果所采取的操作是由于重复而导致的更新,则 JDBC 会返回计数 2 以及原始行的 ID 和新生成的 ID,即使新 ID 从未实际插入到表中。

您可以通过调用 PreparedStatement.getGeneratedKeys() 来获取正确的密钥。第一个键几乎总是您感兴趣的那个。对于此声明:

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

您可以通过调用获取插入或更新的ID:

Long key;
ResultSet keys = preparedStatement.getGeneratedKeys();
if (keys.next())
    key = keys.getLong("GENERATED_KEY");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-14
    • 1970-01-01
    • 2015-04-10
    • 2013-11-09
    • 2018-04-15
    相关资源
    最近更新 更多