2

2 つの時点の間にデータセットで発生したすべての変更のリストを本質的に取得しようとしている状況があります。これは、Oracle の VERSIONS BETWEEN キーワードの非常に良いケースのように思えますが、他のテーブルに効果的に結合して、必要な結果を得る方法がわかりません。

次のテーブルがあるとします。

CREATE TABLE emp (
    emp_id        NUMBER(5) PRIMARY KEY,
    employee_name VARCHAR2(20)
    dept_id       NUMBER(3) NOT NULL
                     CONSTRAINT admin_dept_fkey REFERENCES dept
                     (dept_id))
);

CREATE TABLE dept(
    dept_id    NUMBER(5),
    department VARCHAR2(20)
);

従業員レコードが変更された場合、従業員レコードが変更されたときの部署名を取得できる必要があります。これは、従業員がまだ同じ部署に属していても、ある時点で部署名が変更されている可能性があるためです。

例: EMP.VERSIONS_STARTSCN EMP_ID EMPLOYEE_NAME DEPT_ID DEPARTMENT 1 1 マイケル 1 サービス 0 1 マイケル 1 営業

データベースが非正規化されていて、テーブル自体に部門名を格納していた場合、これは非常に簡単です。ただし、ルックアップ テーブルを使用すると、直感的ではなくなるようです。

私が試したこと:

SELECT *
FROM emp VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE e
JOIN dept d ON d.dept_id = e.dept_id;

これにより、現在の部門が表示されますが、従業員レコードが変更された時点での部門はわかりません。

SELECT *
FROM emp VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE e
JOIN dept VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE d
ON d.dept_id = e.dept_id;

従業員レコードが変更された時点で存在していた部門のみが実際に必要な場合、各部門が変更された従業員用に複数の行が返されるため、これも良くありません。

内部選択もいくつか試しましたが、Oracle では、内部クエリで VERSIONS_ENDSCN または VERSIONS_STARTTIME を使用することは許可されていないようです。私が試したバリエーションは次のとおりです。

SELECT 
    versions_startscn,
    e.employee_name,
    (SELECT department FROM dept AS OF SCN versions_startscn d WHERE d.dept_id = e.dept_id)
FROM emp VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE e

SELECT 
    e.employee_name
    (SELECT department FROM dept AS OF SCN versions_startscn d WHERE d.dept_id = e.dept_id)
FROM(
    SELECT 
        versions_startscn,
        e.employee_name,
    FROM emp VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE e
    )

これらのクエリは両方とも、VERSIONS_STARTSCN が宣言されていないというエラーをスローします。

これはかなり一般的な使用例だと思いますが、結合で VERSIONS BETWEEN を使用する例を見つけることができませんでした。私はこれを行う方法を思いつきました.SCN MINVALUE AND MAXVALUEの間の従業員の変更でカーソルを開き、SCNを変数に選択し、empテーブルとDEPT AS OF SCNからネストされたテーブルタイプに変更を選択します、しかし、これはかなり単純に見えることを行うには多くの作業のように思えます. 誰かに何かアイデアがあれば、それは大歓迎です。

現在、v11.2.0.4 を使用しています。

4

1 に答える 1