所以我正在开发一个项目,将数据从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)
答案 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)
除非在prepare()和execute()
之间使用setinputsizes()方法,否则将截断作为绑定变量传递的日期/时间值的小数秒
文章的示例显示,为了节省毫秒,您需要指定How's it going? Yo!
参数的输入大小:
tval