Oracle 的转储(系统时间戳)字节的含义
Meaning of Oracle's dump(systimestamp) bytes
我正在尝试了解我的数据库上设置的时间戳中的字节的含义。如何计算它们以生成更具可读性的日期?
我正在使用以下查询来获取我需要的数据:
SELECT systimestamp
,DUMP (systimestamp)
,sessiontimezone
FROM dual;
我上面查询的输出是:
+-------------------------------------+-----------------------------------------------------------------+------------------+
| systimestamp | dump(systimestamp) | sessiontimezone |
+-------------------------------------+-----------------------------------------------------------------+------------------+
| 31-JUL-15 08.55.06.157047000 +00:00 | Typ=188 Len=20: 223,7,7,31,8,55,6,0,216,88,92,9,0,0,5,0,0,0,0,0 | Europe/Bucharest |
+-------------------------------------+-----------------------------------------------------------------+------------------+
我在网上找到了一些解释字节含义的资源 (here),但规则与我的场景不匹配。
例如:223不是世纪+100等等
我尝试这样做的原因是我在将 timestamp(3)
列中的值与 systimestamp
中的值进行比较时遇到了一个问题,我正在尝试编写一个脚本验证我的 issue/solution 是否相同 as explained here.
感谢任何帮助。
有多种表面相似但内部不同的日期时间数据类型。 systimestamp
是类型 188(并且有时区信息);时间戳字面量是没有时区信息的 187 类型和有时区信息的 188 类型;一个普通的时间戳列是类型 180:
select dump(systimestamp) from dual;
DUMP(SYSTIMESTAMP)
--------------------------------------------------------------------------------
Typ=188 Len=20: 223,7,7,31,9,50,28,11,128,203,79,35,1,0,5,0,0,0,0,0
select dump(timestamp '2015-07-31 08:55:06.157047 +00:00') from dual;
DUMP(TIMESTAMP'2015-07-3108:55:06.157047+00:00')
---------------------------------------------------------------
Typ=188 Len=20: 223,7,7,31,8,55,6,0,216,88,92,9,0,0,5,0,0,0,0,0
select dump(timestamp '2015-07-31 08:55:06.157047') from dual;
DUMP(TIMESTAMP'2015-07-3108:55:06.157047')
---------------------------------------------------------------
Typ=187 Len=20: 223,7,7,31,8,55,6,0,216,88,92,9,0,0,3,0,0,0,0,0
create table t (ts timestamp);
insert into t (ts) values (timestamp '2015-07-31 08:55:06.157047');
select dump(ts) from t;
DUMP(TS)
--------------------------------------------------------------------------------
Typ=180 Len=11: 120,115,7,31,9,56,7,9,92,88,216
其中,只有一个时间戳列使用您链接到的文章中的内部格式,对年份使用 excess-100 表示法。
其他的,第一个字节是base-256修饰符,第二个字节是base-256年份;所以你会把它解释为
223 + (7 * 256) = 2015
您可以在 My Oracle Support 文档 69028.1 中阅读有关内部存储的更多信息。那,以及评论中链接的早期答案,指的是两种日期类型,但时间戳被视为相同的秒数,其余的一些可以推断为类型 187/188 - 无论如何都是小数秒部分:
Byte 1 - Base 256 year modifier: 223
2 - Base 256 year: 7 (256 * 7 = 1792 + 223 = 2015)
3 - Month: 7
4 - Day: 31
5 - Hours: 8
6 - Minutes: 55
7 - Seconds: 6
8 - Unused?
9 - Base 256 nanoseconds: 216
10 - Base 256 ns modifier 1: 256 * 88 = 22528
11 - Base 256 ns modifier 2: 256 * 256 * 92 = 6029312
12 - Base 256 ns modifier 3: 256 * 256 * 256 * 9 = 150994944
=> actual nanoseconds = 216 + 22528 + 6029312 + 150994944
=> 157047000
13-20 - Time zone data?
对于类型 120,小数秒是相同的,但字节颠倒了。
我正在尝试了解我的数据库上设置的时间戳中的字节的含义。如何计算它们以生成更具可读性的日期?
我正在使用以下查询来获取我需要的数据:
SELECT systimestamp
,DUMP (systimestamp)
,sessiontimezone
FROM dual;
我上面查询的输出是:
+-------------------------------------+-----------------------------------------------------------------+------------------+
| systimestamp | dump(systimestamp) | sessiontimezone |
+-------------------------------------+-----------------------------------------------------------------+------------------+
| 31-JUL-15 08.55.06.157047000 +00:00 | Typ=188 Len=20: 223,7,7,31,8,55,6,0,216,88,92,9,0,0,5,0,0,0,0,0 | Europe/Bucharest |
+-------------------------------------+-----------------------------------------------------------------+------------------+
我在网上找到了一些解释字节含义的资源 (here),但规则与我的场景不匹配。
例如:223不是世纪+100等等
我尝试这样做的原因是我在将 timestamp(3)
列中的值与 systimestamp
中的值进行比较时遇到了一个问题,我正在尝试编写一个脚本验证我的 issue/solution 是否相同 as explained here.
感谢任何帮助。
有多种表面相似但内部不同的日期时间数据类型。 systimestamp
是类型 188(并且有时区信息);时间戳字面量是没有时区信息的 187 类型和有时区信息的 188 类型;一个普通的时间戳列是类型 180:
select dump(systimestamp) from dual;
DUMP(SYSTIMESTAMP)
--------------------------------------------------------------------------------
Typ=188 Len=20: 223,7,7,31,9,50,28,11,128,203,79,35,1,0,5,0,0,0,0,0
select dump(timestamp '2015-07-31 08:55:06.157047 +00:00') from dual;
DUMP(TIMESTAMP'2015-07-3108:55:06.157047+00:00')
---------------------------------------------------------------
Typ=188 Len=20: 223,7,7,31,8,55,6,0,216,88,92,9,0,0,5,0,0,0,0,0
select dump(timestamp '2015-07-31 08:55:06.157047') from dual;
DUMP(TIMESTAMP'2015-07-3108:55:06.157047')
---------------------------------------------------------------
Typ=187 Len=20: 223,7,7,31,8,55,6,0,216,88,92,9,0,0,3,0,0,0,0,0
create table t (ts timestamp);
insert into t (ts) values (timestamp '2015-07-31 08:55:06.157047');
select dump(ts) from t;
DUMP(TS)
--------------------------------------------------------------------------------
Typ=180 Len=11: 120,115,7,31,9,56,7,9,92,88,216
其中,只有一个时间戳列使用您链接到的文章中的内部格式,对年份使用 excess-100 表示法。
其他的,第一个字节是base-256修饰符,第二个字节是base-256年份;所以你会把它解释为
223 + (7 * 256) = 2015
您可以在 My Oracle Support 文档 69028.1 中阅读有关内部存储的更多信息。那,以及评论中链接的早期答案,指的是两种日期类型,但时间戳被视为相同的秒数,其余的一些可以推断为类型 187/188 - 无论如何都是小数秒部分:
Byte 1 - Base 256 year modifier: 223
2 - Base 256 year: 7 (256 * 7 = 1792 + 223 = 2015)
3 - Month: 7
4 - Day: 31
5 - Hours: 8
6 - Minutes: 55
7 - Seconds: 6
8 - Unused?
9 - Base 256 nanoseconds: 216
10 - Base 256 ns modifier 1: 256 * 88 = 22528
11 - Base 256 ns modifier 2: 256 * 256 * 92 = 6029312
12 - Base 256 ns modifier 3: 256 * 256 * 256 * 9 = 150994944
=> actual nanoseconds = 216 + 22528 + 6029312 + 150994944
=> 157047000
13-20 - Time zone data?
对于类型 120,小数秒是相同的,但字节颠倒了。