从Oracle DB读取时,Date(数据类型)到TimeStamp(数据类型)的转换不正确

时间:2017-03-06 06:42:37

标签: scala apache-spark apache-spark-sql

我们正在尝试从Oracle表中读取数据,“基于日期”的数据类型将转换为“时间戳”数据类型。

例如:表是Oracle。

desc hr.employees;

Name Null? Type
-----------------------------------------
EMPLOYEE_ID NOT NULL NUMBER(6)
FIRST_NAME VARCHAR2(20)
LAST_NAME NOT NULL VARCHAR2(25)
EMAIL NOT NULL VARCHAR2(25)
PHONE_NUMBER VARCHAR2(20)
HIRE_DATE NOT NULL DATE
JOB_ID NOT NULL VARCHAR2(10)
SALARY NUMBER(8,2)
COMMISSION_PCT NUMBER(2,2)
MANAGER_ID NUMBER(6)
DEPARTMENT_ID NUMBER(4)
SSN VARCHAR2(55)

在Scala中的DataFrame中读取架构

|-- EMPLOYEE_ID: decimal(6,0) (nullable = false)    
|-- FIRST_NAME: string (nullable = true)    
|-- LAST_NAME: string (nullable = false)    
|-- EMAIL: string (nullable = false)    
|-- PHONE_NUMBER: string (nullable = true)    
|-- HIRE_DATE: timestamp (nullable = false) (Incorrect data type read here)    
|-- JOB_ID: string (nullable = false)    
|-- SALARY: decimal(8,2) (nullable = true)    
|-- COMMISSION_PCT: decimal(2,2) (nullable = true)    
|-- MANAGER_ID: decimal(6,0) (nullable = true)    
|-- DEPARTMENT_ID: decimal(4,0) (nullable = true)    
|-- SSN: string (nullable = true)

Hire_Date被错误地读作TimeStamp,有没有办法纠正。

正在从Oracle中即时读取数据,并且应用程序没有数据类型的预先知识,并且在读取后无法转换它。

1 个答案:

答案 0 :(得分:0)

<强>分析: 按照oracle -

  

Oracle Database 8i及更早版本不支持TIMESTAMP   数据,但Oracle DATE数据曾用于将时间组件作为   SQL标准的扩展。所以,Oracle Database 8i和更早版本   JDBC驱动程序的版本将oracle.sql.DATE映射到java.sql.Timestamp   保留时间组件。从Oracle Database 9.0.1开始,   包含TIMESTAMP支持,9i JDBC驱动程序开始映射   oracle.sql.DATE到java.sql.Date。这种映射不正确   截断了Oracle DATE数据的时间组件。为了克服这一点   问题,Oracle Database 11.1引入了一个新的标志   mapDateToTimestamp。该标志的默认值为true,即   意味着默认情况下驱动程序将正确映射oracle.sql.DATE   到java.sql.Timestamp,保留时间信息。如果你还是   想要不正确但10g兼容的oracle.sql.DATE到java.sql.Date   映射,然后你可以通过设置值来获得它   mapDateToTimestamp标志为false。

参考链接为here

<强>解决方案:

  1. 所以oracle的指示提供属性jdbc.oracle.mapDateToTimestamp为false -

      Class.forName("oracle.jdbc.driver.OracleDriver")
      var info : java.util.Properties = new java.util.Properties()
      info.put("user", user)
      info.put("password", password)
      info.put("oracle.jdbc.mapDateToTimestamp", "false")
      val jdbcDF = spark.read.jdbc(jdbcURL, tableFullName, info)
    
  2. 添加支持“oracle.jdbc.mapDateToTimestamp”标志的Oracle数据库连接器jar是ojdbc14.jar

  3. 希望它有所帮助!