Oracle の TIMESTAMP[データベース]
(2026-07-14 21:58:21) by shinoda


< ページ移動: 1 2 >

Oracle DBを使ったシステムで、時間(ミリ秒まで)をキーにしているテーブルで「キーの重複エラー」が出てプログラムが落ちるという障害が出たので、ちょっと調べてみた。

Oracle でミリ秒まで管理する場合のデータ型は DATE ではなく TIMESTAMP となる。精度はナノ秒(秒数以下(小数秒) 9桁)まで。

テストで、TIMESTAMP型の項目をキーとしたテーブルを作成する。

CREATE TABLE t_test1 (
    id INTEGER,
    udate TIMESTAMP,
    PRIMARY KEY (id, udate)
)

id と udate の組み合わせでユニークでないといけないテーブルだ。

なので、

INSERT INTO t_test1 (id, udate) VALUES(1, '2026-07-07 11:00:00.111111');

を 2回実行しようとすると、

ORA-00001: 一意制約(TESTER.SYS_C008227)に反しています

のエラーとなる。

INSERT INTO t_test1 (id, udate) VALUES(1, '2026-07-07 11:00:00.111222');

であれば、ミリ秒以下(小数秒 4〜6桁目のマイクロ秒)の値が違うので登録はできる。

ミリ秒(秒数以下 3桁のみ)までの指定での INSERTでは、マイクロ秒に 000 を補完するので、

INSERT INTO t_test1 (id, udate) VALUES(1, '2026-07-07 11:00:00.111');

これも(内部的には 11:00:00.111000 という時間になり)通る。

SELECT 時に書式を指定しなければ、TIMESTAMP の項目はミリ秒までしか表示しない。

SELECT * FROM t_test1 WHERE udate >= '2026-07-07 11:00:00.111';

<画像:20260707_timestamp1.jpg>

例えばマイクロ秒まで表示したければ、小数行を 6桁表示するようにフォーマットを指定する。

SELECT id, TO_CHAR(udate, 'YYYY-MM-DD HH24:MI:SS.FF6') FROM t_test1
WHERE udate >= '2026-07-07 11:00:00.111';

<画像:20260707_timestamp2.jpg>

ちなみに、CREATE TABLE 時に TIMESTAMP とだけ指定すると、マイクロ秒(小数秒 6桁)までの管理となる。
そのため、

INSERT INTO t_test1 (id, udate) VALUES(1, '2026-07-07 11:00:00.111222333');

は、実際には 111222 までしか見ないので(ナノ秒部の 333 は無視する)、

ORA-00001: 一意制約(TESTER.SYS_C008227)に反しています

< ページ移動: 1 2 >


コメント投稿
次の記事へ >
< 前の記事へ
TOPへ戻る

Powered by
MT4i 3.0.8