sqlserver 使用原生 JDBC 做基本的数据插入操作,总是插入不进去,抛如下异常:
com.microsoft.sqlserver.jdbc.SQLServerException: 不支持从 UNKNOWN 到 UNKNOWN 的转换。 at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:190) at com.microsoft.sqlserver.jdbc.DataTypes.throwConversionError(DataTypes.java:1117) at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.setObject(SQLServerPreparedStatement.java:991) at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.setObjectNoType(SQLServerPreparedStatement.java:926) at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.setObject(SQLServerPreparedStatement.java:935) at net.techfuser.qnhclient.task.downservice.OrderServiceDownQnhZjkTask.downQnhZjk(OrderServiceDownQnhZjkTask.java:153)
跑错代码如下:
String orderInsertSql = "insert into qnh_order(" + fields.toString() + ") values(" + values.toString() + ")"; log.debug( "构造完成 orderInsertSql: " + orderInsertSql ); PreparedStatement pstmt = connection.prepareStatement(orderInsertSql); for(int j = 0;j < orderValues.size(); j++){ Object val = orderValues.get(j); log.debug(j + ":预绑定sql " + orderFields.get(j) + ":" + val ); pstmt.setObject(j+1, val); }
解决:
PreparedStatement 在绑定 Date 的时候不支持 java.util.Date类型, 因此需要将其转换为 java.sql包下相应的日期时间类型,最终修复后的代码如下:
PreparedStatement pstmt = connection.prepareStatement(orderInsertSql); for(int j = 0;j < orderValues.size(); j++){ Object val = orderValues.get(j); log.debug(j + ":预绑定sql " + orderFields.get(j) + ":" + val ); if(val instanceof Date) { val = new java.sql.Timestamp(((Date) val).getTime()); } pstmt.setObject(j+1, val); }
执行程序是执行到一半卡住
在处理这个异常之前,还出现程序在eclipse (jdk 1.8) 中正常的执行,使用gradle 打成jar 包后执行程序时执行到一半卡住不继续执行也不抛出任何异常信息,最终定位问题是 String.join("," , fieldList) 方法造成的,String.join() 是JDK1.8才支持的方法,jar 包最终运行的环境是JDK 1.7 因此出现上述的异常现象。在此过程中我 gradle 明确指定使用 1.7 编译却没有编译报错,可能是我gradle哪里配置不对或者gradle本身就存在bug。