HSQLDBマジック

HSQLDBでのjava.sql.Statement#executeQueryの不思議。
Javadocは次のように書かれている。

public ResultSet executeQuery(String sql) throws SQLException
単一の ResultSet オブジェクトを返す、指定された SQL 文を実行します。

パラメータ:
sql - データベースに送られる SQL 文。通常静的 SQL SELECT 文
戻り値:
指定されたクエリーによって作成されたデータを含む ResultSet オブジェクト。null にはならない
例外:
SQLException - データベースアクセスエラーが発生した場合、または指定された SQL 文が単一の ResultSet オブジェクト以外のものを生成する場合

JDBCの仕様上では、実行できるのはSELECT文くらいだと読み取れる。


そこで、目指せexecuteQueryでINSERT文というわけで
こんなプログラムを実行してみる。
# Utilsクラス、DBのテーブルの構成はご想像におまかせ。


public static void main(String[] args) {
Connection conn = null;
ResultSet rs = null;
Statement stmt = null;

try {
conn = Utils.getConnection();
String sql = "insert into tekitou values (10, 'runrun')";

stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
System.out.println(rs.next());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
Utils.releaseResultSet(rs);
Utils.releaseStatement(stmt);
Utils.releaseConnection(conn);
}
}
そして実行結果。

false
なんか実行できちゃうみたい。
HSQLDBのコンソールから確かめると、ちゃんとインサートされてるし。
でもResultSet#next()はfalseになる罠。
更新できたかわかんねー&件数もわかんねーじゃん。
# ちなみに、DELTE・UPDATEもexecuteQueryで元気に動きました。


いくらJDBCドライバの実装依存とはいえ、executeQueryで更新系SQL
実行できるのは、びみょーだよなぁ。




ちなみに、Derbyで試した結果。


org.apache.derby.client.am.SqlException: executeQuery method cannot be used for update.
at org.apache.derby.client.am.Statement.checkForAppropriateSqlMode(Unknown Source)
at org.apache.derby.client.am.Statement.flowExecute(Unknown Source)
at org.apache.derby.client.am.Statement.executeQueryX(Unknown Source)
at org.apache.derby.client.am.Statement.executeQuery(Unknown Source)
やっぱり怒られました。