DB2にてOracleのROWIDと同様な機能を使用する方法です。この記事ではDB2 for LUWのVer10.5で動作確認を行っています。(動作保証をしているわけではないのであしからず。)

OracleのROWIDとは

まず、OracleのROWIDって何?って方のために簡単に説明します。
ROWIDとは、Oracle内でレコードのアドレスを示すポインタでOracleの内部的な管理情報になります。PRIMARY KEYなどのユニークキーが無くても行を特定できるキーとなっています。 Oracleの内部管理情報なのでWHERE句でROWIDを使用するとテーブルのレコードに高速でアクセスできます。単一行でのアクセス(UNIQUE SCAN)では最速です。

このROWIDはレコードのUPDATEなどで変更されることはありませんがエクスポート、インポート、表をまるごと移動させたりすると変更されてしまいます。 なのでROWIDの使用は、SELECTでデータを取得後に再度SELECTする場合やUPDATE、DELETEする場合になります。

DB2でいうROWIDについて

OracleでいうROWIDの参照はDB2でいうとRID_BIT()という関数で取得できる値と等価ということです。例えば、OracleでいうEMPLOYEE.ROWID は、DB2のRID_BIT(EMPLOYEE) と等価です。
-- Oracle
SELECT  EMPLOYEE.ROWID AS ROWID FROM EMPLOYEE
-- DB2
SELECT RID_BIT(EMPLOYEE) AS RID FROM EMPLOYEE
RID_BIT(テーブル名)にてテーブルのIDとが取得できます。

どんなことに使うか

例えば、RIDを使ってSELECT INSERTを行えばバックアップテーブルに移動してDELETEで削除がテーブルごとの主キー(PRIMARY KEY)をいちいち指定しなくても行うことができます。複数のテーブルを作成日等の共通項目でバックアップするようなスクリプトでループ処理させるときにとても簡単に実装することができるようになります。以下、サンプルコードになります。

-- SYSTEM_LOGテーブルからBK_EMPLOYEEテーブルへコピー
INSERT INTO BK_SYSTEM_LOG
SELECT * 
FROM SYSTEM_LOG 
WHERE RID_BIT(SYSTEM_LOG) IN ( 
	SELECT RID_BIT(SYSTEM_LOG) FROM SYSTEM_LOG ORDER BY RID_BIT(SYSTEM_LOG) 
)

-- コピー済みのデータの削除
DELETE FROM SYSTEM_LOG
WHERE RID_BIT(SYSTEM_LOG) IN ( 
	SELECT RID_BIT(SYSTEM_LOG) FROM SYSTEM_LOG ORDER BY RID_BIT(SYSTEM_LOG) 
)

簡単な解説としてまず、SYSTEM_LOGテーブルからBK_EMPLOYEEテーブルへINSERT SELECTでコピーします。(SYSTEM_LOGテーブルとBK_EMPLOYEEテーブルのテーブル名以外の定義は同じとします。)このときにWHERE句にRID_BIT以外の条件(作成日等)を入れれば対象データを絞り込むことができます。

次にコピー済みのデータを元テーブルから削除します。この時のポイントはINSERT SELECTした時のWHERE句と条件を揃えること(当たり前ですが)です。この2つのSQLを使用すればバックアップテーブルへのデータの移動ができます。テーブルのデータ量が肥大化して検索がとても遅くなってしまったなどで、検索することはないけど監査等の関係で残しておかなければならないデータがあるような場合に使えるものとなっています。

また、DB2ではFETCH FIRST ◯◯ ROWS ONLYをつかって繰り返し処理してコミットを細分化(◯◯件ずつコミット)すれば大量データのトランザクションログの対策もできます。ただしソート順をORDER BYでRID_BITを指定しないとコピーと削除の整合性が保たれるとは言えないので気をつけてください。

※上記コードですが、数千件程度であれば問題ないのですがテーブルが膨大になるととても遅いです。RID_BITでの単一行でのアクセス(UNIQUE SCAN)は確かに最速なのですがIN句などを使用した複数行問い合わせではその限りではないのです。