HHeLiBeXの日記 正道編

日々の記憶の記録とメモ‥

トランザクション内でユニークなTIMESTAMP値を取得する試み

1つのトランザクションの中で、例えば以下のようなクエリ

INSERT INTO TBL(ID, TS) VALUES(1, CURRENT_TIMESTAMP)

INSERT INTO TBL(ID, TS) VALUES(2, CURRENT_TIMESTAMP)

を発行すると、2つの行のTIMESTAMP値(TS列)は同一になるとは限らない。
しかし時にはトランザクション内でユニークなTIMESTAMP値がほしい場合もある(かも)ということで、その方法について考えてみる。

SQLの規格(SQL2003)に従うと、まず、事前に以下の関数

CREATE FUNCTION SQL_UNIQUE_TIMESTAMP()
   RETURNS TIMESTAMP
   LANGUAGE SQL
   NOT DETERMINISTIC
   MODIFIES SQL DATA
   BEGIN
      DECLARE ts TIMESTAMP;
      DECLARE stmt CLOB;

      SET stmt = 'SET ? = (SELECT UNIQ_TS FROM SQL_TBL_UNIQUE_TIMESTAMP)';
      PREPARE pstmt FROM stmt;
      EXECUTE pstmt INTO ts;
      RETURN ts;
   END

を定義しておく。
で、セッション開始時に

CREATE GLOBAL TEMPORARY TABLE SQL_TBL_UNIQUE_TIMESTAMP (UNIQ_TS TIMESTAMP)
   ON COMMIT DELETE ROWS

INSERT INTO SQL_TBL_UNIQUE_TIMESTAMP(UNIQ_TS) VALUES(CURRENT_TIMESTAMP)

をやっておき、

INSERT INTO TBL(ID, TS) VALUES(1, SQL_UNIQUE_TIMESTAMP())

INSERT INTO TBL(ID, TS) VALUES(2, SQL_UNIQUE_TIMESTAMP())

のように定義した関数を呼び出せば、セッション中でユニークなTIMESTAMP値が取得できる。
問題はGLOBAL TEMPORARY TABLEの作成をやらなきゃいけない点だが、関数の中で動的SQLを実行する形にしてしまえばよいだろう…