0

我面临两个我认为可能相关的问题。

我正在尝试对 oracle (10g) 数据库执行 JDBC 选择,结果集将日期列显示为时间戳

    ResultSetMetaData rsMetaData = null;  
    rsMetaData = resultSet.getMetaData();  
    if(rsMetaData.getColumnType(1) == java.sql.Types.TIMESTAMP){
        System.out.println("Timestamp");
    }

oracle 中此列的数据类型是 DATE 所以我希望返回的 columnTyperesultSetMeta是 DATE 但它总是TIMESTAMP

处理完这些数据后,我尝试使用 sqlldr 将其加载到 Oracle 数据库由于输入中接收到的数据类型错误,输出控制文件使用 TIMESTAMP。(这个控制文件是由我的程序基于 resultSetMetaData 创建的。)这正是它在控制文件中的显示方式。

TIMESTAMP "yyyy-MM-dd HH24:mi:ss.ff"  

当我尝试使用此控制文件加载以下数据时,问题就开始了。

1987-06-17 00:00:00.0

sqlldr 成功地将这些数据加载到 Oracle 中而没有任何警告,但是当我检查目标表时,我得到的日期为“1987 年 6 月 16 日”,而不是预期/要求的“1987 年 6 月 17 日”。这可能是因为 oracle 解释时间“00:00:00.0”的方式。

上面的问题 1 和 2 对我来说都是严重的问题,我找不到解释。

4

1 回答 1

1

SQL 标准DATE类型没有时间组件;Oracle 的实现具有秒精度,因此即使您只存储一个日期,您也可以免费获得时间。

如果您插入特定日期,例如to_date('06/05/2012', 'DD/MM/YYYY')或 literal date '2012-05-06',则时间将为午夜。如果您插入一个带有时间的值,例如SYSDATE,它将被保留。无论哪种方式,如果您通过 SQL*Plus 或类似方式进行查询,而没有指定包含时间的日期格式掩码,它可能看起来只是一个日期,但时间会在那里,只是不显示。

在 JDBC 中,必须将 OracleDATE视为 SQL TIMESTAMP,否则时间部分将丢失。如果您不想要 Jave 中的时间,您可以将其转换为日期类型,但我认为这不会帮助您解决第二个问题。

SQL*Loader 问题看起来可能是时区问题。看来您使用的日期是可以的,或者至少是一致的(即使您丢失了明确的时间,Oracle 也会将其视为00:00无论如何;请参阅数据类型)。

我只能猜测,无论您sqlldr从哪里运行,都与您查询的时区不同,可能来自环境变量。例如,如果一个人知道现在是夏令时而另一个人不知道,那么您的查询可能会在 16 日显示 23:00 - 您需要使用明确的日期格式掩码进行查询以检查 - 因为 GMT/BST 之间的小时差, EST/EDT 等。在不了解您的环境的情况下,很难说出正在发生的事情。不过,大胆猜测,您可能正在Java 调用 SQL*Loader,我可以想象这会引起混乱。

于 2012-05-07T07:07:34.707 回答