質問

Here is what I am trying to do. I want to insert into this table or update the record if the primary key(entity_id) exists. I am just having an issue with the SQL syntax. It wont let me have more params than the first amount of 'VALUES' so I get the following error:

Parameter index out of range (7 > number of parameters, which is 6).

int insertOrUpdateSuccess = MyDBSyncher.UPDATE("INSERT INTO " + DB_NAME + ".entities " +
    "(`entity_id`, `wai_type`, `wai_id`, `character_id`, `looted`, `creation_time`) " +
    "VALUES ((?), (?), (?), (?), (?), (?)) " +
    "ON DUPLICATE KEY UPDATE " +
    "`wai_type`='(?)', `wai_id`='(?)', `character_id`='(?)', `looted`='(?)'", 
    new String[]{tmpEntityId, values[0], values[1], values[2], values[3], values[4],
    values[0], values[1], values[2], values[3]});

This is kind of similar I think to what I am asking but I could not interpret it for my needs. Sorry to possibly post a duplicate.

Ohh and here is the UPDATE() function in my code:

public static int UPDATE(String updateStatement, String[] params){
    try {
        if(!conn.isClosed()) {
            logger.trace("Successfully connected to MySQL server using TCP/IP - " + conn);

            stat = conn.prepareStatement(updateStatement);
            for (int i = 0; i < params.length; i++){
                stat.setString(i+1, params[i]);
            }
            return stat.executeUpdate();
        }
    } catch(SQLException eSQL) {
        logger.fatal(eSQL.getMessage());
    }
    return -1;
}

Thanks for any help with this. :)

役に立ちましたか?

解決 2

In the context of a PreparedStatement, the character ? is a bind parameter to be replaced by some value later (with setters). If you use it within quotes, then the statement considers it as a literal, not to be replaced. This part of your query:

"`wai_type`='(?)', `wai_id`='(?)', `character_id`='(?)', `looted`='(?)'", 

is setting wai_type to (?), which is not what you want. Get rid of the single quotes. Actually, get rid of the ` characters as well.

他のヒント

Why not just get rid of putting binding param in the duplicated values itself that is following query:

INSERT INTO mytable (col1, col2, col3) VALUES (?, ?, ?)
ON DUPLICATE KEY UPDATE col1=?, col2=?, col3=?;

Can be re-written as:

INSERT INTO mytable (col1, col2, col3) VALUES (?, ?, ?)
ON DUPLICATE KEY UPDATE col1=VALUES(col1), col2=VALUES(col2), col3=VALUES(col3);

IMO one should prefer 2nd over 1st because:

  • not using binding param for 'ON DUPLICATE KEY UPDATE' part in the query means you don't have to write extra piece of code (or iteration in your case) to bind them

  • writing less code means fewer chances of making binding errors (typos etc.)

  • it has better readability

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top