テーブルのカラムへの null 値の代入
PreparedStatement を用いて null を入れる場合、
statement.setObject(index, null)
とするのがお手軽ではありますが、SQL Server では binary, varbinary 型のカラムに setObject で null を入れられません。
そこで、仕方なく setNull を使うのですが、setNull は他の set*** 系メソッドと違い、第二引数にカラムの JDBC 型を渡す必要があり、面倒です。
PreparedStatement であれば、こいつの getParameterMetaData や getMetaData で SQL 発行前に ParameterMetaData, ResultSetMetaData を取得できるのですが、JDBC ドライバは PreparedStatement#(getParameterMetaData|getMetaData) で null を返してもよい仕様になっている(そして、大抵の JDBC ドライバがそうする)ため、これだけでは不安です。
というわけで、java.sql.Types.NULL を使いましょう。
見落とされがちな SQL タイプですが、javadoc にはきちんと「総称 SQL 値 NULL を識別します」と書かれています。
要は、SQL Server の binary, varbinary に対しては、setObject(index, null) の代わりに、setNull(index, java.sql.Types.NULL) を使いましょう、ということです。
※追記
setXxx(数値型の場合、setObject、それ以外の場合、setString 等)で null を入れると、すべてうまくいくようです。
以下、調査結果の抜粋です。
- setObject(index, null)
- SQL Server では、binary, varbinary 型のカラムに対してはエラー
- 自分が試した限り、PostgreSQL8.3, Oracle11g, DB2 9.7 では問題なし
- setNull(index, java.sql.Types.NULL)
- SQL Server では、date, datetime2, float, text, ntext, real, time 型のカラムに対してはエラー
- 自分が試した限り、PostgreSQL8.3, Oracle11g, DB2 9.7 では問題なし
- setXxx
- 数値型に対しては setObject(setInt や setDouble には null を渡せないため)、それ以外、例えば varchar や binary には setString(null), setBinary(null) とする方法
- DB2, Oracle, PostgreSQL, SQL Server の各カラムで正常動作