一个很小的问题(java date类型存oracle数据库)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个很小的问题(java date类型存oracle数据库)相关的知识,希望对你有一定的参考价值。

我使用下面的语句:
SimpleDateFormat sdf = new SimpleDateFormat("yy-MM-dd hh:mm:ss");
String nowdate = sdf.format(new Date());
System.out.println(nowdate);
sql = insert into tablename(colname) values('nowdate')----字段colname为ORACLE date类型
运行后输出:
----->08-09-11 10:22:27
----->ORA-01843: 无效的月份

我也试过了其他的方法,类似的有:
Date dat =new date()
sql中把nowdate换成 dat.toString()
同时执行不行的

我查看了一下ORACLE中:select * from NLS_SESSION_PARAMETERS
得到:NLS_DATE_FORMAT ----DD-MON-RR
NLS_DATE_LANGUAGE----SIMPLIFIED CHINESE
我尝试了修改:NLS_DATE_FORMAT ----为:DD-MM-RR或DD-MON-YY或DD-MM-YYYY
NLS_DATE_LANGUAGE----为:AMERICAN
等等上面类似的,也试过他们的组合都不行的。同时我在调试的时候也修改过SimpleDateFormat sdf = new SimpleDateFormat("yy-MM-dd hh:mm:ss")中的格式,多种组合都不行的

有详细解决办法并给出代码且运行成功的追加分数 谢谢了!!
。。。。。。。。。。。。。。。。。。。。。。。。。。。。
对于兄弟: chinagenius补充的回答:
我按照你的方法:
SimpleDateFormat sdf = new SimpleDateFormat("yy-MM-dd hh:mm:ss");
String nowdate = sdf.format(new Date());
System.out.println(nowdate);
sql= "insert into tablename(colname) values(to_date('"+nowdate+"','yy-MM-dd hh:mm:ss'))";
statement.execute(sql);这样肯定就好了
还是报错: ORA-01810: 格式代码出现两次

然后我把你的代码改成了:
sql= "insert into tablename(colname) values(to_date('"+new Date()+"','yy-MM-dd hh:mm:ss'))";
statement.execute(sql)
还是报错: ORA-01810: 格式代码出现两次

我都块崩溃了

修改答复:很抱歉,java.sql.Date()肯定是在什么地方用的,好像是Hibernate的时候可以直接设值,现在不用Hibernate就只能用to_date函数了 改成下面的吧 呵呵!!

import java.util.Date;导入util包下的Date类 用于后面to_date使用

SimpleDateFormat sdf = new SimpleDateFormat("yy-MM-dd hh:mm:ss");
String nowdate = sdf.format(new Date());
System.out.println(nowdate);
sql= "insert into tablename(colname) values(to_date('"+nowdate+"','yy-MM-dd hh:mm:ss'))";

statement.execute(sql);这样肯定就好了
参考技术A 实现思路:首先oracle数据库中的表必须是有字段类型是date类型,之后即可通过java方式进行插入,如插入当前时间:
oracle中当前时间用sysdate表示。所以可以通过如下方式插入:
string
userinfo="insert
into
userinfo
values("+"'"+userd+"',sysdate"+")";
//之后执行插库操作。
备注,实际在数据库中插入语句如下
sql:insert
into
userinfo
values('123',sysdate);
参考技术B 你的这个语句:insert into tablename(colname) values('nowdate')
插入的实际上为 'nowdate'字符串,而不是nowdate变量的值
你可以:
sql = insert into tablename(colname) values(?)
然后再匹配值
statement.setString(0,nowdate);
然后执行
你试试吧

答复补充:
查一下你的数据库colname字段试不是char类型,(注意不能是DATE类型)。
参考技术C SimpleDateFormat sdf = new SimpleDateFormat("yy-MM-dd");
String nowdate = "'"+sdf.format(new Date())+"'";
/*不好意思刚忘记了*/
String value = "char2date("+ nowdate + ",'yyyy-mm-dd')";
System.out.println(nowdate);
sql = insert into tablename(colname) values(value)

注意区别
参考技术D 你直接用数据库时间不久可以了sysdate

java.sql.date , java.sql.timestamp 谓词 -> Oracle 分区数据类型

【中文标题】java.sql.date , java.sql.timestamp 谓词 -> Oracle 分区数据类型【英文标题】:java.sql.date , java.sql.timestamp predicate -> Oracle partition data type 【发布时间】:2014-06-09 08:34:16 【问题描述】:

您好,我们有很大的 Oracle 列对象,我们已使用 DATE

数据类型 对其进行分区

其中一个分区如下所示:

GCP_P1  TO_DATE(' 2011-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN') 83  M_DATA01    DISABLED    348132  15214   146 08.06.2014 02:20:40 1078    0

每个分区为一周。

我们通过带有 jdbc 的瘦客户端运行我们的 sql。没有 ORM,只有纯 jdbc。

当分区列的谓词项是 java.sql.timestamp 时,我们意识到查询不会从分区中受益。但是,当它是 java.sql.date 类型时,执行计划显示成功的分区访问。

例如,我们的 sql 看起来像这样:

SELECT COUNT(1) FROM ATABLE WHERE PARTITIONED_COLUMN > ?

当我们的java语句是:

preparedStatement.setDate(...); // it benefits from partition

但是当它是这样的时候:

preparedStatement.setTimestamp(...); //it does not benefits from partition

我正在从蟾蜍那里寻找它们。我有经验,当它是java.sql.date时,它在oracle上被解释为DATE,当它是java.sql.timestamp时它被解释为TIMESTAMP

我正在使用以下 sql 语句跟踪捕获的 jdbc 日期类型

SELECT *
  FROM V$SQL_BIND_CAPTURE
WHERE WAS_CAPTURED = 'YES' AND LAST_CAPTURED BETWEEN SYSDATE-1/50 AND SYSDATE
ORDER BY LAST_CAPTURED DESC;

我的问题是你遇到过这样的问题吗?如果是这样,你会指导我看一些文件吗?

【问题讨论】:

【参考方案1】:

您描述的案例记录在第 8 节 - 映射"Getting Started with the JDBC API" 的 SQL 和 Java 类型

8.3.12 DATE, TIME, and TIMESTAMP

因为标准 Java 类 java.util.Date 不匹配任何 这三种 JDBC 日期/时间类型(它包括 DATE 和 TIME信息但没有纳秒),JDBC定义了三个 java.util.Date 的子类以对应于 SQL 类型。它们是:

java.sql.日期

用于 SQL 日期信息。时、分、秒和 java.util.Date 基类的毫秒字段应设置为 零。如果提供给 java.sql.Date 的毫秒数 构造函数是否定的,驱动程序将计算日期为 1970 年 1 月 1 日之前的毫秒数。否则,日期为 计算为 1 月 1 日之后的指定毫秒数, 1970 年。

java.sql.Time

用于 SQL TIME 信息。年、月、日 java.util.Date 基类的字段设置为 1970 年、1 月和 1. 这是 Java 时代的“零”日期。

java.sql.时间戳

用于 SQL TIMESTAMP 信息。此类通过添加扩展 java.util.Date 纳秒字段。

【讨论】:

虽然这是关于 jdbc 类型的好信息,但它对 Oracle 的 DATE 类型的细节以及它如何映射到 jdbc 类型没有帮助。 映射的逻辑出现了。由于这是实现细节,因此无需编写可能会有所不同。要使用 Oracle DATE 类型的细节,您应该退出 Java API 并使用 oracle.sql 包。恕我直言,这里不是这种情况,因为这是在驱动程序内部完成的。 几乎可以肯定这里的问题是使用的列是 Oracle DATE 类型。通过使用标准的 jdbc setTimestamp 方法,oracle 在幕后进行强制转换。要获得所需的行为(能够利用索引或分区),必须处理 oracle.sql.DATE ojdbc 对象。 你说得对。但这是通过映射指定的。如果您使用java.sql.Date,将使用日期,另一方面,当您使用java.sql.Timestamp 时,将使用TIMESTAP,但如果您在DATE 列上使用setTimestamp。 JDBC 在oracle.sql.Timestap 的实例上创建并传递它。因为TIMESTAMP 宽了 4 个字节(纳秒)。在准备执行计划期间,引擎找不到TIMESTAP 类型的索引,因此它不会使用它。这意味着决定是在 db 级别而不是 jdbc 上。 结束用户应确保从 API 调用有效方法,正确性基于发布的映射。另一种方法是将参数直接传递给您在答案中描述的语句。但是我们仍然必须知道该类型在 DB 中,如果我们使用 oracle.sql.DATE 我们会成功,但如果我们使用 oracle.sql.TIMESTAP 我们会像 OP 一样失败。【参考方案2】:

oracle jdbc developers guide 包含从 jdbc 类型到 oracle 数据类型的映射。由于其复杂性,有一个特定于 DATE 数据类型的section。它有以下注释:

在 Oracle 数据库 11g 中,如果您在 DATE 列上有索引 由 SQL 查询使用,然后为了获得更快和准确的结果,您 必须按以下方式使用 setObject 方法:

 Date d = parseIsoDate(val); 
 Timestamp t = new Timestamp(d.getTime());
 stmt.setObject(pos, new oracle.sql.DATE(t,(Calendar)UTC_CAL.clone()));

【讨论】:

以上是关于一个很小的问题(java date类型存oracle数据库)的主要内容,如果未能解决你的问题,请参考以下文章

java 中怎么把字符串转为oracle date类型

oracle能单独存一个不带时间的日期么?或者是不带日期的时间

java类里 Date 类型的数据存数据库里时对应的字段类型也是Date的类型,存的时候格式应该为啥?

java.sql.date , java.sql.timestamp 谓词 -> Oracle 分区数据类型

java Date时间的各种转换方式和Mysql存时间类型字段的分析

oracle 中时间类型 date 与 long 互转