获取纳秒级时间即9位精度时间获取问题?

【 使用环境 】 测试环境
【 OB or 其他组件 】
【 使用版本 】v4.2
【问题描述】 SYSTIMESTAMP、CURRENT_TIMESTAMP(9) 是否只支持微秒级精度6位?后3位补零了,但发现数据库是可以展示9位纳秒级数据的,请问怎么获取数据库纳秒级时间呢?

SELECT
TO_TIMESTAMP(‘2003-10-24 10:48:45.656123456’,‘YYYY-MM-DD HH24:MI:SS:FF9’) TO_TS9,
TO_CHAR(TO_TIMESTAMP(‘2003-10-24 10:48:45.656123456’,‘YYYY-MM-DD HH24:MI:SSXFF’),‘YYYY-MM-DD HH24:MI:SS:FF9’) TO_CS9,
TO_CHAR(SYSTIMESTAMP, ‘YYYY-MM-DD HH24:MI:SS.FF9’) AS TO_CS92,
CURRENT_TIMESTAMP(9) TIMESTAMP9
FROM DUAL;

*************************** 1. row ***************************
TO_TS9: 2003-10-24 10:48:45.656123456
TO_CS9: 2003-10-24 10:48:45:656123456
TO_CS92: 2025-03-14 10:24:38.757049000
TIMESTAMP9: 14-MAR-25 10.24.38.757054000 AM +08:00

曲线解决方法是获取SCN,通过转换可以实现。OBv4.0版本中SCN比之前版本多了3位长度,可以实现纳秒级时间,之前版本的SCN是微秒级的。这是我暂时找到的方法。请指导。

image
这边测试了下社区版目前的时间精度最高为微秒级别,无法直接获取纳秒级时间。如果您需要更高精度的时间值,可能需要结合外部工具或编程语言(如 Python、Java)来实现。

实测3.x企业版,最大精度微秒级

@论坛小助手

根据文档库中的信息,结合您的问题描述,以下是对您问题的解答:

已知信息

  1. 时间精度支持

    • OceanBase 数据库支持 DATETIMETIMESTAMP 类型的时间值,其中 TIMESTAMP 类型在 Oracle 模式下可以精确到纳秒(9位小数),而在 MySQL 模式下仅支持微秒(6位小数)。
    • 根据文档片段 1 的描述,TIMESTAMP 类型的时间格式为 YYYY-MM-DD HH:MM:SS[.fraction],其中 [.fraction] 的精度取决于 Scale 属性,最大值为 6(默认值也为 6)。但在 Oracle 模式下,时间戳可以支持更高的精度。
  2. SCN 转换

    • SCN 是 OceanBase 数据库内部的时间版本号,可以通过 SCN_TO_TIMESTAMP() 函数将其转换为时间戳。在某些版本中,SCN 的精度可能已经扩展到纳秒级。
    • 文档片段 2 提供了一个示例,展示了如何通过 SCN_TO_TIMESTAMP() 函数将 SCN 转换为时间戳,结果中包含纳秒级精度。
  3. 当前时间函数

    • 在 MySQL 模式下,NOW()CURRENT_TIMESTAMP 函数返回的时间精度为微秒(6位小数)。例如,CURRENT_TIMESTAMP(9) 的后三位可能会补零。
    • 在 Oracle 模式下,SYSTIMESTAMPCURRENT_TIMESTAMP 可以支持更高的精度(9位小数),但实际输出可能依赖于数据库的具体实现。
  4. 曲线解决方法

    • 您提到可以通过获取 SCN 并使用 SCN_TO_TIMESTAMP() 函数来实现纳秒级时间的获取。这是合理的,因为 SCN 在某些版本中确实支持更高的精度。

解答

1. 如何获取纳秒级时间?

在 OceanBase 数据库的 Oracle 模式下,可以通过以下方式获取纳秒级时间:

  • 直接使用时间函数
    如果数据库支持纳秒级精度(如 v4.2 版本),可以直接使用 SYSTIMESTAMPCURRENT_TIMESTAMP(9) 函数。例如:

    SELECT SYSTIMESTAMP AS systimestamp,
           CURRENT_TIMESTAMP(9) AS current_timestamp
    FROM DUAL;
    

    如果返回的结果中后三位为零,可能是由于数据库配置或显示限制导致的。

  • 通过 SCN 转换
    如果直接使用时间函数无法获取纳秒级精度,可以通过 SCN 转换实现。例如:

    SELECT MAX_SCN, SCN_TO_TIMESTAMP(MAX_SCN) AS timestamp_with_nanoseconds
    FROM gv$ob_log_stat;
    

    这种方法利用了 SCN 的高精度特性,能够返回纳秒级时间。


2. 为什么 CURRENT_TIMESTAMP(9) 后三位补零?

根据文档片段 1 和片段 8 的描述,在 MySQL 模式下,TIMESTAMP 类型的时间精度默认为微秒(6位小数)。即使指定 CURRENT_TIMESTAMP(9),后三位也可能被补零,因为 MySQL 模式下的时间类型不支持更高的精度。

在 Oracle 模式下,CURRENT_TIMESTAMP(9) 应该能够返回完整的纳秒级时间。如果仍然出现补零现象,可能需要检查以下几点:

  • 数据库是否运行在 Oracle 模式下。
  • 数据库版本是否支持完整的纳秒级精度。

3. 曲线解决方法的合理性

您提到的通过 SCN 转换获取纳秒级时间的方法是合理的。SCN 在某些版本中已经扩展到纳秒级精度,因此可以通过以下步骤实现:

  1. 获取当前的最大 SCN 值。
  2. 使用 SCN_TO_TIMESTAMP() 函数将 SCN 转换为时间戳。

示例代码如下:

SELECT MAX_SCN, SCN_TO_TIMESTAMP(MAX_SCN) AS timestamp_with_nanoseconds
FROM gv$ob_log_stat;

总结

  1. 在 Oracle 模式下,SYSTIMESTAMPCURRENT_TIMESTAMP(9) 应该能够返回完整的纳秒级时间。如果后三位补零,可能是由于数据库配置或显示限制导致的。
  2. 如果直接使用时间函数无法满足需求,可以通过 SCN 转换实现纳秒级时间的获取。
  3. 确保数据库运行在 Oracle 模式下,并检查版本是否支持完整的纳秒级精度。

如果您仍有疑问,建议联系 OceanBase 的技术支持团队以获取进一步的帮助。

检索到的文档如下:

  1. 日期时间类型概述
  2. SCN_TO_TIMESTAMP
  3. 恢复架构
  4. 闪回查询
  5. 设置日志恢复终点
  6. OceanBase 术语
  7. VERSION
  8. 查询中使用时间函数
  9. TIMESTAMP_TO_SCN
  10. OB_VERSION