sqlserver datetime到oracle timestamp的问题

时间:2016-06-20 14:43:33

标签: python sql-server oracle cx-oracle

所以我正在开发一个项目,将数据从sql server db移动到oracle db,日期让我很难过。为了进行数据移动,我有一个python脚本,它从sql server db中提取数据,然后运行一个插入查询。

问题是日期看起来像2016-06-01 05:45:06.003但是如果我删除小数秒它会违反主键,因为2016-06-01 05:45:06有很多记录但{{1}只有一个记录所以它必须有毫秒。

我应该提到oracle中列的数据类型是TIMESTAMP

如果我只是拉取记录并运行我的插入这只是一个基本插入,其值为2016-06-01 05:45:06.003

这样做会让我的日期看起来像VALUES(:1, :2, :3, :4, :5, :6, :7, :8, :9, :10, :11, :12, :13, :14, :15)。这样会很好但是对于每一条记录,小数秒都是000000,所以我失去了准确性,这使我违反了主键。

我认为修复将是明确的格式,所以我修改了insert语句值子句,就像这个01-JUN-16 07.05.41.000000000 AM。这更糟糕,因为它将每行中的所有日期更改为VALUES(TO_TIMESTAMP(:1, 'YYYY-MM-DD HH24:MI:SS,FF9'), :2, :3, :4, :5, :6, :7, :8, :9, :10, :11, :12, :13, :14, :15)我也尝试16-JUN-20 12.00.00.000000000 AM,但这会产生相同的结果。

我确信这是一件令人愚蠢的事情,我不知道但是对于我的生活,我不知道它是什么。

自从被问到,sql server表上的列的数据类型是YYYY-MM-DD HH24:MI:SS,FF9,而在oracle服务器上我将它当前设置为DateTime但是我可以更改oracle端的数据类型

我正在使用cx_oracle来连接并运行插入。我可以确认在插入运行之前数据确实有毫秒。

蟒蛇:

TimeStamp(3)

2 个答案:

答案 0 :(得分:2)

您遇到的内容可能与您的nls格式设置有关。但是,我没有看到使用to_timestamp

的问题
with sample_data as (select '2016-06-01 05:45:06.003' col1 from dual union all
                     select '2016-06-01 12:55:06.638' col1 from dual union all
                     select '2016-06-02 11:53:24.827' col1 from dual)
select col1,
       to_timestamp(col1, 'yyyy-mm-dd hh24:mi:ss.ff3') col1_ts,
       to_char(to_timestamp(col1, 'yyyy-mm-dd hh24:mi:ss.ff3'), 'yyyy-mm-dd hh24:mi:ss.ff3') col1_ts_str
from   sample_data;

COL1                    COL1_TS                                            COL1_TS_STR                  
----------------------- -------------------------------------------------- -----------------------------
2016-06-01 05:45:06.003 01/06/2016 05:45:06.003000000                      2016-06-01 05:45:06.003      
2016-06-01 12:55:06.638 01/06/2016 12:55:06.638000000                      2016-06-01 12:55:06.638      
2016-06-02 11:53:24.827 02/06/2016 11:53:24.827000000                      2016-06-02 11:53:24.827  

(col1_ts列是由oracle存储的时间戳,作为字符串以默认格式返回(在不同的客户端上可能会有所不同,具体取决于它们是否与其nls格式混淆),而col1_ts_str是timestamp以我请求的特定格式返回为字符串。

您应该通过在时间戳列上执行to_char来检查数据是否已正确输入,例如

select to_char(your_timestamp_column, '<format>') ts_col
from   your_table;

答案 1 :(得分:2)

This Oracle article警告说:

  

除非在prepare()和execute()

之间使用setinputsizes()方法,否则将截断作为绑定变量传递的日期/时间值的小数秒

文章的示例显示,为了节省毫秒,您需要指定How's it going? Yo! 参数的输入大小:

tval