MYSQL:在插入具有重复唯一键的记录时获取现有主键?

时间:2013-08-08 14:25:06

标签: mysql sql jdbc

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

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

然而,当发生这种情况时,我需要检索现有记录的主键。我找不到使用单个SQL语句执行此操作的方法。如果重要,我的代码是Java,我正在使用JDBC。

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

2 个答案:

答案 0 :(得分:2)

  

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

如果列上有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

答案 1 :(得分:0)

实际上,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");