Blog

com.mysql.jdbc.PreparedStatement.executeUpdate が Can not issue executeUpdate() for SELECTs と言ってくる件

com.mysql.jdbc を使っていて、executeUpdate で SELECT 文を発行しようとした場合、以下のような例外があがる。

Caused by: java.sql.SQLException: Can not issue executeUpdate() for SELECTs
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:996)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:935)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:924)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:870)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2113)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2077)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2062)

この例外は以下の位置から発生している。

        if ((this.firstCharOfStmt == 'S') && isSelectQuery()) {
            throw SQLError.createSQLException(Messages.getString("PreparedStatement.37"), "01S03", getExceptionInterceptor());
        }

isSelectQuery の実装は以下のようになっている。

protected boolean isSelectQuery() throws SQLException {
    synchronized (checkClosed().getConnectionMutex()) {
        return StringUtils.startsWithIgnoreCaseAndWs(StringUtils.stripComments(this.originalSql, "'\"", "'\"", true, false, true, true), "SELECT");
    }
}

こういうのをドライバが実装するのは、あまり筋がよくないように思うが、まあそうなっているよ、ということで。