【问题标题】:Force Oracle's sysdate to return different value for multiple statements强制 Oracle 的 sysdate 为多个语句返回不同的值
【发布时间】:2019-05-23 22:53:47
【问题描述】:

我想强制 Oracle sysdate 函数为单独的语句返回不同的值,就像在 Postgres 中一样。我已经对文档、网络和 SO 本身进行了一些挖掘,但找不到解决此问题的答案。

这个文档似乎很差:see for yourself

我将 Oracle 11g 与 SQL Developer 18.3 一起使用

请阅读下面的 MVCE。

执行后:

create table t(a timestamp);
insert into t values (sysdate);
insert into t values (sysdate);
insert into t values (sysdate);
select * from t;

我明白了:

A                          
---------------------------
18/12/25 04:25:59,000000000
18/12/25 04:25:59,000000000
18/12/25 04:25:59,000000000

我想得到(手动更改):

A                          
---------------------------
18/12/25 04:25:59,1234
18/12/25 04:25:59,7281
18/12/25 04:26:00,1928

真正的问题出现在对过程的不同CALL 语句中,但上面的示例似乎为我复制了这个问题。


更新

我发现有用的一件事是在语句之​​间放置暂停,但这真的不是我想要的:

set pause on;
create table t(a timestamp);
insert into t values (sysdate);
pause
insert into t values (sysdate);
pause
insert into t values (sysdate);

【问题讨论】:

  • 即使你能做到这一点,你确定它会完全解决你的问题吗?我的意思是,假设两个插入恰好发生在足够近的地方,以至于 SYSDATE 值仍然看起来相同?
  • @TimBiegeleisen 这不是多用户环境,目的只是为了我自己的培训。我正在执行不同的语句,但我没有观察到调用之间的任何差异,这对于我从其他 DBMS 的经验中学到的东西来说很奇怪。

标签: oracle11g oracle-sqldeveloper sysdate


【解决方案1】:

如文档中所述,the sysdate function 返回一个 date,其精度仅为秒 - 它不支持小数秒。因此,同一秒内的多次调用总是会得到相同的值,你不能强迫它做任何其他事情。

您将该日期值放入 timestamp 列中,这会导致从一种数据类型到另一种数据类型的隐式转换,但该转换无法设置/创建新的小数秒值 - 它保留隐式从日期开始的小数秒,当然总是零。

除了sysdate,Oracle 还有a systimestamp function,它返回一个timestamp with time zone 值——它确实有小数秒。精度受您运行的平台的限制。如果您使用它来填充您的普通时间戳列,那么仍然会发生隐式转换,但您实际上只是丢弃了时区信息。

Oracle 还支持 current_datecurrent_timestamp,它们非常相似 - 除了它们返回当前会话时区的日期/时间,而不是像 sys* 版本那样返回服务器时区。

【讨论】:

  • 谢谢亚历克斯。在哪里处理转换似乎是一个选择问题。很好的补充:)
  • 感谢您的解释,但是如果我有两个 sysdate 在一个大的 select 查询中,例如持续 20 秒。 Oracle 是一次性解析所有sysdates 还是所有systimestamps?
  • 看来这些函数都解决了一次! SELECT 'sysdate' AS FUNCTION, sysdate AS RETURN FROM DUAL UNION ALL SELECT 'systimestamp', systimestamp FROM DUAL UNION ALL SELECT 'systimestamp', systimestamp FROM DUAL UNION ALL SELECT 'current_timestamp', current_timestamp FROM DUAL UNION ALL SELECT 'systimestamp', systimestamp FROM DUAL UNION ALL SELECT 'current_timestamp', current_timestamp FROM DUAL UNION ALL SELECT 'sysdate', sysdate FROM DUAL UNION ALL SELECT 'systimestamp', systimestamp FROM DUAL 查看第 3、4、5、6 和 8 行的 RETURN 列的值。
【解决方案2】:

我发现current_timestamp 可以完成这项工作:

drop table t;
create table t(a timestamp);
insert into t values (current_timestamp);
insert into t values (current_timestamp);
insert into t values (current_timestamp);
select * from t;

输出:

A                          
---------------------------
18/12/25 04:48:54,134000000
18/12/25 04:48:54,142000000
18/12/25 04:48:54,149000000

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2019-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-14
相关资源
最近更新 更多