Java 为什么PreparedStatement.setNull需要sqlType?

Java 为什么PreparedStatement.setNull需要sqlType?,java,sql,jdbc,Java,Sql,Jdbc,根据PreparedStatement.setNull的java文档:“注意:必须指定参数的SQL类型”。该方法需要列的SQL类型的原因是什么 我注意到传递java.sql.Types.VARCHAR也适用于非VARCHAR列。是否存在VARCHAR不适用的场景(某些列类型或某些DB提供程序) 谢谢 根据 PreparedStatement.setNull:“注意:您 必须指定参数的SQL 类型”。是什么原因导致 方法需要 专栏 最大限度地兼容;根据规范,有些数据库不允许向底层数据源发送非类型化

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

  • 我注意到传递java.sql.Types.VARCHAR也适用于非VARCHAR列。是否存在VARCHAR不适用的场景(某些列类型或某些DB提供程序)

  • 谢谢

    根据 PreparedStatement.setNull:“注意:您 必须指定参数的SQL 类型”。是什么原因导致 方法需要 专栏

    最大限度地兼容;根据规范,有些数据库不允许向底层数据源发送非类型化NULL

    我注意到路过 java.sql.Types.VARCHAR也适用于 非varchar列。有 VARCHAR不会出现的场景 合适的(某些列类型或 某些数据库提供商)


    我不认为这种行为真的是规范的一部分,或者如果是的话,那么我确信那里有某种隐含的强迫。在任何情况下,都不建议依赖这样的行为,当底层数据存储发生更改时,这种行为可能会中断。为什么不直接指定正确的类型呢?

    JDBC驱动程序似乎正在远离
    setNull
    。看

    我的数据库列表支持更具逻辑性的行为:

  • 神谕
  • MySQL
  • 赛贝斯
  • MS SQL Server
  • HSQL
  • 我列出的不支持此逻辑行为的数据库如下:

  • 德比
  • PostgreSQL

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


    --Lasse

    1。我仍然不明白为什么我必须声明类型。据我所知,使用SET MY_COLUMN=NULL的UPDATE命令将对每种列类型都有效,为什么还不够呢。我有一个方法,它获取一个SQL字符串和一个集合,并为每个对象调用PreparedStatement.setObject/setNull。如果我想将正确的类型传递给setNull,我需要传递每个对象的类型并创建一个丑陋的If。如果数据库驱动程序可以处理setObject,我认为它应该处理setNull并在内部进行检查。@user:1;正如我已经提到的,JDBC试图标准化与数据库的交互,但是每个数据库实现都有自己的方式。例如,我听说Oracle在设置NULL时会抱怨没有提供正确的类型。因此JDBC要求您指定类型,而底层JDBC实现是否将其传递给数据库则是另一回事。如果一个特定的数据库连接协议决定在设置空值时传递类型,那么就没有必要对此进行推理;这是你做出的设计决定。我不知道有任何db helper/包装器代码/框架试图向用户隐藏数据库类型。在hibernate中,可以指定注释/XML配置来设置列类型。在代码中添加一个处理用户提供类型的特性如何?如果这一切真的很麻烦的话,请把瓦查尔递过来,交叉手指,希望一切顺利。:-)