JDBC - INSERT并返回生成的id,或者如果DUPLICATE KEY返回旧的id

时间:2011-10-13 16:34:08

标签: java mysql jdbc

标题很清楚...... 我希望能够将一个项目添加到数据库中,并且如果已经有一个具有匹配的唯一列的项目,则返回该项目的ID ...

以下表达式与我在解决方案中的结果非常接近

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

我能够使用statement.generatedKeys()获取新id(插入新行时)。 如果重复,“id”会出现在statement.generatedKeys()中吗?如果没有,我该如何获取它?

更新:使用存储过程,以下就是我需要的:

INSERT INTO applications (path, displayName) VALUES (?, ?) 
ON DUPLICATE KEY UPDATE 
   id = LAST_INSERT_ID(id), path = ?, displayName = ?;
SELECT LAST_INSERT_ID() INTO ?;

它适用于我正在使用的不同项目,它在.NET中使用MySQL Connector,但遗憾的是,在这个Java项目中,存储过程对我来说不是一个选项。

有没有其他方法可以在同一次网络旅行中发送2个语句?

3 个答案:

答案 0 :(得分:2)

这似乎是合法的

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

但这看起来很疯狂:

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

您是否会更新现有记录的ID字段?那些引用这个记录的记录会发生什么?

无论如何,在正常更新的情况下猜测(forst one)statement.generatedKeys()不会返回已存在的ID。 在这种情况下,您可能必须发出一个额外的select语句(使用where子句中的唯一键列:select id from table where a=1 and b=2)来查找记录的ID。

或者你可以编写一个存储过程,插入/更新在两种情况下都会返回ID。

答案 1 :(得分:2)

所以我和OP的要求相同。 Mysql处理INSERT的方式... ON DUPLICATE KEY UPDATE只是asinine,但不幸的是我们必须忍受它。在Mysql 5.5或更高版本上使用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");

答案 2 :(得分:0)

如果您的目标是阻止重复记录,则可以使用主键/ UNIQUE constraint设置表格。然后,您可以在代码中使用以下路径之一:

  1. 以编程方式检查您要添加的行的唯一性,并处理表中已存在该行的情况
  2. 尝试插入新行。如果它是重复的,则尝试将失败并出现异常,您可以使用相同的标准找到旧行。我认为这是一种糟糕的做法。
相关问题