次のMySQLテストテーブルについて考えてみます。
CREATE TABLE `customers` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`email` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
次のように既存のサンプルデータを使用します:
id name email
-- -------------- ----------------
1 Loblaw, Bob [email protected]
2 Thompson, Gord [email protected]
デフォルトの接続設定でcompensateOnDuplicateKeyUpdateCounts=false
(ここで説明
)次のJavaコード
PreparedStatement ps = dbConnection.prepareStatement(
"INSERT INTO customers (name, email) " +
"VALUES (?, ?) " +
"ON DUPLICATE KEY UPDATE " +
"name = VALUES(name), " +
"id = LAST_INSERT_ID(id)");
ps.setString(1, "McMack, Mike");
ps.setString(2, "[email protected]");
int euReturnValue = ps.executeUpdate();
System.out.printf("executeUpdate returned %d%n", euReturnValue);
Statement s = dbConnection.createStatement();
ResultSet rs = s.executeQuery("SELECT LAST_INSERT_ID() AS n");
rs.next();
int affectedId = rs.getInt(1);
if (euReturnValue == 1) {
System.out.printf(" => A new row was inserted: id=%d%n", affectedId);
}
else {
System.out.printf(" => An existing row was updated: id=%d%n", affectedId);
}
次のコンソール出力を生成します
executeUpdate returned 1
=> A new row was inserted: id=3
ここで、パラメータ値を使用して同じコードを再度実行します
ps.setString(1, "Loblaw, Robert");
ps.setString(2, "[email protected]");
コンソール出力は
ですexecuteUpdate returned 2
=> An existing row was updated: id=1
これは、.executeUpdate
が 一意のインデックスによって既存の行が更新される場合、実際には2を返すことができます。 実際のについてさらにサポートが必要な場合 コードをテストしてから、質問を編集して含めます。
編集
さらにテストすると、.executeUpdate
- 試行されたINSERTは、UNIQUEキー値が重複するため、および中止されます。
- 指定されたONDUPLICATEKEYUPDATEの変更既存の行の値は実際には変更されません 。
これは、上記のテストコードをまったく同じパラメータ値で2回続けて実行することで確認できます。 UPDATE ... id = LAST_INSERT_ID(id)
に注意してください 「トリック」は正しいid
を保証します 値が返されます。
挿入されている値がUNIQUEキー値のみである場合、これはおそらくOPのテスト結果を説明しています。