最終的なアプローチは (solution_add) + の代わりに - を使用しただけで機能します。11g の動作はバグ修正によるものです (10g 以下では、キャストが使用されたときに plsql は「切り捨て」として動作していましたが、SQL はラウンドとして動作していました。Oracle は PLSQL が正しいと判断し、それに応じて 11g を変更しました。
つまり、次を使用します。
v1.base_val +
(extract(second from v1.base_val) - trunc(extract(second from v1.base_val))) / 86400 solution_add
おそらく明示的に指定して、タイムスタンプから日付への暗黙的な変換を取り除くでしょう(危険なキャスト()を回避します)
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