Значение байтов дампа (systimestamp) Oracle
Я пытаюсь понять, что означают байты из метки времени, установленной в моей БД. Как они вычисляются для создания более читаемой даты?
Я использую запрос ниже, чтобы получить данные, которые мне нужны:
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 |
+-------------------------------------+-----------------------------------------------------------------+------------------+
Я нашел несколько ресурсов онлайн, объясняющих, что означают байты ( здесь), но правила не совпадают в моем сценарии.
Например: 223 не век + 100 и т. Д.
Я пытаюсь это сделать из-за проблемы, с которой я сталкиваюсь при сравнении значений в timestamp(3)
колонка с systimestamp
и я пытаюсь написать сценарий, чтобы проверить, соответствует ли моя проблема / решение описанному здесь.
Любая помощь приветствуется.
1 ответ
Существуют различные внешне похожие, но внутренне разные типы данных datetime. 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
Из них только в столбце меток времени используется внутренний формат в статье, к которой вы привязаны, с использованием нотации "100" за год.
Для остальных первый байт - это модификатор base-256, а второй байт - это base 256; так что вы бы интерпретировали это как
223 + (7 * 256) = 2015
Подробнее о внутреннем хранилище вы можете прочитать в документе "Моя поддержка Oracle" 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 дробные секунды такие же, но с обращенными байтами.