Search code examples
javasqlh2sql-merge

Can I detect if a 'merge into' H2 statement was using insert or update internally?


Is there any way to detect in Java that a H2 merge into statement was doing insert instead of update?

In both cases the result is the number of affected rows but I need to know if the record was already there and updated or it was just created.

The result is interesting for a Rest service where I want to return 204 instead of 201 - Created.


Solution

  • Yes, there is:

    Connection c = DriverManager.getConnection("jdbc:h2:mem:1")) {
    Statement s = c.createStatement();
    s.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, V INT)");
    PreparedStatement ps = c.prepareStatement(
        "SELECT ID FROM OLD TABLE (MERGE INTO TEST(ID, V) KEY(ID) VALUES (?, ?))");
    ResultSet rs;
    ps.setInt(1, 1);
    ps.setInt(2, 10);
    rs = ps.executeQuery();
    System.out.println(rs.next() ? "UPDATE" : "INSERT");
    ps.setInt(1, 1);
    ps.setInt(2, 20);
    rs = ps.executeQuery();
    System.out.println(rs.next() ? "UPDATE" : "INSERT");
    

    You need a recent version of H2, however, because historic versions don't support data change delta tables.

    In the sample code I used non-standard and non-portable variant of MERGE command for simplicity. You can either use it or its standard-compliant version, you can find syntax of both of them in documentation of H2.