datax之oraclereader读取时间类型字段问题学习
创始人
2025-05-31 15:13:49

众所周知 hive是字段类型不敏感的,比如date 2022-01-01 和string 2022-01-01 在大多数情况下都是可以呼唤的。我们这边为了方便经常将oracle的date字段 在hive中直接用string字段去替代,最近发现了一个问题。

表中字段如下 字段类型是date。 注意这个date 不是datetime。

 

date类型只保留年月日 不保留时分秒 

所以我们一般来说看到这个date 数值就是年月日,但是因为工具看到的也不同 我用dbeaver看到的如上,同事用的哪个工具忘了如下

当然 我猜测底层存储的肯定是1469635200000 这种,时分秒的单位都归0了

这时候我们要明确一个问题,前端需要看到的到底是什么? 如果你想看到年月日时分秒,那么datax就是这么做的。

但是如果你想看到的只是年月日,那么就需要自己去改了。当然你在hive用date类型接受也没有问题。

学习一下源码。

CommonRdbmsReader.java

// for mysql bug, see http://bugs.mysql.com/bug.php?id=35115
--你看这里还有bug。。 这里才是 年月日 没有时分秒
case Types.DATE:if (metaData.getColumnTypeName(i).equalsIgnoreCase("year")) {record.addColumn(new LongColumn(rs.getInt(i)));} else {record.addColumn(new DateColumn(rs.getDate(i)));}break;case Types.TIMESTAMP:record.addColumn(new DateColumn(rs.getTimestamp(i)));break;

注意 oracle的date类型属于这里的 Types.TIMESTAMP 

 DateColumn.java

/*** 构建值为ts(java.sql.Timestamp)的DateColumn,使用Date子类型为DATETIME* */
public DateColumn(final java.sql.Timestamp ts) {this(ts == null ? null : ts.getTime());this.setSubType(DateType.DATETIME);
}

设置datecolumn的类型为datetime, 并且把值ts 传进去了。

然后我们看取出来是怎么取的

@Override
public String asString() {try {return ColumnCast.date2String(this);} catch (Exception e) {throw DataXException.asDataXException(CommonErrorCode.CONVERT_NOT_SUPPORT,String.format("Date[%s]类型不能转为String .", this.toString()));}
}@Override
public Date asDate() {if (null == this.getRawData()) {return null;}return new Date((Long)this.getRawData());
}
---这里就是as string的后续方法
static String asString(final DateColumn column) {if (null == column.asDate()) {return null;}switch (column.getSubType()) {case DATE:return DateFormatUtils.format(column.asDate(), DateCast.dateFormat,DateCast.timeZoner); --yyyy-MM-ddcase TIME:return DateFormatUtils.format(column.asDate(), DateCast.timeFormat,DateCast.timeZoner);case DATETIME:return DateFormatUtils.format(column.asDate(),DateCast.datetimeFormat, DateCast.timeZoner);--yyyy-MM-dd HH:mm:ssdefault:throw DataXException.asDataXException(CommonErrorCode.CONVERT_NOT_SUPPORT,"时间类型出现不支持类型,目前仅支持DATE/TIME/DATETIME。该类型属于编程错误,请反馈给DataX开发团队 .");}
}

所以问题很清楚了,

就是oracle对于date类型数据 在java的types里对应的是timestamp

对于mysql的date类型来说对应的就是date 只保留年月日。

这里有点不是特别理解,oracle的date和mysql的date哪里不一样?

CREATE TABLE test.cc_test_time(
t1 DATE,
t2 timestamp
)

String querySql = "SELECT * from test.cc_test_time "; rs = demo.execQuery(querySql); ResultSetMetaData metaData = rs.getMetaData(); for (int i = 1; i <= metaData.getColumnCount(); i++) { System.out.println("columntype="+metaData.getColumnType(i)); }

INSERT INTO test.cc_test_time VALUES (sysdate,sysdate)

columntype=93
columntype=93

 

而且经过我的测试 oracle的date 和timestamp类型 对应的都是 93也就是timestamp,所以datax在对oracle取数的时候,这两个类型是区分不了的。。

具体我就不尝试了。比如timestamp精确到毫秒 ,我猜测datax也忽略了毫秒,反正统一都是年于日时分秒。 

相关内容

热门资讯

美联储降息分析,叙事转变的风险... 来源:宏观对冲陈凯丰Kevin但在我看来,这需要比普遍说法更长的时间才能显现出来……事实上,历史告诉...
环球下周看点:三大央行决议重磅... 财联社12月14日讯(编辑 牛占林)随着甲骨文和博通接连释放利空消息,有关人工智能(AI)热潮的担忧...
2025中关村量子大会开幕 集... (来源:千龙网)12月13日,以“量智新纪,产链未来”为主题的中关村量子大会在北京中关村国际创新中心...
青海省提升困境儿童心理健康关爱... 本报讯(西海新闻记者 周建萍)“难过的时候不用憋着,大声哭出来就好;遇到不开心的事,找信任的人聊一聊...
以军称在加沙城打死哈马斯一高级... 转自:宁波晚报以色列国防军13日发表声明说,不久前在加沙城袭击了一名巴勒斯坦伊斯兰抵抗运动(哈马斯)...