SQL Loader时间戳到UNIX时间

时间:2015-01-07 20:09:34

标签: sql timestamp loader sql-loader milliseconds

我有一个用于sql loader的工作控制文件,我可以以各种格式上传我的时间戳。

 my_timestamp  TIMESTAMP \"dd-MON-yy hh.mi.ss.ff6 PM\",

但我想将我的.csv文件中的时间戳以毫秒为单位上传到我的数据库中的NUMBER字段。如果可能的话,有什么建议吗?

1 个答案:

答案 0 :(得分:0)

我假设您要剥离毫秒部分并将其单独存储。

未测试:

...
my_timestamp    TIMESTAMP  "dd-MON-yy hh.mi.ss.ff6 PM"
my_milliseconds NUMBER     "regexp_substr(:my_timestamp, '\.(\d+) ', 1,1,null,1)"
...

但是这样可行,所以上面应该有效:

select regexp_substr('07-JAN-14 04.24.00.123456 PM', '\.(\d+) ', 1,1,null,1) 
from dual; 

返回第一个组(由parens包围),它匹配由左边的句点和右边的空格包围的一个或多个数字的字符串的模式。

编辑:哦,你需要将整个时间戳转换为UNIX时间,这是自1970年1月1日0:0:0(纪元)以来的秒数。

首先,您需要使用公式将日期转换为UNIX时间。一个小小的谷歌搜索透露了这一个:

SELECT (cast(to_timestamp('14.03.2010 08:16:22.123456 AM','dd.mm.yyyy hh:mi:ss.FF6 AM')as date) - TO_DATE('01/01/1970 00:00:00', 'MM-DD-YYYY HH24:MI:SS')) *
24 * 60 * 60 
FROM DUAL;

结果为'1268554582'。使用epoch转换器将此UNIX时间转换回日期:http://www.epochconverter.com/验证返回了正确的日期。

那么,如何在控制文件中使用它?如果你可以像上面那样选择它,它可以像这样放在控制文件中:

...
my_timestamp    TIMESTAMP  "dd-MON-yy hh.mi.ss.ff6 PM"
my_unixtime     NUMBER     "(cast(:my_timestamp)as date) - TO_DATE('01/01/1970 00:00:00', 'MM-DD-YYYY HH24:MI:SS')) *
24 * 60 * 60"
...

您可能需要EXPRESSION关键字,我不确定:

my_unixtime NUMBER  EXPRESSION "(cast(:my_timestamp)as date) - TO_DATE('01/01/1970 00:00:00', 'MM-DD-YYYY HH24:MI:SS')) *
24 * 60 * 60"

现在适用于一列,但如果有很多,或者你想重用它?为了重用和可维护性,使用接受时间戳的函数将代码放在一个地方,并返回如上所述的unixtime,并从控制文件中调用它:

...
my_timestamp    TIMESTAMP  "dd-MON-yy hh.mi.ss.ff6 PM"
my_unixtime     NUMBER     "my_timestamp_to_unix_converter(:my_timestamp)"
...

注意事项:

毫秒丢失,因为UNIX时间是自1970年1月1日以来的秒,而不是毫秒。如果毫秒对您很重要,您可能需要单独保存它们,如上所示。

当2038年到来时可能会遇到麻烦:http://en.wikipedia.org/wiki/Year_2038_problem

资源:

http://www.epochconverter.com/

http://orcasoracle.squarespace.com/oracle-rdbms/2009/10/9/converting-timestamp-to-date.html

https://community.oracle.com/thread/1045221