简体   繁体   中英

Updating multiple rows by their IDs

I have an ArrayList of IDs and I want to update a certain column in each row corresponding to each ID. What I am trying to do is writing another, existing ID in that column.

I've got a more or less working solution; I'll show it to you first and then describe my problems with it:

public static void partnerStmt(ArrayList<Integer> keys, int age, int sex, int variable){
    int amount = keys.size();
    int ageMin = age - variable;
    int ageMax = age + variable;

    if (ageMin < 18)
        ageMin = 18;

    String select = "SELECT ID FROM individuen WHERE Jahre BETWEEN " 
            + ageMin +" AND "+ ageMax + " AND family IS 2 AND married IS NULL AND Sex "
            + "IS " + sex + " ORDER BY RANDOM() LIMIT " +amount+";";

    try {
        Statement stmt = DBController.connection.createStatement();
        ResultSet rs = stmt.executeQuery(select);
        for (int i = 0; i < keys.size(); i++) {
            int key = keys.get(i);
            int idColumn = rs.findColumn("ID");
            int partnerID = rs.getInt(idColumn);

            PreparedStatement person = DBController.connection
                    .prepareStatement("UPDATE individuen set Partner = " + partnerID +  
                    " WHERE ID = " + key);
            person.executeUpdate();
            rs.next()
            }
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

My problems with this are, that it is slow. Updating one row at a time just doesn't work with more then 100k entries to be updated. The second problem is, that for some reason IDs, that I am writing into the table ( partnerID ) show up multiple times after running the programm.

Does anybody know a more efficient and better way of doing something like this?

Use batching functionality of JDBC to reduce the number of round-trips:

PreparedStatement person = DBController.connection.prepareStatement(
    "UPDATE individuen set Partner = ? WHERE ID = ?"
);
int idColumn = rs.findColumn("ID");
for (Integer key : keys) {
    if (!rs.next()) {
        // Make sure that we do not read a missing parent ID.
        // This should never happen, as long as rs has enough rows.
        break;
    }
    person.setInt(1, rs.getInt(idColumn));
    person.setInt(2, key);
    person.addBatch();
}
person.executeBatch();

Note that this code uses parameterized statements with ? parameters and setXYZ methods for supplying values.

you could try using in since it looks like your partner id doesnt change

just create a list of your keys and use it like this

"UPDATE individuen set Partner = " + partnerID + " WHERE ID IN (1,2,3,4)"

also even if this doesnt work try moving

int idColumn = rs.findColumn("ID");
int partnerID = rs.getInt(idColumn);

our of your for loop since it never changes

This is how I solved it thanks to you help. I'm still not sure, if this is the most efficient way. So if you've got some suggestions, I'm happy to try them out ;)

public static void partnerStmt(ArrayList<Integer> keys, int age, int sex, int range){
    int amount = keys.size();
    int aageMin = alter - range;
    int ageMax = alter + range;
    int[][] storeArr = new int[amount][2];

    if (ageMin < 18)
        ageMin = 18;

    String select = "SELECT ID FROM individuen WHERE Age BETWEEN " 
            + ageMin +" AND "+ ageMax + " AND Family IS 2 AND Partner IS NULL AND Sex "
            + "IS " + sex + " ORDER BY RANDOM() LIMIT " +amount+";";

    try {
        Statement stmt = DBController.connection.createStatement();
        ResultSet rs = stmt.executeQuery(select);

        for (int i = 0; i < anzahl; i++){
            int idColumn = rs.findColumn("ID");
            int idPartner = rs.getInt(idColumn);
            storeArr[i][0] = keys.get(i);
            storeArr[i][1] = idPartner;
            rs.next();
        }

        PreparedStatement person = DBController.connection.prepareStatement(
            "UPDATE individuen set Partner = ? WHERE ID = ?");

        for (int i = 0; i < amount; i++){
            person.setInt(1, storeArr[i][0]);
            person.setInt(2, storeArr[i][1]);
            person.addBatch();
        }

        person.executeBatch();
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM