CREATE MASK ステートメント

CREATE MASK ステートメントは、現行サーバーで列マスクを作成します。列マスクは、指定された列について戻す値を指定します。

呼び出し

このステートメントは、アプリケーション・プログラムに組み込むか、あるいは対話式に発行することができます。これは、DYNAMICRULES 実行動作が暗黙的または明示的に指定された場合のみ、動的に準備できる実行可能ステートメントです。

許可

このステートメントの許可 ID が持つ特権には、SECADM 権限が含まれている必要があります。 SECADM 権限では、任意のスキーマに列マスクを作成できます。マスク定義内でその他のオブジェクトを参照するために必要なその他の権限はありません。 例えば、表からデータを取り出すための SELECT 特権や、ユーザー定義関数を呼び出すための EXECUTE 特権は必要ありません。

構文

構文図を読む構文図をスキップするCREATEOR REPLACE MASKmask-nameONtable-name AScorrelation-nameFOR COLUMNcolumn-nameRETURN case-expressionDISABLEENABLE

説明

OR REPLACE
列マスクの定義が現行のサーバー上に存在している場合に、その列マスクの定義を置換するために指定します。 既存の定義は、新しい定義がカタログ内で置換される前に、効率的にドロップされます。
mask-name
列マスクの名前を指定します。名前 (暗黙修飾子または明示修飾子を含む) は、現行サーバーに既に存在する列マスクや行アクセス権を指定するものであってはなりません (SQLSTATE 42710)。
table-name
列マスクを作成する対象の表を指定します。名前は、現行サーバーに存在する表を識別するものでなければなりません (SQLSTATE 42704)。この名前は、ニックネーム、作成済み一時表、宣言済み一時表、ビュー、シノニム、型付き表、別名 (SQLSTATE 42809)、カタログ表 (SQLSTATE 42832) を識別するものであってはなりません。
correlation-name
表を指定するために case-expression 内で使用できる相関名を指定します。
FOR COLUMN column-name
マスクを適用する列を指定します。column-name は、表の列を指定する非修飾名でなければなりません (SQLSTATE 42703)。 この列にはマスクが既に存在していてはなりません (SQLSTATE 428HC)。この列は、以下の列のいずれであってもなりません。
  • LOB 列、または LOB に基づく特殊タイプ列 (SQLSTATE 42962)。
  • XML 列 (SQLSTATE 42962)。
  • 生成される列を定義する式で参照される列 (SQLSTATE 428HB)。
RETURN case-expression
列について戻す値を決定するために評価される CASE 式を指定します (SQLSTATE 42601)。CASE 式の結果が、行の列値の位置に返されます。CASE 式の結果のデータ・タイプ、NULL 属性、データ長はそれぞれ、column-name のものと同じでなければなりません (SQLSTATE 428HB)。column-name のデータ・タイプがユーザー定義のデータ・タイプである場合、 CASE 式の結果のデータ・タイプは同じユーザー定義のデータ・タイプでなければなりません。 CASE 式では、以下のオブジェクトまたはエレメントのいずれも参照してはなりません (SQLSTATE 428HB)。
  • 作成済みのグローバル一時表または宣言済みのグローバル一時表。
  • シャドー表。
  • ニックネーム。
  • 表関数。
  • メソッド。
  • パラメーター・マーカー (SQLSTATE 42601)。
  • 非セキュアとして定義されているユーザー定義関数。
  • 非決定論的である、または外部アクションを持つ関数や式 (ROW CHANGE 式、シーケンス式など)。
  • XMLQUERY スカラー関数。
  • XMLEXISTS 述部。
  • OLAP 指定。
  • SELECT 文節内の * または name.*
  • 疑似列。
  • SELECT 節を指定しない集約関数。
  • 前記のいずれかの制限が定義に含まれるビュー。
行アクセス制御または列アクセス制御が現在アクティブになっている表を CASE 式で参照している場合、これらの表からのアクセス制御はカスケードされません。詳しくは、『注』のセクションを参照してください。
ENABLE または DISABLE
列アクセス制御のための列マスクを有効または無効にすることを指定します。デフォルトは DISABLE です。
DISABLE
列アクセス制御のための列マスクを無効にすることを指定します。表の列アクセス制御が現在アクティブになっていない場合、列マスクは、表の列アクセス制御がアクティブになっても無効のままになります。
ENABLE
列アクセス制御のための列マスクを有効にすることを指定します。表の列アクセス制御が現在アクティブになっていない場合、列マスクは、表の列アクセス制御がアクティブになったときに有効になります。表の列アクセス制御が現在アクティブになっている場合、列マスクはすぐに有効になり、その表を参照するすべてのパッケージと動的キャッシュ・ステートメントが無効になります。

有効な列マスクを適用しても、ステートメント内の他の節 (WHERE、GROUP BY、HAVING、SELECT DISTINCT、および ORDER BY など) の操作が妨げられることはありません。最終結果表に返される行は、結果行に含まれている値が列マスクによってマスクされた可能性があるという点を除けば、違いはありません。 そのため、マスクされた列が ORDER BY ソート・キーにも出現する場合、順序は元の列値に基づくものとなり、最終結果表でマスクされた値にその順序が反映されない可能性があります。 同様に、マスクされた値は、SELECT DISTINCT によって強制適用される固有性が反映されない可能性があります。 マスクされる列が式に組み込まれていると、列マスクは式の評価が行われる前に列に適用されるため、式の結果が異なる場合があります。 例えば、列 SSN に列マスクを適用すると、マスク値に対して DISTINCT 操作が行われるため、集約関数 COUNT(DISTINCT SSN) の結果が変わることがあります。一方、照会に含まれる式が、列マスク定義内で列値をマスクするために使用されている式と同じである場合、式の結果は変わらない可能性があります。 例えば、照会の式が 'XXX-XX-' || SUBSTR( SSN, 8, 4) で、列マスク定義に同じ式が指定されているとします。この特定の例では、照会の式を列 SSN で置き換えることにより、同じ式が 2 回評価されるのを回避できます。

列マスクはスタンドアロン・オブジェクトとして作成され、これが使用されるコンテキストのすべてを認識しているわけではありません。最終結果表内の列値をマスクするために、列マスク定義はデータベース・マネージャーによって照会にマージされます。列マスク定義は、ステートメントのコンテキストに取り込まれると、ステートメント内の特定の SQL セマンティクスと競合することがあります。したがって、特定の状況では、ステートメントと列マスクの適用方法の組み合わせによってはエラーが戻されることがあります (SQLSTATE 428HD)。この状況が発生した場合は、ステートメントを変更するか、列マスクをドロップする、または異なる定義で再作成する必要があります。ステートメントについてバインド時エラーが出される可能性がある状況については、ALTER TABLE ステートメントの説明を参照してください。

列が NULL 可能でない場合、その列マスク定義は、その列について NULL 値を考慮しません。ターゲット表の列アクセス制御がアクティブにされた後、ターゲット表が外部結合操作で NULL が埋められた表となる場合、最終結果表の列値は NULL となる可能性があります。列マスクが NULL 値を確実にマスクできるように、 データベース・マネージャーが列マスク定義を照会にマージするときに、 ターゲット表が外部結合操作で NULL が埋められた表である場合、 最初の WHEN 節として "WHEN target-column IS NULL THEN NULL" が列マスク定義に追加されます。 これにより、NULL 値が必ず NULL にマスクされるようになります。NULL 可能列の場合、これにより、NULL 値を別の値にマスクすることはできなくなりますが、セキュリティーとユーザビリティーの観点からは許容される制約事項です。

ある列を使用して、INSERT、UPDATE、MERGE、または SET transition-variable 代入ステートメントの新規の値を派生させる場合、マスク値ではなくオリジナルの列値が新規の値の派生に使用されます。 列に列マスクがある場合、その列マスクが適用され、実行時のアクセス制御規則の評価によって、列が定数にでも式にでもなく確実にそれ自体にマスクされます。 これによって、マスク値がオリジナルの列値と必ず同じになります。 列マスクによって列が列自体にマスクされない場合、既存の行は更新されず、新規行は挿入されず、実行時にエラーが戻されます (SQLSTATE 428HD)。マスクされたデータを表に挿入する必要がある場合、まずそのデータを変数に割り当てておくことによってそれを実現できます。 例えば、行データ・タイプの配列エレメントを持つ配列変数を作成できます。 列マスクの適用された表データを配列変数に割り当て、次にその配列変数を使用して別の表にデータを挿入することができます。 新規の値を派生させるために列マスクの適用に使用される規則は、照会の最終結果表について前述したのと同じ規則に従います。挿入操作および更新操作に影響する列マスクの使用方法については、INSERT、UPDATE、および MERGE の各ステートメントを参照してください。

表の列アクセス制御をアクティブにする方法、および列マスクが適用される方法については、ACTIVATE COLUMN ACCESS CONTROL 節を指定した ALTER TABLE ステートメントを参照してください。

  • 表の列アクセス制御がアクティブになる前に作成された列マスク: CREATE MASK ステートメントは独立したステートメントであり、これを使用して、表の列アクセス制御がアクティブになる前に列アクセス制御マスクを作成することができます。 この場合の唯一の要件は、表と列がマスクの作成前に存在していることです。単一の表に対して複数の列マスクを作成できますが、1 つの列に設定できるマスクは 1 つのみです。

    マスクの定義は データベース・カタログに保管されます。マスクの作成対象の表への従属関係と、定義で参照されるその他のオブジェクトへの従属関係が記録されます。パッケージや動的キャッシュ・ステートメントは無効になりません。列マスクの作成時には、列アクセス制御のためにその列マスクを有効にするか無効にするかを指定できます。有効に設定されている列マスクは、ACTIVATE COLUMN ACCESS CONTROL 節が指定された ALTER TABLE ステートメントを使用して表の列アクセス制御がアクティブになった後で、初めて有効になります。ALTER TABLE ステートメントを発行するには SECADM 権限が必要です。表の列アクセス制御がアクティブになっても、無効な列マスクは引き続き無効です。ALTER MASK ステートメントを使用して、ENABLE と DISABLE を切り替えることができます。

    表の列アクセス制御がアクティブになった後、表がデータ操作ステートメントで参照されるとき、その表に対して作成されているすべての有効な列マスクがデータベース・マネージャーによって暗黙的に適用され、照会の最終結果表で参照される列について返される値がマスクされるか、データ変更ステートメントで使用する新しい値が決定されます。

    表を参照する動的キャッシュ・ステートメントおよびパッケージが繰り返し無効になることを防ぐため、列マスクを作成してから表の列アクセス制御をアクティブにするという順序で操作することをお勧めします。

  • 表の行アクセス制御がアクティブになった後で作成された列マスク: 有効に設定された列マスクは、コミットされるとすぐに有効になります。 表を参照するパッケージと動的キャッシュ・ステートメントはすべて無効になります。したがって、データ操作ステートメントで表が参照されている場合、有効な列マスクはすべて、データベース・マネージャーによりそのステートメントに暗黙に適用されます。表の列アクセス制御がアクティブになっても、無効な列マスクは引き続き無効です。
  • 列アクセス制御または行アクセス制御が適用されている表が列マスク定義で参照される場合、カスケード効果はない: 列マスク定義が、行アクセス制御または列アクセス制御が現在適用されている表と列を参照することがあります。列マスクの作成対象の表がデータ操作ステートメントで参照される場合、このような表と列のアクセス制御は無視されます。
  • データベース制限に関する考慮事項: データ操作ステートメントで既にいくつかのデータベース制限に近づいている場合、作成される有効な列マスクと有効な行の権限の数が多いほど、それらがいくつかの制限に影響する可能性が高くなります。これは、データ操作ステートメントで表が参照される場合に、有効な列マスク定義と行の権限の定義が暗黙にこのステートメントにマージされるためです。
  • 使用可能に設定されているが無効な状態にある列マスク: 列アクセス制御の列マスクが使用可能に設定されているものの、その状態が無効に設定されている場合、列マスクが定義された表へのアクセスは、この状態が解決されるまでブロックされます (SQLSTATE 560D0)。
  • 列マスクの定義対象の列に代入できないデータを返す列マスク: 列マスクの定義によっては、定義対象の列のデータ・タイプに割り当てられないデータを返す可能性がある列マスクになる場合があります。 この状況が生じる場合、CREATE MASK ステートメントは成功しますが、 ユーザー照会でマスクが適用されるときにキャスト・エラーが報告されます。

  • 例 1: 表 EMPLOYEE の列アクセス制御がアクティブになった後で、給与管理部門の Paul は、従業員番号が 123456 の従業員の社会保障番号を確認できます。管理職の Mary は、社会保障番号の最後の 4 文字のみを確認できます。どちらのロールでもない Peter は、社会保障番号を確認できません。
    CREATE MASK SSN_MASK ON EMPLOYEE
      FOR COLUMN SSN RETURN
        CASE WHEN (VERIFY_GROUP_FOR_USER(SESSION_USER,'PAYROLL') = 1)
                                     THEN SSN
             WHEN (VERIFY_GROUP_FOR_USER(SESSION_USER,'MGR') = 1)
                                     THEN 'XXX-XX-' || SUBSTR(SSN,8,4)
             ELSE NULL
        END
      ENABLE;
    ALTER TABLE EMPLOYEE ACTIVATE COLUMN ACCESS CONTROL;
    SELECT SSN FROM EMPLOYEE WHERE EMPNO = 123456;
  • 例 2: SELECT ステートメントで、列マスク SSN_MASK に使用されている式と同じ式に列 SSN が組み込まれています。 表 EMPLOYEE に対して列アクセス制御をアクティブにした後に、列マスク SSN_MASK が SELECT ステートメントの列 SSN に適用されます。この特定の式の場合、SELECT ステートメントの結果は、すべてのユーザーに対して列アクセス制御をアクティブにする前と同じ結果になります。 ユーザーは SELECT ステートメントの式を列 SSN に置き換えることによって、同じ式が 2 回評価されるのを回避できます。
    CREATE MASK SSN_MASK ON EMPLOYEE
      FOR COLUMN SSN RETURN
        CASE WHEN (1 = 1) THEN 'XXX-XX-' || SUBSTR(SSN,8,4)
             ELSE NULL
        END
      ENABLE;
    ALTER TABLE EMPLOYEE ACTIVATE COLUMN ACCESS CONTROL;
    SELECT 'XXX-XX-' || SUBSTR(SSN,8,4) FROM EMPLOYEE WHERE EMPNO = 123456;
  • 例 3: カリフォルニア州政府が、各都市の世帯における図書館利用に関する調査を実施しました。各都市から 50 世帯がこの調査対象として抽出されました。各世帯には、調査結果から生成されるどのレポートでもそれぞれの利用状況を示すかどうかを指定するオプション (オプトインまたはオプトアウト) が与えられました。

    SELECT ステートメントを使用して、各都市の世帯の平均利用時間を示すレポートが生成されます。抽出された世帯が選択したオプトインまたはオプトアウトの情報に基づいて都市名をマスクするため、列マスク CITY_MASK が作成されます。しかし、表 LIBRARY_ USAGE に対して列アクセス制御をアクティブにした後に、SELECT ステートメントはバインド時エラーを受け取ります。このエラーは、列マスク CITY_MASK が別の列 LIBRARY_OPT を参照しており、この LIBRARY_OPT がグループ化列を識別していないために発生します。

    CREATE MASK CITY_MASK ON LIBRARY_USAGE
      FOR COLUMN CITY RETURN
        CASE WHEN (LIBRARY_OPT = 'OPT-IN') THEN CITY
             ELSE ' '
        END
      ENABLE;
    ALTER TABLE LIBRARY_USAGE ACTIVATE COLUMN ACCESS CONTROL;
    SELECT CITY, AVG(LIBRARY_TIME) FROM LIBRARY_USAGE GROUP BY CITY;
  • 例 4: EMPNO が 123456 の従業員の 5 月のボーナスは $8000、給与は $80000 です。管理職がこの従業員の給与を取り出すときに、NULL 値ではなく給与額が取り出されます。これは、列マスク SALARY_MASK が、列マスク BONUS_MASK が定義されている列 BONUS を参照する場合、カスケード効果が発生しないためです。
    CREATE MASK SALARY_MASK ON EMPLOYEE
      FOR COLUMN SALARY RETURN 
        CASE WHEN (BONUS < 10000) THEN SALARY
             ELSE NULL
        END
      ENABLE;
    CREATE MASK BONUS_MASK ON EMPLOYEE
      FOR COLUMN BONUS RETURN 
        CASE WHEN (BONUS > 5000) THEN NULL
             ELSE BONUS
        END
      ENABLE;
    ALTER TABLE EMPLOYEE ACTIVATE COLUMN ACCESS CONTROL;
    SELECT SALARY FROM EMPLOYEE WHERE EMPNO = 123456;