我有一个像这样的 mysql 查询
INSERT INTO table (col1, col2, col3) VALUES ('val1','val2','val3') ON DUPLICATE KEY UPDATE col1=VALUES(col1),STATUS=1
我在 JDBC 中使用 executeBatch()
插入多条记录,如果记录已经存在更新状态列和一些其他值。表也有 last_updated
列。
对于新记录插入,jdbc 返回 1 和 2 以进行更新,但它也返回 1 以表示不更新记录。如果我使用相同的值手动执行该查询,我将受到 0 行的影响。
String usersToConvquery = "INSERT INTO ne_ms_conversation_users (conversationId, userId, role) VALUES (?,?,?) ON DUPLICATE KEY UPDATE role=VALUES(role),STATUS=1";
stm = connection.prepareStatement(usersToConvquery);
for (long userId : users) {
stm.setString(1, conversationId);
stm.setLong(2, userId);
stm.setInt(3, 3);
stm.addBatch();
}
int[] insertCount = stm.executeBatch();
System.out.println(Arrays.toString(insertCount));
默认情况下,MySQL 连接器/J 驱动程序返回已插入或更新的“找到的”行数,即使没有任何值更改,请参阅 useAffectedRows
(默认为 false)连接属性(property)文件:
Don't set the CLIENT_FOUND_ROWS flag when connecting to the server
(not JDBC-compliant, will break most applications that rely on "found"
rows vs. "affected rows" for DML statements), but does cause "correct"
update counts from "INSERT ... ON DUPLICATE KEY UPDATE" statements to
be returned by the server.
有趣的是,JDBC 规范没有说明返回计数的确切含义(尽管它可能会被 TCK 检查),但是对于某些数据库系统来说,'affected rows' == 'found rows' 确实如此,因为无论旧值如何,它们都会更新(如果只是为了获得正确的事务行为),而且很多应用程序依赖于 updateCount > 0
也确实意味着该行已经存在。
INSERT ... ON DUPLICATE KEY UPDATE
上的 MySQL 文档说:
With ON DUPLICATE KEY UPDATE
, the affected-rows value per row is 1
if the row is inserted as a new row, 2 if an existing row is updated,
and 0 if an existing row is set to its current values. If you specify
the CLIENT_FOUND_ROWS
flag to the mysql_real_connect()
C API
function when connecting to mysqld
, the affected-rows value is 1
(not 0) if an existing row is set to its current values.
您可能还想看看 connection property compensateOnDuplicateKeyUpdateCounts
,这只会使此类语句的所有执行返回更新计数 1。