我有一个mysql数据库,其中一个表具有自动增量主键和唯一字符串值键(sha-1哈希)。
如果我尝试添加具有与现有记录相同的sha-1哈希的记录,我只想获取现有记录的主键。我可以使用“INSERT ... ON DUPLICATE KEY UPDATE”或“INSERT IGNORE”之类的东西来防止在尝试插入具有现有哈希值的记录时发生异常。
然而,当发生这种情况时,我需要检索现有记录的主键。我找不到使用单个SQL语句执行此操作的方法。如果重要,我的代码是Java,我正在使用JDBC。
或者,我可以使用两个语句(如果找不到查询后跟插入,或者如果存在重复键则插入后跟查询)。但我认为单一陈述会更有效率。
答案 0 :(得分:2)
如果我尝试添加具有与现有相同的sha-1哈希的记录 记录,我只想获得现有记录的主键。一世 可以使用“INSERT ... ON DUPLICATE KEY UPDATE”或“INSERT”之类的东西 IGNORE“以防止在尝试使用a插入记录时发生异常 现有哈希值。
如果列上有UNIQUE
索引,无论您尝试什么,RDMS都不允许该列中的重复项(NULL
值除外)
正如你所说,如果这附加,有防止“错误”的解决方案。在您的情况下可能INSERT IGNORE
。
无论如何,INSERT
和UPDATE
修改数据库。 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");