为什么PreparedStatement.setNull需要sqlType?

时间:2010-11-22 08:16:19

标签: java sql jdbc

  1. 根据PreparedStatement.setNull的java文档:“注意:您必须指定参数的SQL类型”。该方法需要列的SQL类型的原因是什么?

  2. 我注意到传递java.sql.Types.VARCHAR也适用于非varchar列。是否存在VARCHAR不适合的情况(某些列类型或某些数据库提供程序)?

  3. 感谢。

3 个答案:

答案 0 :(得分:11)

  

根据java文档   PreparedStatement.setNull:“注意:你   必须指定参数的SQL   类型“。是什么原因   方法需要SQL类型   列?

为获得最大兼容性;根据规范,有些数据库不允许将无类型的NULL发送到底层数据源。

  

我注意到了传球   java.sql.Types.VARCHAR也适用于   非varchar列。在那儿   VARCHAR不会出现的情况   适合(某些列类型或   某些数据库提供商)?

我不认为这种行为确实是规范的一部分,或者如果是,那么我确信那里会有某种隐含的强制行为。在任何情况下,都不建议依赖于在基础数据存储区更改时可能会中断的此类行为。为什么不指定正确的类型?

答案 1 :(得分:8)

JDBC驱动程序似乎正在远离setNull。请参阅Add support for setObject(<arg>, null)

支持更符合逻辑的行为的数据库列表是:

  1. 甲骨文
  2. MySQL的
  3. 的Sybase
  4. MS SQL Server
  5. HSQL
  6. 我不支持此逻辑行为的数据库列表是:

    1. 德比Queries with guarded null Parameter fail
    2. PostgreSQL Cannot pass null in Parameter in Query for ISNULL Suggested solution

答案 2 :(得分:1)

对于Oracle来说,将varchar2用于其他数据类型是非常不明智的。这可能会欺骗优化器,您可能会得到一个糟糕的执行计划。例如,在绑定中使用timestamp数据类型对日期列进行过滤时,Oracle最终可能会读取将所有日期转换为时间戳的所有行,然后过滤掉所需的行。 如果你的日期列上有索引,它甚至可能会变得更糟(如果oracle选择使用它) - 在你的oracle块上进行单次读取。

- 拉塞