System.Data.SQLite で、日付型のラウンドトリップに失敗することがある

 SQLite の特徴の一つに「弱い型付け」があります。
それゆえ、PHPとか Ruby とかと相性がよいわけです。

が、それゆえに、.NET 系の「強い型付け」な言語と相性が悪かったりします。

先日遭遇したのは、こんな事例。

SQLiteに日付型のデータを入れて、取ってくるところでExceptionになる。
一言で言うと「ラウンドトリップできない」と。

ラウンドトリップ失敗の例

つまり、パラメータクエリで日付を渡すと、取得時に落ちるわけです。

原因は、” Now.ToString() “でした。
つまり、 DateTime.ToString を引数なしで呼び出すと、「地域と言語の指定」に従った「短い形式」で文字列にするわけです。日本の場合、一般的には “yyyy/mm/dd” 形式。

ですが、SQLite では “yyyy-mm-dd”形式 – 要するに、 ISO 8601 形式 (“T”は無くても良い)を日付として認識し、”yyyy/mm/dd”は日付として認識してくれない用なのです。

ためしに、コンソールでこんな風にやってみると…

sqlite> select datetime(‘2010-01-20′);
2010-01-20 00:00:00
sqlite> select datetime(‘2010/01/20′);

sqlite>

スラッシュ区切りは日付にあらずと言うわけです。が、そこは弱い型付けの SQLite、しっかりInsertは成功してるんですね。さらに、コンソールでのSelectも成功。 System.Data.SQLite で変換失敗というわけです。

解決策は意外と簡単で、
1)パラメータ渡すのにいちいち ToString しないで DateTime で渡す
2)どうしても ToString したかったら、 ToString(“s”) を使う。
3)DataSet を使う

データセットを使ってみた例

相手が SQL Server とか Oracle とかなら、そもそもコンパイルか Insert 時にエラーになりそうですが、 SQLite の場合にはこうなりますってことで。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Spam Protection by WP-SpamFree