标题很清楚...... 我希望能够将一个项目添加到数据库中,并且如果已经有一个具有匹配的唯一列的项目,则返回该项目的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个语句?
答案 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设置表格。然后,您可以在代码中使用以下路径之一: