Oracle jdbc和sqllr的双重问题

时间:2012-05-06 14:59:16

标签: oracle jdbc sql-loader

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

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

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

oracle中此列的数据类型为DATE,因此我将resultSetMeta返回的columnType表示为DATE,但始终为TIMESTAMP

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

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

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

1987-06-17 00:00:00.0

sqlldr在没有任何警告的情况下成功地将这些数据加载到Oracle中,但是当我检查目标表时,我得到的日期为'16 -Jun-1987'而不是预期/需要'17 -Jun-1987'。这可能是因为oracle解释了时间“00:00:00.0”。

上述问题1和2都是严重的问题,我无法找到解释。

1 个答案:

答案 0 :(得分:1)

SQL标准DATE type没有时间组件; Oracle's implementation does,具有第二精度,所以即使您只存储日期,您也可以免费获得时间。

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

在JDBC中,Oracle DATE必须被视为SQL TIMESTAMP,否则时间部分将丢失。如果你不想在Jave中有时间你可以将它投射到日期类型,但我认为它不会帮助你解决第二个问题。

SQL * Loader问题看起来可能是时区问题。看来您使用的日期是正常的,或者至少是一致的(即使您丢失了明确的时间,Oracle也会将其视为00:00;请参阅data types)。

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