【问题标题】:Java Date for Sql insert用于 Sql 插入的 Java 日期
【发布时间】:2015-08-26 15:34:26
【问题描述】:

我试图在 oracle 数据库中插入一个日期,但我一直面临转换问题。

public List<Customer> getCustomerData(Date start, Date end) {
...
String query = "SELECT name FROM customers WHERE trunc(order_timestamp) between trunc(?) and trunc(?)";

DateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
pst.setDate(1, new java.sql.Date(sdf.parse(sdf.format(start)).getTime()));

pst.setDate(2,  new java.sql.Date(sdf.parse(sdf.format(end)).getTime()));

}

来自我的来电者

SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
Date start = sdf.parse("10/10/2014");
Date end = sdf.parse("10/10/2016");
customerDao.getCustomerData(start,end);

我得到的错误是:

Caused by: org.h2.jdbc.JdbcSQLException: Data conversion error converting "2014-10-10"; SQL statement:
select name from customers where trunc(order_timestamp) between trunc(?) and trunc(?)  [22018-160]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
    at org.h2.message.DbException.get(DbException.java:158)
    at org.h2.value.Value.convertTo(Value.java:852)
    at org.h2.engine.FunctionAlias$JavaMethod.getValue(FunctionAlias.java:366)
    at org.h2.expression.JavaFunction.getValue(JavaFunction.java:38)
    at org.h2.expression.Comparison.getValue(Comparison.java:206)
    at org.h2.expression.ConditionAndOr.getValue(ConditionAndOr.java:83)
    at org.h2.expression.ConditionAndOr.getValue(ConditionAndOr.java:90)
    at org.h2.expression.Expression.getBooleanValue(Expression.java:180)
    at org.h2.command.dml.Select.queryFlat(Select.java:514)
    at org.h2.command.dml.Select.queryWithoutCache(Select.java:617)
    at org.h2.command.dml.Query.query(Query.java:298)
    at org.h2.command.dml.Query.query(Query.java:268)
    at org.h2.command.dml.Query.query(Query.java:37)
    at org.h2.command.CommandContainer.query(CommandContainer.java:82)
    at org.h2.command.Command.executeQuery(Command.java:185)
    at org.h2.jdbc.JdbcPreparedStatement.executeQuery(JdbcPreparedStatement.java:96)
    at com.customerDaoImpl.custDao.getParentContextdata(custDao.java:431)
    ... 29 more
Caused by: java.lang.NumberFormatException: For input string: "2014-10-10"
    at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1222)
    at java.lang.Double.parseDouble(Double.java:510)
    at org.h2.value.Value.convertTo(Value.java:831)
    ... 44 more

我认为发生的事情是 getTime() 会将日​​期重新格式化为 yyyy-MM-dd 格式,而输入是 n MM/dd/yyyy 格式。但我不确定这是否正是导致问题的原因。

编辑: H2 不支持 trunc 但您可以编写要调用的外部脚本。

Customer.sql

drop ALIAS if exists TRUNC;
CREATE ALIAS TRUNC as '
import java.text.*;
@CODE
double trunc(double num) throws Exception {
    return Math.floor(num*10) /10;
}
';

【问题讨论】:

  • 如果您不确定输入的确切格式,您需要另一种格式 (yyyy-MM-dd) 或帮助方法来尝试解析多种格式。
  • getTime() 返回毫秒数。它怎么可能重新格式化任何东西。发布 complete 异常堆栈跟踪。
  • 听起来您需要两种日期格式:一种用于“yyyy-MM-dd”,另一种用于“MM/dd/yyyy”。 getTime() 返回自纪元以来的毫秒数。完全没有格式。
  • 错误很明显:您发送日期为"yyyy-MM-dd",而您的模式为"MM/dd/yyyy"。您希望它如何工作?
  • 我的问题是你为什么要这样做:pst.setDate(1, new java.sql.Date(sdf.parse(sdf.format(start)).getTime())); 当你可以这样做时:pst.setDate(1, new java.sql.Date(start.getTime()));

标签: java sql date h2


【解决方案1】:

正如堆栈跟踪所示,您根本没有使用 Oracle。您正在使用 H2。 而且 H2 似乎没有任何trunc 函数接受日期作为参数。

无论如何,这个函数调用是没有用的,因为你已经传递了一个日期,没有任何时间部分,作为参数。 trunc 操作,如果存在的话,什么都不做。

【讨论】:

  • 这就是这个策略的问题:你最终会得到通过的测试,尽管它们在真正的生产数据库中会失败,反之亦然。不知道为什么这么多人更喜欢这样,而不是失去几秒钟的时间来瞄准真实的数据库。
  • 已更新:至于 trunc,您可以编写脚本函数,数据库将调用该函数,我已将其添加到编辑中。
【解决方案2】:

似乎需要 DATETIME 或 TIMESTAMP,因此请使用 Timestamp 而不是 sql Datejava.sql.Date 仅适用于几天,将家长的课程小时、分钟和秒设置为零。

【讨论】:

  • 数据转换错误转换“2014-10-10 00:00:00.0”。它仍然存在
【解决方案3】:

您的外部trunc 脚本需要double 作为输入,但您传递的是java.sql.Date。试试这个脚本:

drop ALIAS if exists TRUNC;
CREATE ALIAS TRUNC as '
import java.text.*;
import java.lang.*;
import java.sql.Date;
@CODE
double trunc(Date date) throws Exception {
    return Math.floor(new Long(date.getTime()).doubleValue()*10) / 10;
}
';

虽然我怀疑你会收到另一个错误,抱怨你试图将double 值与between 进行比较。您的trunc 脚本不应该也返回一个日期吗?如果应该,那么只需返回日期:

drop ALIAS if exists TRUNC;
CREATE ALIAS TRUNC as '
import java.text.*;
import java.lang.*;
import java.sql.Date;
@CODE
Date trunc(Date date) throws Exception {
    return date;
}
';

如果可行,您可以稍后改进此脚本以在 date 上应用您想要的任何其他操作来模拟您的 trunc 行为。

为了记录,这里是将您的日期转换为“yyyy-MM-dd”模式的 H2 代码:ValueDate.java#158。 字符串值存储在这里Value.java#827,然后在这里被Double解析器方法使用:Value.java#876

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-24
    • 1970-01-01
    相关资源
    最近更新 更多