您的最终方法有效(solution_add),它只是您使用的-而不是+。11g 的行为是由于一个错误修复(在 10g 及更低版本中,plsql 在使用 cast 时表现为“trunc”,而 SQL 表现为圆形。Oracle 认为 PLSQL 是正确的,并相应地更改了 11g。
即使用:
v1.base_val +
(extract(second from v1.base_val) - trunc(extract(second from v1.base_val))) / 86400 solution_add
虽然我可能会明确指定它以消除从时间戳到日期的隐式转换(避免狡猾的 cast())
to_date(to_char(v1.base_val, 'dd-mm-yyyy hh24:mi:ss'), 'dd-mm-yyyy hh24:mi:ss')+
(( extract(second from v1.base_val) - trunc(extract(second from v1.base_val))) / 86400)
例如:
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
PL/SQL Release 10.2.0.4.0 - Production
CORE 10.2.0.4.0 Production
TNS for Linux: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - Production
SQL> with v_data as
2 (select to_timestamp('2012-12-10 10:49:30.00000000',
3 'YYYY-MM-DD HH24:mi:ss.FF8') base_val,
4 to_timestamp('2012-12-10 10:49:30',
5 'YYYY-MM-DD HH24:mi:ss') expected
6 from dual
7 union all
8 select to_timestamp('2012-12-10 10:49:30.46300000',
9 'YYYY-MM-DD HH24:mi:ss.FF8') base_val,
10 to_timestamp('2012-12-10 10:49:30',
11 'YYYY-MM-DD HH24:mi:ss') expected
12 from dual
13 union all
14 select to_timestamp('2012-12-10 10:49:30.50000000',
15 'YYYY-MM-DD HH24:mi:ss.FF8') base_val,
16 to_timestamp('2012-12-10 10:49:31',
17 'YYYY-MM-DD HH24:mi:ss') expected
18 from dual
19 union all
20 select to_timestamp('2012-12-10 10:49:30.56300000',
21 'YYYY-MM-DD HH24:mi:ss.FF8') base_val,
22 to_timestamp('2012-12-10 10:49:31',
23 'YYYY-MM-DD HH24:mi:ss') expected
24 from dual
25 union all
26 select to_timestamp('2012-12-10 10:49:30.99999999',
27 'YYYY-MM-DD HH24:mi:ss.FF8') base_val,
28 to_timestamp('2012-12-10 10:49:31',
29 'YYYY-MM-DD HH24:mi:ss') expected
30 from dual)
31 select v1.base_val,
32 v1.expected,
33 v1.base_val +
34 (extract(second from v1.base_val) - trunc(extract(second from v1.base_val))) / 86400 solution_add,
35 to_date(to_char(v1.base_val, 'dd-mm-yyyy hh24:mi:ss'), 'dd-mm-yyyy hh24:mi:ss')+
36 (( extract(second from v1.base_val) - trunc(extract(second from v1.base_val))) / 86400) solution_add2
37 from v_data v1;
BASE_VAL EXPECTED SOLUTION_ADD SOLUTION_ADD2
------------------------- ------------------------- ------------------------- -------------------------
10-dec-12 10:49:30000 10-dec-12 10:49:30000 10-dec-2012 10:49:30 10-dec-2012 10:49:30
10-dec-12 10:49:30463 10-dec-12 10:49:30000 10-dec-2012 10:49:30 10-dec-2012 10:49:30
10-dec-12 10:49:30500 10-dec-12 10:49:31000 10-dec-2012 10:49:31 10-dec-2012 10:49:31
10-dec-12 10:49:30563 10-dec-12 10:49:31000 10-dec-2012 10:49:31 10-dec-2012 10:49:31
10-dec-12 10:49:30999 10-dec-12 10:49:31000 10-dec-2012 10:49:31 10-dec-2012 10:49:31
SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
PL/SQL Release 11.2.0.2.0 - Production
CORE 11.2.0.2.0 Production
TNS for Linux: Version 11.2.0.2.0 - Production
NLSRTL Version 11.2.0.2.0 - Production
SQL> with v_data as
2 (select to_timestamp('2012-12-10 10:49:30.00000000',
3 'YYYY-MM-DD HH24:mi:ss.FF8') base_val,
4 to_timestamp('2012-12-10 10:49:30',
5 'YYYY-MM-DD HH24:mi:ss') expected
6 from dual
7 union all
8 select to_timestamp('2012-12-10 10:49:30.46300000',
9 'YYYY-MM-DD HH24:mi:ss.FF8') base_val,
10 to_timestamp('2012-12-10 10:49:30',
11 'YYYY-MM-DD HH24:mi:ss') expected
12 from dual
13 union all
14 select to_timestamp('2012-12-10 10:49:30.50000000',
15 'YYYY-MM-DD HH24:mi:ss.FF8') base_val,
16 to_timestamp('2012-12-10 10:49:31',
17 'YYYY-MM-DD HH24:mi:ss') expected
18 from dual
19 union all
20 select to_timestamp('2012-12-10 10:49:30.56300000',
21 'YYYY-MM-DD HH24:mi:ss.FF8') base_val,
22 to_timestamp('2012-12-10 10:49:31',
23 'YYYY-MM-DD HH24:mi:ss') expected
24 from dual
25 union all
26 select to_timestamp('2012-12-10 10:49:30.99999999',
27 'YYYY-MM-DD HH24:mi:ss.FF8') base_val,
28 to_timestamp('2012-12-10 10:49:31',
29 'YYYY-MM-DD HH24:mi:ss') expected
30 from dual)
31 select v1.base_val,
32 v1.expected,
33 v1.base_val +
34 (extract(second from v1.base_val) - trunc(extract(second from v1.base_val))) / 86400 solution_add,
35 to_date(to_char(v1.base_val, 'dd-mm-yyyy hh24:mi:ss'), 'dd-mm-yyyy hh24:mi:ss')+
36 (( extract(second from v1.base_val) - trunc(extract(second from v1.base_val))) / 86400) solution_add2
37 from v_data v1;
BASE_VAL EXPECTED SOLUTION_ADD SOLUTION_ADD2
------------------------- ------------------------- ------------------------- -------------------------
10-dec-12 10:49:30000 10-dec-12 10:49:30000 10-dec-12 10:49:30 10-dec-12 10:49:30
10-dec-12 10:49:30463 10-dec-12 10:49:30000 10-dec-12 10:49:30 10-dec-12 10:49:30
10-dec-12 10:49:30500 10-dec-12 10:49:31000 10-dec-12 10:49:31 10-dec-12 10:49:31
10-dec-12 10:49:30563 10-dec-12 10:49:31000 10-dec-12 10:49:31 10-dec-12 10:49:31
10-dec-12 10:49:30999 10-dec-12 10:49:31000 10-dec-12 10:49:31 10-dec-12 10:49:31