sql >> データベース >  >> RDS >> Mysql

JavaPreparedStatementおよびONDUPLICATEKEY UPDATE:行が挿入されたか更新されたかを知るにはどうすればよいですか?

    次の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

    の場合は1を返します
    1. 試行されたINSERTは、UNIQUEキー値が重複するため、および中止されます。
    2. 指定されたONDUPLICATEKEYUPDATEの変更既存の行の値は実際には変更されません

    これは、上記のテストコードをまったく同じパラメータ値で2回続けて実行することで確認できます。 UPDATE ... id = LAST_INSERT_ID(id)に注意してください 「トリック」は正しいidを保証します 値が返されます。

    挿入されている値がUNIQUEキー値のみである場合、これはおそらくOPのテスト結果を説明しています。



    1. MySQLでのbase64エンコード

    2. MySQLエラーコード:1411。関数str_to_dateの日時の値が正しくありません:''

    3. Postgresqlのid列の位置は重要ですか?

    4. Oracleで日付を別の形式で表示する方法