【问题标题】:SQL Server 2005 to 2012 com.microsoft.sqlserver.jdbc.SQLServerException: Implicit conversion from data type varbinary to datetime2 is not allowedSQL Server 2005 到 2012 com.microsoft.sqlserver.jdbc.SQLServerException:不允许从数据类型 varbinary 到 datetime2 的隐式转换
【发布时间】:2016-01-14 19:02:38
【问题描述】:

我们正在从 SQL Server 2005 迁移到 2012。其中一项功能因此错误而失败

com.microsoft.sqlserver.jdbc.SQLServerException:不允许从数据类型 varbinary 到 datetime2 的隐式转换。使用 CONVERT 函数运行此查询。

我们使用 SQLJDBC driver 3.0 与 SQL Server 2012 进行通信。我发现当我们尝试将 NULL 值插入到 DATETIME 列(可为空)中时会发生此问题。但是在 2005 年也是如此。感谢您对此问题的任何帮助。

这是一个简单的INSERT 语句,使用 MyBatis ORM 从 Java 到 SQL Server 2012 失败:

Insert into temp_test (date1, name, date2) values ('2010-10-10 00:00:00.0','test',null) 

当我们从我们的应用程序(使用 SQL JDBC 驱动程序)尝试时,此插入失败...但是相同的代码库在 SQL 2005 中没有任何问题。

【问题讨论】:

  • 如果可能,请发MVCE,或者至少向我们提供尽可能多的代码和信息。
  • 在初始线程中添加了其他详细信息...
  • 请解释为什么您在问题中引用DATETIME2,但您声明该列的类型为DATETIME。在 SQL Server 2008 中还引入了DATETIME2...但您声明您正在从 2005 年迁移到 2012 年?这不加起来。请澄清。
  • 该错误消息也让我措手不及。表中的列是 DATETIME 但是当我们向 DB 发送空值时,SQLServer 2012 范式中正在发生 varbinary 到 datetime2 的隐式转换,因此我们看到此差异错误消息。
  • 您是否尝试过我在回答中给出的建议?

标签: sql-server-2005 sql-server-2012 mybatis sqljdbc


【解决方案1】:

我刚刚在 MyBatis 和 SQL Server 2012 中尝试执行 DATETIME2 列可能为空的插入时遇到了这个错误。我的问题的解决方案是在 MyBatis 文档中指定的映射器文件中指定 JDBC 类型。

发件人:http://www.mybatis.org/mybatis-3/sqlmap-xml.html#Parameters

JDBC 要求所有可空列的 JDBC 类型,如果 null 是 作为值传递。您可以通过阅读 PreparedStatement.setNull() 方法的 JavaDocs。

在映射器文件中的插入语句中,date2 列的值将添加“jdbctype = TIMESTAMP”,如下所示:

<insert id="testInsert" parameterType="com.example.object">
    INSERT INTO tempt_test
      (date1, name, date2)
    VALUES
      (#{date1}, #{name}, #{date2, jdbcType = TIMESTAMP})
</insert>

【讨论】:

  • 救命稻草。干杯!
【解决方案2】:

我可以推荐以下关于从迁移到 SQL Server 2012 的 read,由 Thomas LaRock (SolarWinds) 编写。

文章相关引述:

此外,如果不查看表格定义,很难就您的问题说出更具体的内容。不过,我建议以下几点:

  • DATE/TIME 字符串应尽可能采用ISO 8601 format 格式:例如'2010-10-10T00:00:00.0'
  • 如果您仍然遇到问题,请尝试使用 CAST('2010-10-10T00:00:00.0' AS DATETIME)CONVERT(DATETIME,datetimecolumn,&lt;format&gt;) 插入
  • compatibility level of your database 重置为适用于 SQL Server 2012 的版本:ALTER DATABASE &lt;database_name&gt; SET COMPATIBILITY_LEVEL=110;
  • 将您的SQLJDBC driver 升级到最新版本(当前版本为 6.0)
  • 使用不同的驱动程序,例如 JTDS JDBC Driver(开源 100% 纯 Java(类型 4)用于 Microsoft SQL Server 的 JDBC 3.0 驱动程序,支持 2012)
  • 为 SQL Server 2012 安装最新的 Service Pack(最新的是 Service Pack 3;overview)。
  • 查看MyBatis 是否与 SQL Server 2012 不兼容。

【讨论】:

  • 感谢您的详细评论。非常抱歉,回复这个问题比预期花费了一点时间。现在问题已经解决了。这是我们使用的 SQL JDBC 驱动程序的问题,以及 SQL 2012 为日期时间解释空值的方式。来自 Java 的插入查询应该有一个显式的转换函数来强制将其作为日期时间插入以避免这个意外错误。2005 或 2008 版本不是这种情况。例如:转换(日期时间,开始日期,21),
  • @Viggy 啊,我给的第二个建议 =)。我自己必须这样做一次。
  • @Viggy 如果您认为我的回答对未来遇到同样问题的访问者有价值,请接受或投票。 GL!
  • 仅供参考... Cast 也不起作用,但它必须隐藏功能。 cast 抛出了相同的异常堆栈。
  • @Viggy IC,我会将其更新为答案以供将来参考。
猜你喜欢
  • 1970-01-01
  • 2015-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-17
相关资源
最近更新 更多