3 Workspace Managerの有効期間のサポート
この章では、バージョン対応表を使用した有効期間(有効日付)のサポートについて説明します。
この章の内容は次のとおりです。
トピック:
- 有効期間のサポート: 概要と例
 一部のアプリケーションでは、データにその妥当性を示す時間範囲を関連付けて格納する必要があります。つまり、各レコードは、そのレコードに関連付けられている時間範囲内でのみ有効です。
- WM_PERIODデータ型WM_PERIODデータ型は、セッションまたは作業領域およびバージョン対応表の行について有効期間の範囲を指定するために使用されます。
- 有効期間の定数
 次の表に、WM_PERIOD指定のvalidFromおよびvalidTillタイムスタンプに使用できる定数を示します。
- 有効期間のサポート用のAPI機能
 次の表に、有効期間のサポート専用、または有効期間のサポートに関連するパラメータを持つDBMS_WMサブプログラムを示します。
- 有効期間サポートの演算子
 Workspace Managerには、2つの期間パラメータを受け入れる関係チェック演算子と関係集合演算子が用意されており、問合せで有効期間フィルタを適用するために使用できます。
- 有効期間サポートを使用した問合せおよびDML操作
 この項では、有効期間サポートに関連する問合せおよびデータ操作言語(挿入、更新および削除)操作の動作と考慮事項について説明します。
- 有効期間サポートのための制約管理
 この項では、参照整合性制約と一意制約に影響する有効期間サポートに関連した考慮事項について説明します。
- 有効期間サポートを使用したロック
 有効期間サポートを伴うバージョン対応表の1行がロックされる場合、その行は自動的に有効期間全体を通じてロックされます。指定した期間だけ行をロックする方法はありません。
- 有効期間サポートの影響を受ける静的データ・ディクショナリ・ビュー
 この項では、Workspace Managerの静的データ・ディクショナリ・ビューに対する有効期間サポートの影響について説明します。
- 既存の表に対する有効期間サポートの追加
 既存のバージョン対応表に有効期間サポートを追加できます。
- 有効期間サポートがある表の作業領域のマージおよびリフレッシュ
 有効期間サポートがある表をマージまたはリフレッシュする場合、主キー値が同じ行の間に交差部がある明確なケースを考慮することで、結果の行を特定できます。
3.1 有効期間のサポート: 概要と例
一部のアプリケーションでは、データにその妥当性を示す時間範囲を関連付けて格納する必要があります。つまり、各レコードは、そのレコードに関連付けられている時間範囲内でのみ有効です。
表をバージョン対応表にする場合は、有効期間サポートを有効にできます。(既存のバージョン対応表に有効期間サポートを追加することもできます。詳細は、既存の表に対する有効期間サポートの追加を参照してください。)有効期間サポートを有効にすると、各行には、行に関連付けられた有効期間を保持する列が追加されます。セッションに対して有効期間の範囲を指定することができます。Workspace Managerでは、有効期間の範囲が問合せや挿入、更新および削除操作で適切に反映され適応されます。有効期間の範囲には、過去または将来を指定できます。過去、現在、将来を含めることもできます。
例3-1に、有効期間のサポートの簡単な例を示します。この例では、次の操作を実行しています。
- 
                        従業員とその給与の表を作成します。 
- 
                        有効期間のサポートを指定して表をバージョン対応にします。これにより、表に WM_VALID列が自動的に追加されます。
- 
                        この表に行を挿入します。行ごとに、従業員名、給与および有効期間のサポートを指定します。 
- 
                        セッションの有効期間の範囲を設定します。 
- 
                        従業員1人の新規の給与と有効期間を指定して1行を更新します。 
- 
                        表のバージョニングを無効化します。 
例3-1:
- 
                        この章の他の項で説明する有効期間のサポートの概念および手法を参照してください。 
- 
                        Workspace Managerの概要で説明したWorkspace Managerの概念と手法をよく理解していると仮定します。 
- 
                        作業領域またはセーブポイントを作成しないでください。(これらは、Workspace Managerを使用した簡単な例の例: マーケティング予算のオプションおよび例: 倉庫拡張のオプションで示します。) 
例3-1 有効期間のサポート
-- Create a very simple employees table (deliberately oversimplified
-- for purposes of illustration).
CREATE TABLE employees (
  name VARCHAR2(16) PRIMARY KEY,
  salary NUMBER 
);
-- Version-enable the table. Specify TRUE for valid time support.
EXECUTE DBMS_WM.EnableVersioning ('employees', 'VIEW_WO_OVERWRITE', FALSE, TRUE);
INSERT INTO employees VALUES(
  'Adams',
  30000,
  WMSYS.WM_PERIOD(TO_DATE('01-01-1990', 'MM-DD-YYYY'), 
                  TO_DATE('01-01-2005', 'MM-DD-YYYY'))
);
INSERT INTO employees VALUES(
  'Baxter',
  40000,
  WMSYS.WM_PERIOD(TO_DATE('01-01-2000', 'MM-DD-YYYY'), DBMS_WM.UNTIL_CHANGED)
);
INSERT INTO employees VALUES(
  'Coleman',
  50000,
  WMSYS.WM_PERIOD(TO_DATE('01-01-2003', 'MM-DD-YYYY'), 
                  TO_DATE('12-31-9999', 'MM-DD-YYYY'))
);
COMMIT;
-- Set valid time period to virtually all time.
EXECUTE DBMS_WM.SetValidTime(TO_DATE('01-01-1900', 'MM-DD-YYYY'),
  TO_DATE('01-01-9999', 'MM-DD-YYYY'));
-- Update the salary for an existing employee. Perform "sequenced" update, so
-- that existing time-related information is preserved. This results in two rows
-- for Baxter.
-- First, set valid time to the intended range for Baxter's raise.
EXECUTE DBMS_WM.SetValidTime(TO_DATE('01-01-2003', 'MM-DD-YYYY'), DBMS_WM.UNTIL_CHANGED);
-- Give Baxter a raise, effective 01-Jan-2003 until changed.
UPDATE employees SET salary = 45000 WHERE name = 'Baxter';
-- Disable versioning. By default (keepWMValid parameter value of TRUE),
-- the WM_VALID column is kept, with all its data. 
COMMIT;
EXECUTE DBMS_WM.DisableVersioning ('employees');3.2 WM_PERIODデータ型
WM_PERIODデータ型は、セッションまたは作業領域およびバージョン対応表の行について有効期間の範囲を指定するために使用されます。
                  
WM_PERIOD型の定義は、次のとおりです。
                  
CREATE TYPE WM_PERIOD AS OBJECT ( validFrom TIMESTAMP WITH TIME ZONE, validTill TIMESTAMP WITH TIME ZONE, MAP member function wm_period_map return varchar2);
validFromは範囲の開始日で、validTill期間は指定した日付の前日までとなります。つまり、有効日付の範囲はvalidFromの日付からvalidTillの日付の前日までとなります。
                  
wm_period_mapメンバー・ファンクションにより、WM_PERIOD型の列で順序付け(ソート)およびDISTINCTの使用が有効になります。
                  
例3-2 セッションの有効期間を特定の日付に設定する例
例3-2では、セッションの有効期間の範囲を2003年1月1日に設定しています。
EXECUTE DBMS_WM.SetValidTime(TO_DATE('01-01-2003', 'MM-DD-YYYY'), TO_DATE('01-02-2003', 'MM-DD-YYYY'));
例3-3では、2003年1月1日から変更時まで有効な1行を挿入しています。
例3-3 期間の範囲に有効な1行を挿入する例
INSERT INTO employees VALUES(
  'Baxter',
  40000,
  WMSYS.WM_PERIOD(TO_DATE('01-01-2003', 'MM-DD-YYYY'), DBMS_WM.UNTIL_CHANGED)
);
有効期間サポートを伴う表に作成されたビューに、WM_VALID型の1列のかわりにTIMEZONE WITH TIMESTAMP型の2列を使用して有効期間範囲を格納する場合、Workspace Managerシステム・パラメータUSE_SCALAR_TYPES_FOR_VALIDTIMEをONに設定します。Workspace Managerのシステム・パラメータを参照してください。 
                     
3.3 有効期間の定数
次の表に、WM_PERIOD指定のvalidFromおよびvalidTillタイムスタンプに使用できる定数を示します。
                  
(Workspace Managerではこれらは定数として使用されますが、関数として実装されます。)
表3-1 有効期間のサポートの定数
| 定数 | 説明 | 
|---|---|
| DBMS_WM.MIN_TIME | Workspace Managerでサポートされる最小(最も古い)タイムスタンプ値。現在は、-4712年(紀元前4712年)1月1日が開始時です。 | 
| DBMS_WM.MAX_TIME | Workspace Managerでサポートされる最大(最も新しい)タイムスタンプ値。現在は、9999年12月31日(11:59.999999000 pm)が終了時です。 | 
| DBMS_WM.UNTIL_CHANGED | 後続の変更により値がオーバーライドされるまでDBMS_WM.MAX_TIMEとして扱われるタイムスタンプ。 | 
3.4 有効期間のサポート用のAPI機能
次の表に、有効期間のサポート専用、または有効期間のサポートに関連するパラメータを持つDBMS_WMサブプログラムを示します。
表3-2 有効期間のサポート用のAPI機能
| サブプログラム | 有効期間サポート | 
|---|---|
| 
 | |
| 
 | |
| セッションの有効期間の | |
| セッションの有効期間の | |
| セッションの有効期間を指定の範囲に設定します。このプロシージャは、パラメータを指定せずに(有効期間の範囲を現在の時刻から変更時までに設定して)実行するか、 | |
| 現行セッションの有効期間フィルタを削除します。 | |
| 現行セッションの有効期間フィルタ(バージョン対応表に適用される時間)を設定します。 | |
| 有効期間サポートがある表で、順序付きと順序なしの更新操作、および順序付き削除操作を無効にします。 | |
| 有効期間のサポートがある表で、順序付きと順序なしの更新操作、および順序付き削除操作を有効にします。 | 
3.5 有効期間サポートの演算子
Workspace Managerには、2つの期間パラメータを受け入れる関係チェック演算子と関係集合演算子が用意されており、問合せで有効期間フィルタを適用するために使用できます。
関係チェック演算子は、2つの期間に関係がある場合は整数値1を、関係がない場合は0(ゼロ)を戻します。有効期間のサポート用に次の関係チェック演算子が用意されています。
- 
                        WM_OVERLAPSは、2つの期間がオーバーラップしているかどうかをチェックします。 
- 
                        WM_CONTAINSは、第1期間に第2期間が含まれているかどうかをチェックします。 
- 
                        WM_MEETSは、第1期間の終了時が第2期間の開始時と一致するかどうかチェックします。 
- 
                        WM_EQUALSは、2つの期間が等しい(開始時と終了時が同じ)かどうかチェックします。 
- 
                        WM_LESSTHANは、第1期間の終了時が第2期間の開始時より前かどうかチェックします。 
- 
                        WM_GREATERTHANは、第1期間の開始時が第2期間の終了時より後かどうかチェックします。 
集合演算子は、2つの期間の関係を反映する期間を戻すか、2つの期間に指定の関係がない場合はNULL値を戻します。有効期間のサポート用に次の関係集合演算子が用意されています。
- 
                        WM_INTERSECTIONは、2つの期間の交差部、すなわち両方の期間に共通する時間の範囲を戻します。 
- 
                        WM_LDIFFは、2つの期間の差異のうち左側(早い方)の部分を戻します。 
- 
                        WM_RDIFFは、2つの期間の差異のうち右側(遅い方)の部分を戻します。 
関係チェック演算子は、行のwm_valid.validFrom属性とwm_valid.validTill属性のかわりに使用できます。たとえば、次の2つの問合せは等価で、どちらも1991年1月1日に有効なデータが選択されます。
SELECT * FROM employees e WHERE WM_CONTAINS (e.wm_valid,
   WMSYS.WM_PERIOD(TO_DATE('01-01-1991', 'MM-DD-YYYY'), 
                   TO_DATE('01-02-1991', 'MM-DD-YYYY')) = 1;
SELECT * from employees e 
   WHERE e.wm_valid.validFrom <= TO_DATE('01-01-1991', 'MM-DD-YYYY')
     AND e.wm_valid.validTill > TO_DATE('01-03-1991', 'MM-DD-YYYY');
これ以降は、各演算子の追加情報を説明します。各演算子は、アルファベット順に示します。
トピック:
3.5.1 WM_CONTAINS
WM_CONTAINS演算子は、第1期間に第2期間が含まれているかどうかをチェックします。WM_CONTAINS(p1, p2)は、期間p1に期間p2が含まれている場合にのみ1を戻し、それ以外の場合は0(ゼロ)を戻します。
                     
例:
WM_CONTAINS(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1985', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1988', 'MM-DD-YYYY'))) = 1
 
WM_CONTAINS(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1985', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1995', 'MM-DD-YYYY'))) = 0
例3-4では、EMPLOYEES表のうち1995年1月1日に有効だった行(つまり、WM_VALID列の値に1995年1月1日の期間が含まれている行)がすべて戻されます。
                     
例3-4 WM_CONTAINS演算子
SELECT * FROM employees e
  WHERE WM_CONTAINS(e.wm_valid,
    wm_period(TO_DATE('01-01-1995', 'MM-DD-YYYY'),
              TO_DATE('01-02-1995', 'MM-DD-YYYY'))) = 1;
NAME                 SALARY                                                     
---------------- ----------                                                     
WM_VALID(VALIDFROM, VALIDTILL)                                                  
--------------------------------------------------------------------------------
Adams                 30000                                                     
WM_PERIOD('01-JAN-1990 12:00:00 -04:00', '01-JAN-2005 12:00:00 -04:00')3.5.2 WM_EQUALS
WM_EQUALS演算子は、第1期間が第2期間と同じかどうかをチェックします。WM_CONTAINS(p1, p2)は、期間p1が期間p2と等しい場合にのみ1を戻し、それ以外の場合は0(ゼロ)を戻します。
                     
例:
WM_EQUALS(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY'))) = 1
 
WM_EQUALS(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1985', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1995', 'MM-DD-YYYY'))) = 0
例3-5では、EMPLOYEES表のうち1990年1月1日から2005年1月1日に有効である行(つまり、WM_VALID列の値がこの期間と一致する行)がすべて戻されます。
                     
例3-5 WM_EQUALS演算子
SELECT * FROM employees e
  WHERE WM_EQUALS(e.wm_valid,
    wm_period(TO_DATE('01-01-1990', 'MM-DD-YYYY'),
              TO_DATE('01-01-2005', 'MM-DD-YYYY'))) = 1;
NAME                 SALARY                                                     
---------------- ----------                                                     
WM_VALID(VALIDFROM, VALIDTILL)                                                  
--------------------------------------------------------------------------------
Adams                 30000                                                     
WM_PERIOD('01-JAN-1990 12:00:00 -04:00', '01-JAN-2005 12:00:00 -04:00') 3.5.3 WM_GREATERTHAN
WM_GREATERTHAN演算子は、第1期間が第2期間より後に発生するかどうかをチェックします。WM_CONTAINS(p1, p2)は、期間p1全体が期間p2より後の場合にのみ1を戻し、それ以外の場合は0(ゼロ)を戻します。
                     
例:
WM_GREATERTHAN(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1970', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1980', 'MM-DD-YYYY'))) = 1
 
WM_GREATERTHAN(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1970', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1981', 'MM-DD-YYYY'))) = 0
例3-6では、EMPLOYEES表のうち2001年1月1日より後にのみ有効な行(つまり、WM_VALID列のタイムスタンプがどちらも2001年1月1日より後の行)がすべて戻されます。
                     
例3-6 WM_GREATERTHAN演算子
SELECT * FROM employees e
  WHERE WM_GREATERTHAN(e.wm_valid,
    wm_period(TO_DATE('01-01-2001', 'MM-DD-YYYY'),
              TO_DATE('01-02-2001', 'MM-DD-YYYY'))) = 1;
NAME                 SALARY                                                     
---------------- ----------                                                     
WM_VALID(VALIDFROM, VALIDTILL)                                                  
--------------------------------------------------------------------------------
Coleman               50000                                                     
WM_PERIOD('01-JAN-2003 12:00:00 -04:00', '31-DEC-9999 12:00:00 -04:00')3.5.4 WM_INTERSECTION
WM_INTERSECTION演算子は、2つの期間の交差部、すなわち両方の指定された期間に共通する期間を戻します。WM_INTERSECTION(p1, p2)は、期間p1と期間p2の交差部の期間を戻します。
                     
次の例では、1985年1月1日から1988年1月1日の期間が戻されます。
WM_INTERSECTION(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1985', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1988', 'MM-DD-YYYY')))
次の例では、1985年1月1日から1990年1月1日の期間が戻されます。
WM_INTERSECTION(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1985', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1995', 'MM-DD-YYYY')))
次の例では、2つの期間の交差部がないためNULL値が戻されます。
WM_INTERSECTION(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1992', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1995', 'MM-DD-YYYY')))
例3-7では、EMPLOYEES表の行ごとに、WM_PERIOD列の値が1995年1月1日の期間と交差する従業員名と期間が戻されます。
                     
例3-7 WM_INTERSECTION演算子
SELECT e.name, WM_INTERSECTION(e.wm_valid,
  wm_period(TO_DATE('01-01-1995', 'MM-DD-YYYY'),
            TO_DATE('01-02-1995', 'MM-DD-YYYY')))
 FROM employees e;
NAME                                                                            
----------------                                                                
WM_INTERSECTION(E.WM_VALID,WM_PERIOD(TO_DATE('01-01-1995','MM-DD-
--------------------------------------------------------------------------------
Adams                                                                           
WM_PERIOD('01-JAN-1995 12:00:00 -04:00', '02-JAN-1995 12:00:00 -04:00')         
                                                                                
Baxter                                                                          
                                                                                
                                                                                
Coleman 
例3-7の出力が示すように、1995年1月1日に有効な行を持つのはAdamsのみです。
3.5.5 WM_LDIFF
WM_LDIFF演算子は、2つの期間の差異のうち左側(早い方)の部分を戻します。WM_LDIFF(p1, p2)は、期間p1と期間p2の差異のうち左側の期間を戻します。
                     
次の例では、1980年1月1日から1985年1月1日の期間が戻されます。
WM_LDIFF(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1985', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1988', 'MM-DD-YYYY')))
次の例では、p1.validFromがp2.validFromより後のため、NULL値が戻されます。
                     
WM_LDIFF(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1975', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1995', 'MM-DD-YYYY')))
次の例では、p2がp1とまったく重複しない(この場合は後である)ためNULL値が戻されます。
                     
WM_LDIFF(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1992', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1995', 'MM-DD-YYYY')))
例3-8では、EMPLOYEES表の行ごとに、WM_PERIOD列の値が1995年1月1日の左側と異なる従業員名と期間が戻されます。
                     
例3-8 WM_LDIFF演算子
SELECT e.name, WM_LDIFF(e.wm_valid,
  wm_period(TO_DATE('01-01-1995', 'MM-DD-YYYY'),
            TO_DATE('01-02-1995', 'MM-DD-YYYY')))
 FROM employees e;
NAME                                                                            
----------------                                                                
WM_LDIFF(E.WM_VALID,WM_PERIOD(TO_DATE('01-01-1995','MM-DD-YYYY'),
--------------------------------------------------------------------------------
Adams                                                                           
WM_PERIOD('01-JAN-1990 12:00:00 -04:00', '01-JAN-1995 12:00:00 -04:00')         
                                                                                
Baxter                                                                          
                                                                                
                                                                                
Coleman
例3-8の出力が示すように、左側の差異期間中に有効な行を持つのはAdamsのみです。
3.5.6 WM_LESSTHAN
WM_LESSTHAN演算子は、第1期間が第2期間より前に発生するかどうかをチェックします。WM_CONTAINS(p1, p2)は、期間p1全体が期間p2より前の場合にのみ1を戻し、それ以外の場合は0(ゼロ)を戻します。
                     
例:
WM_LESSTHAN(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1991', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1992', 'MM-DD-YYYY'))) = 1
 
WM_LESSTHAN(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1989', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1992', 'MM-DD-YYYY'))) = 0
例3-9では、EMPLOYEES表のうち2010年1月1日より前にのみ有効な行(つまり、WM_VALID列のタイムスタンプがどちらも2001年1月1日より前の行)がすべて戻されます。
                     
例3-9 WM_LESSTHAN演算子
SELECT * FROM employees e
  WHERE WM_LESSTHAN(e.wm_valid,
    wm_period(TO_DATE('01-01-2010', 'MM-DD-YYYY'),
              TO_DATE('01-02-2010', 'MM-DD-YYYY'))) = 1;
NAME                 SALARY                                                     
---------------- ----------                                                     
WM_VALID(VALIDFROM, VALIDTILL)                                                  
--------------------------------------------------------------------------------
Adams                 30000                                                     
WM_PERIOD('01-JAN-1990 12:00:00 -04:00', '01-JAN-2005 12:00:00 -04:00')3.5.7 WM_MEETS
WM_MEETS演算子は、第1期間の終了時が第2期間の開始時かどうかをチェックします。WM_MEETS(p1, p2)は、p1.validTill = p2.validFromの場合にのみ1を、それ以外の場合は0(ゼロ)を戻します。
                     
例:
WM_MEETS(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1990', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1995', 'MM-DD-YYYY'))) = 1
 
WM_MEETS(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1992', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1995', 'MM-DD-YYYY'))) = 0
例3-10では、EMPLOYEES表のうち、有効日付期間の終了タイムスタンプが2005年1月1日から2006年1月1日の期間開始日と同じである場合(つまり、WM_VALID.validTillが指定期間の開始日と等しい場合)にのみ有効な行がすべて戻されます。
                     
例3-10 WM_MEETS演算子
SELECT * FROM employees e
  WHERE WM_MEETS(e.wm_valid,
    wm_period(TO_DATE('01-01-2005', 'MM-DD-YYYY'),
              TO_DATE('01-01-2006', 'MM-DD-YYYY'))) = 1;
NAME                 SALARY                                                     
---------------- ----------                                                     
WM_VALID(VALIDFROM, VALIDTILL)                                                  
--------------------------------------------------------------------------------
Adams                 30000                                                     
WM_PERIOD('01-JAN-1990 12:00:00 -04:00', '01-JAN-2005 12:00:00 -04:00')3.5.8 WM_OVERLAPS
WM_OVERLAPS演算子は、2つの期間がオーバーラップしているかどうかをチェックします。WM_OVERLAPS(p1, p2)は、期間p1と期間p2がオーバーラップしている場合は1を戻し、それ以外の場合は0(ゼロ)を戻します。
                     
例:
WM_OVERLAPS(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1985', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1995', 'MM-DD-YYYY'))) = 1
 
WM_OVERLAPS(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1970', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1980', 'MM-DD-YYYY'))) = 0
例3-11では、EMPLOYEES表のうち、有効日付の範囲が1990年1月1日から2000年1月1日の期間とオーバーラップしている行がすべて戻されます。
                     
例3-11 WM_OVERLAPS演算子
SELECT * FROM employees e
  WHERE WM_OVERLAPS(e.wm_valid,
    wm_period(TO_DATE('01-01-1990', 'MM-DD-YYYY'),
              TO_DATE('01-01-2000', 'MM-DD-YYYY'))) = 1;
NAME                 SALARY                                                     
---------------- ----------                                                     
WM_VALID(VALIDFROM, VALIDTILL)                                                  
--------------------------------------------------------------------------------
Adams                 30000                                                     
WM_PERIOD('01-JAN-1990 12:00:00 -04:00', '01-JAN-2005 12:00:00 -04:00') 3.5.9 WM_RDIFF
WM_RDIFF演算子は、2つの期間の差異のうち右側(遅い方)の部分を戻します。WM_RDIFF(p1, p2)は、期間p1と期間p2の差異のうち右側の期間を戻します。
                     
次の例では、1988年1月1日から1990年1月1日の期間が戻されます。
WM_RDIFF(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1985', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1988', 'MM-DD-YYYY')))
次の例では、p1.validTillがp2.validTillより前のため、NULL値が戻されます。
                     
WM_RDIFF(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1975', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1995', 'MM-DD-YYYY')))
例3-12では、EMPLOYEES表の行ごとに、WM_PERIOD列の値が1995年1月1日より後の異なる従業員名と期間が戻されます。
                     
例3-12 WM_RDIFF演算子
SELECT e.name, WM_RDIFF(e.wm_valid,
  wm_period(TO_DATE('01-01-1995', 'MM-DD-YYYY'),
            TO_DATE('01-02-1995', 'MM-DD-YYYY')))
 FROM employees e;
NAME                                                                            
----------------                                                                
WM_RDIFF(E.WM_VALID,WM_PERIOD(TO_DATE('01-01-1995','MM-DD-YYYY'),
--------------------------------------------------------------------------------
Adams                                                                           
WM_PERIOD('02-JAN-1995 12:00:00 -04:00', '01-JAN-2005 12:00:00 -04:00')         
                                                                                
Baxter                                                                          
                                                                                
                                                                                
Coleman                                                                         
WM_PERIOD('01-JAN-2003 12:00:00 -04:00', '31-DEC-9999 12:00:00 -04:00') 
例3-12の出力が示すように、右側の差異期間中に有効な行を持つのはAdamsとColemanのみです。
3.6 有効期間サポートを使用した問合せおよびDML操作
この項では、有効期間サポートに関連する問合せおよびデータ操作言語(挿入、更新および削除)操作の動作と考慮事項について説明します。
トピック:
3.6.1 問合せ
有効期間サポートを伴うバージョン対応表に対して発行される問合せすべてで、現行のセッションの有効期間設定(SetValidTimeプロシージャまたはSetValidTimeFilterONプロシージャを使用して設定)が考慮されます。問合せで別に指定(たとえば、有効期間サポートの演算子で説明した有効期間サポート演算子の1つを使用して)しないかぎり、各問合せでは、基礎となる表のうち有効期間の範囲がセッションの有効期間または有効期間フィルタとオーバーラップしている行で、問合せのその他の条件を満たす行がすべて表示されます。
デフォルトでは(つまり、セッションでSetValidTimeプロシージャをコールしていない場合、またはパラメータを指定せずにコールした場合)、現時点で有効なすべての行が有効であるとみなされ、現時点から後が制限なしで有効期間とみなされます。
3.6.2 データ操作言語(DML)操作
有効期間サポートがあるバージョン対応表に対して発行されたすべてのDML文(INSERT、UPDATEおよびDELETE)では、現在のセッションの有効期間設定および更新モードが考慮されます。(更新モードは、SetWMValidUpdateModeONおよびSetWMValidUpdateModeOFFプロシージャによって制御します。)DML文は、有効期間が有効なすべての行に影響する可能性があります。
デフォルトでは(つまり、セッションでSetValidTimeプロシージャをコールしていない場合、またはパラメータを指定せずにコールした場合)、現時点で有効なすべての行をDML文で操作でき、変更後のすべての行では有効期間範囲のタイムスタンプが現時点から変更時までとして設定されます。
以降の各項では、特定タイプのDML操作に適用される付加的な考慮事項について説明します。
3.6.2.1 更新演算
有効期間サポートを伴うバージョン対応表の更新操作は、順序付けしても順序付けしなくてもかまいません。
順序付き更新操作が発生するのは、UPDATE文でWM_VALID列の変更を指定しない場合です。順序付き更新操作の場合、行のWM_VALID.ValidTill値は現行セッションの有効期間範囲のValidFromタイムスタンプに変更され、新規の行が作成されて、そのWM_VALID期間に現行セッションの有効期間範囲が反映されます。順序付き更新では、WM_VALID列の値が異なるため、UPDATE文により重複レコードが作成されないことが保証されます。
                        
例3-13は、従業員Baxterを昇給させる、順序付き更新操作を示しています。更新前、Baxterに対して1つの行があり、給与は40000で、有効期間は2000年1月1日から変更されるまでです。
例3-13 順序付き更新操作
-- Update the salary for an existing employee. Perform "sequenced" update, so
-- that existing time-related information is preserved. This results in two rows
-- for Baxter.
-- First, set valid time to the intended range for Baxter's raise.
EXECUTE DBMS_WM.SetValidTime(TO_DATE('01-01-2003', 'MM-DD-YYYY'), 
  DBMS_WM.UNTIL_CHANGED);
-- Give Baxter a raise, effective 01-Jan-2003 until changed.
UPDATE employees SET salary = 45000 WHERE name = 'Baxter';
例3-13の更新操作では、次の文に示すように、既存の行のWM_VALID値が変更され、新規の給与値とセッションの有効期間範囲を反映するWM_VALID値を使用して新規の行が作成されます。
                           
-- Set valid time to encompass virtually all time.
EXECUTE DBMS_WM.SetValidTime(TO_DATE('01-01-1900', 'MM-DD-YYYY'), TO_DATE('01-02-9999', 'MM-DD-YYYY'));
-- See what data exists for Baxter.
SELECT * FROM employees WHERE name = 'Baxter';
NAME                 SALARY
---------------- ----------
WM_VALID(VALIDFROM, VALIDTILL)
--------------------------------------------------------------------------------
Baxter                45000
WM_PERIOD('01-JAN-2003 12:00:00 -04:00', NULL)
Baxter                40000
WM_PERIOD('01-JAN-2000 12:00:00 -04:00', '01-JAN-2003 12:00:00 -04:00')
順序付き削除操作では、セッションの有効期間範囲内にある行の部分が削除されます。つまり、新規の行が作成されて、そのWM_VALID期間に現行セッションの有効期間範囲が反映され、その後、その行が削除されます。例3-13のUPDATE文がかわりにDELETE FROM employees WHERE name = 'Baxter';だった場合、2003年1月1日から変更されるまで有効なBaxterの新しい行は削除されますが、2003年1月1日より前に有効なBaxterの行は影響を受けません。順序なし削除操作という概念はありません。たとえば、有効期間が例3-13で設定されなかった場合、削除操作WHERE name = 'Baxter'ではBaxterに関するすべての行が削除されます。
                           
表が有効期間サポートのあるバージョン対応表の場合、またはバージョン対応表に有効期間サポートが追加された場合、順序付きの更新および削除操作が有効になります。ただし、SetWMValidUpdateModeOFFプロシージャを使用することで、順序付きの更新および削除操作(および順序なし更新操作)のサポートを無効にできます。また、SetWMValidUpdateModeONプロシージャを使用することで、このサポートを再有効化できます。(両方のプロシージャの詳細は、DBMS_WMパッケージ: リファレンスを参照してください。)
順序なし更新操作が発生するのは、UPDATE文でWM_VALID列の変更を指定した場合です。順序なし更新操作では、追加の行は作成されず、更新される1つ以上の行のWM_VALID列値に、UPDATE文で指定した内容が反映されます。順序なし更新操作により、UPDATE文で指定した期間内で有効な同じ主キー値を持つ行が複数生成されないようにする必要があります。このようにしないと、主キー制約違反のために更新が失敗します。
                           
例3-13のUPDATE文は順序なし更新操作だったため、実行結果はBaxterに関する行が1行のみとなっています。既存の行の給与は45000に設定され、WM_VALID列はUPDATE文に指定した期間に設定されます。
                           
3.6.2.2 挿入操作
有効期間サポートを伴うバージョン対応表に1行を挿入する場合に、その行の有効期間を指定できます。期間にNULLのタイムスタンプを指定すると、セッションの有効期間が使用されます。
有効期間サポートを伴うバージョン対応表に1行が挿入されると、Workspace Managerでは、同じ主キー値を持つ既存の行の有効期間範囲が、新規に挿入された行の有効期間範囲とオーバーラップしていないことが確認されます。このような行が検出されると、例外が発生します。例3-14に、有効期間がオーバーラップしているために主キー制約違反となる挿入操作を示します。
例3-14 期間のオーバーラップが原因で失敗する挿入操作
-- Insert. Should violate primary key constraint, because of overlapping times:
-- existing Coleman row is valid from 01-Jan-2003 until 31-Dec-9999.
INSERT INTO employees VALUES(
  'Coleman',
  55000,
  WMSYS.WM_PERIOD(TO_DATE('01-01-2004', 'MM-DD-YYYY'),
                  TO_DATE('12-31-9999', 'MM-DD-YYYY'))
);
)
*
ERROR at line 6:
ORA-20010: unique key violation 
ORA-06512: at "WM_DEVELOPER.OVM_INSERT_10", line 1 
ORA-04088: error during execution of trigger 'WM_DEVELOPER.OVM_INSERT_10'
例3-14に示した文を正常に実行するには、最初にColemanの行のWM_VALID.ValidTill属性を、2004年1月1日以前の日付を反映するタイムスタンプに変更します。
3.7 有効期間サポートのための制約管理
この項では、参照整合性制約と一意制約に影響する有効期間サポートに関連した考慮事項について説明します。
3.7.1 参照整合性制約
有効期間サポートを伴う2つのバージョン対応表の間に参照整合性制約が存在する場合は、制約の規定時に各行の有効期間が考慮されます。たとえば、DEPARTMENTS表に、EMPLOYEES表のEMPLOYEE_ID列を参照する外部キーであるMANAGER_ID列が含まれている(つまり、部門マネージャは既存の従業員である必要がある)とします。両方の表が有効期間サポートありのバージョン対応表で、挿入操作または更新操作により新しいDEPARTMENTS.MANAGER_ID値が生成される場合、DEPARTMENTS.WM_VALID値が、部門マネージャとなる従業員のEMPLOYEES.WM_VALID値の範囲内にない場合には、操作は失敗します。(つまり、新規の部門マネージャが挿入または更新操作に対して指定される期間またはデフォルト設定される期間に有効な従業員でなければ、操作は失敗します。)
                     
参照整合性制約に含まれる表の一方または両方が、有効期間サポートを伴うバージョン対応表でない場合、制約の規定時には有効期間が無視されます。
3.7.2 一意制約
有効期間サポートがあるバージョン対応表に一意制約が存在する場合、制約の実施時に行の有効期間が考慮されます。たとえば、EMPLOYEES表に、一意制約があるEMPLOYEE_ID列が含まれるとします。挿入操作または更新操作により、既存のEMPLOYEE_ID値と同じ新しいEMPLOYEE_ID値が生成される場合、既存の行と挿入された行のWM_VALID値が重複する場合には、操作は失敗します。(つまり、新しい従業員と既存の従業員が同じID番号を持ち、ある時点でそれらの行がどちらも有効である場合、操作は失敗します。ただし、2名の従業員の有効期間が重複していない場合、この操作は正常に実行されます。)
                     
3.8 有効期間サポートを使用したロック
有効期間サポートを伴うバージョン対応表の1行がロックされる場合、その行は自動的に有効期間全体を通じてロックされます。指定した期間だけ行をロックする方法はありません。
即時ロックされた作業領域内で更新操作を実行すると、その実行と同時に祖先作業領域から表示されている行がロックされます。祖先作業領域内でロックされている行は、ロックされているかぎり、有効期間中はそれ以上更新できなくなります。
Workspace Managerのロック操作の詳細は、Workspace Managerでのロック管理を参照してください。
3.9 有効期間サポートの影響を受ける静的データ・ディクショナリ・ビュー
この項では、Workspace Managerの静的データ・ディクショナリ・ビューに対する有効期間サポートの影響について説明します。
これらのビューの詳細は、Workspace Managerの静的データ・ディクショナリ・ビューを参照してください。
トピック:
3.9.1 xxx_CONFビューと有効期間サポート
有効期間サポートを伴うバージョン対応表の場合、xxx_CONFビュー(xxx_CONFビューを参照)には、一時的な競合が含まれます。このような競合が発生するのは、親作業領域内で、子作業領域にある行と同じキーを含む行の有効期間が、子作業領域内のその行の有効期間とオーバーラップする場合です。セッション・コンテキストの有効期間を設定しても、時間ディメンション全体について該当する競合がすべて表示されるため、xxx_CONFビューの結果には影響しません。
有効期間サポートを伴うバージョン対応表の場合は、行の有効期間を示すためにxxx_CONFビューにWM_PERIOD型のWM_VALID列が追加されます。競合が検出された行の重複期間を示すために、WM_PERIOD型のWM_CONFLICTPERIODという名前の列もビューに追加されます。
                     
3.9.2 xxx_DIFFビューと有効期間サポート
有効期間サポートを伴うバージョン対応表の場合、xxx_DIFFビュー(xxx_DIFFビューを参照)には、2つの異なる作業領域またはセーブポイント間の主キーの一時的な差異が含まれます。このような差異が発生するのは、親作業領域または子作業領域内で行が変更(挿入、更新または削除)される場合です。同じ主キー値を持つ2つの行が親作業領域と子作業領域の両方で変更される場合に、各行の有効期間範囲がオーバーラップしていると、2つの行の相関関係はxxx_DIFFビューにのみ表示されます。セッション・コンテキストの有効期間を設定しても、時間ディメンション全体について該当する差異がすべて表示されるため、xxx_DIFFビューの結果には影響しません。
有効期間サポートを伴うバージョン対応表の場合は、行の有効期間を示すためにxxx_DIFFビューにWM_PERIOD型のWM_VALID列が追加されます。差異が検出された行の重複期間を示すために、WM_PERIOD型のWM_DIFFPERIODという名前の列もビューに追加されます。
                     
3.9.3 xxx_HISTビューと有効期間サポート
xxx_HISTビュー(xxx_HISTビューを参照)には、有効期間とトランザクション時間の両方に関する情報が含まれています。また、行を作成したユーザーの名前などの監査情報も含まれます。有効期間サポートを伴うバージョン対応表の場合は、行の有効期間を示すためにxxx_HISTビューにWM_PERIOD型のWM_VALID列が追加されます。
                     
3.9.4 xxx_LOCKビューと有効期間サポート
有効期間サポートを伴うバージョン対応表の場合は、行の有効期間を示すためにxxx_LOCKビュー(xxx_LOCKビューを参照)にWM_PERIOD型のWM_VALID列が追加されます。行は有効期間全体を通じてロックされるため、有効期間がロック期間となります。
                     
3.9.5 xxx_MWビューと有効期間サポート
有効期間サポートを伴うバージョン対応表の場合は、行の有効期間を示すためにxxx_MWビュー(xxx_MWビューを参照)にWM_PERIOD型のWM_VALID列が追加されます。指定した期間中に有効な行のみを表示するには、WM_OVERLAPS演算子を使用します。
                     
3.10 既存の表に対する有効期間サポートの追加
既存のバージョン対応表に有効期間サポートを追加できます。
そのためには、AlterVersionedTableプロシージャを使用します。既存のすべての行のWM_VALID列に設定する有効期間を指定するか、現在のタイムスタンプから変更時までというデフォルトの期間を受け入れることができます。
例3-15では、MY_TABLE表を作成し、有効期間サポートなしでバージョン対応にしてから、有効期間サポートを追加しています。有効期間サポートを追加した後のWM_VALID列には、デフォルトの有効期間が含まれます。
                  
例3-15 既存のバージョン対応表に対する有効期間サポートの追加
CREATE TABLE my_table (id NUMBER PRIMARY KEY);
EXECUTE DBMS_WM.EnableVersioning ('my_table');
INSERT INTO my_table VALUES (1);
SELECT * FROM my_table;
        ID
----------
         1
EXECUTE DBMS_WM.AlterVersionedTable('my_table', 'ADD_VALID_TIME');
SELECT * FROM my_table;
        ID
----------
WM_VALID(VALIDFROM, VALIDTILL)
--------------------------------------------------------------------------------
         1
WM_PERIOD('09-JUN-2003 10:04:13 -04:00', NULL)3.11 有効期間サポートありの表の作業領域のマージおよびリフレッシュ
有効期間サポートがある表をマージまたはリフレッシュする場合、主キー値が同じ行の間に交差部がある明確なケースを考慮することで、結果の行を特定できます。
2つの行が交差しているかどうか判別するために、WM_OVERLAPS演算子を使用できます。
表3-3に示すvalidTillの場合:
                  
- 
                        マージ操作では、ターゲット作業領域は親作業領域です。 
- 
                        リフレッシュ操作では、ターゲット作業領域は、指定した作業領域の子作業領域です。 
- 
                        行の交差の性質のために、競合解消は、マージまたはリフレッシュ操作の前に実行されています。(1つのソース行が複数のターゲット行と競合する可能性があり、また1つのターゲット行が複数のソース行と競合する可能性があります。) 
表3-3 validTill値およびマージまたはリフレッシュ操作の交差結果
| validTill値 | 交差結果 | 
|---|---|
| ソース行とターゲット行の両方に、 | ターゲット作業領域で行の交差部分がソース行と等しくなるように変更されます。 | 
| ソース行の | 行の交差部分が変更され、結果の行にソース行と同等の | 
| ソース行の | 行の交差部分が変更され、結果の行にターゲット行と同等の | 
| ソース行とターゲット行の両方の | 交差部分が変更され、結果の行に | 
表3-3のすべてのケースで、ターゲット行の非交差部分は変更されないままです。ターゲット作業領域に重複行が存在しない場合、特別な考慮は不要です。追加の変更なしでそのまま行はマージまたはリフレッシュされます。