仕事で Postgre から SQLServer に移植していてはまったのでメモ。

  • SQLServer の datetime 型はミリ秒の桁が 0,3,7 に丸められる。
  • WHERE句で比較する場合は丸めが起こらないので比較が一致しない。

具体的にどういう時に起こったかと言うと O/R マッパーを使っていて Bean に日付が残っていたケース。

bean.setKey(123);
bean.setUpdateTime(new Date());
ORMapper.insert(bean);

bean.setItem("hogehoge");
ORMapper.update(bean);

とかやった時に O/R マッパーがこんな SQL を生成してた。

INSERT INTO Bean (key,updateTime) VALUES (123,'2013-01-01T00:00:00.999');

ここで updateTime には '2013-01-01T00:00:01.000' が入る。

UPDATE Bean SET item='hogehoge' WHERE key=123 AND updateTime='2013-01-01T00:00:00.999';

WHERE句の updateTime 丸めが起こらないので UPDATE が失敗してしまう。

WHERE updateTime がそもそも不要なので O/R マッパーの設定ファイルの問題なんだけど DB がアプリが指定した物と違う値を書き込むって有りなの?

後、1/3ミリ秒単位って言うのも謎だし。

尚、SQLServer 2008 からは datetime2型が用意されて 100ナノ秒まで持てます。