2012年2月12日日曜日

java : SQLiteJDBCのSQLException

javaで次のSQLiteJDBCを使ったときの話。

このSQLiteJDBCを使っていて発生したSQLExceptionは次のようになります。

  • getErrorCode → 0
  • getSQLState → null
  • getMessage → [例外の種類] 種類ごとの文 (詳細)

「例外の種類」というのはSQLiteJDBCのorg.sqlite.SQLiteErrorCode列挙体の文字列表現が入るようです。 SQLiteErrorCodeについてはSQLiteJDBCのjavadocに書いてあります。

ErrorCodeやSQLStateはないのでMessageの文字列を見てふるい分けをしなければなりません。

例えば、insert文を間違えたときのSQLException.getMessageは次のようになります。

[SQLITE_ERROR] SQL error or missing database (table tmain has 5 columns but 4 values were supplied)

  • 例外の種類 → SQLITE_ERROR
  • 種類ごとの文 → SQL error or missing database
  • 詳細 → table tmain has 5 columns but 4 values were supplied

こんなテーブルとインデックスを作って

create table tmain (
    id integer primary key,
    uInt integer unique,
    uIdInt integer,
    memo text not null
)
create unique index uId on tmain(uIdInt)

制約違反をしたときは、

[SQLITE_CONSTRAINT]  Abort due to constraint violation (PRIMARY KEY must be unique)
[SQLITE_CONSTRAINT]  Abort due to constraint violation (column uInt is not unique)
[SQLITE_CONSTRAINT]  Abort due to constraint violation (column uIdInt is not unique)
[SQLITE_CONSTRAINT]  Abort due to constraint violation (tmain.memo may not be NULL)

例外の種類がSQLITE_CONSTRAINT、種類ごとの文は「Abort due to constraint violation」ですね。 詳細は、

  • プライマリキーの制約違反 → PRIMARY KEY must be unique
  • unique列の制約違反 → column 列名 is not unique
  • unique indexの制約違反 → column 列名 is not unique
  • not nullの制約違反 → テーブル名.列名 may not be NULL

unique indexの記述がindex名ではなく列名なので注意。 unique indexに複数の列が指定されているときにunique indexの制約違反をした場合は、詳細が次のようになります。

columns 列名1, 列名2 are not unique

文字列で振り分けってことは、詳細の部分については1度確認したエラーメッセージしか振り分けできないって事ですよね? 何とかなりませんかね?