6.4 フィルタによるエクスポートの絞込み

project exportコマンドの使用時は、どのデータベース・オブジェクトをエクスポートに含めるかを正確に制御するためにSQLフィルタを適用できます。これにより、そのプロセスを微調整して、必要なオブジェクトについてのみデータ定義言語(DDL)を生成できます。

これらのフィルタのしくみと、それらをプロジェクトにあわせてカスタマイズする方法について学習します。

6.4.1 フィルタとそのタイプについて

SQLフィルタとは、エクスポート・プロセスの間にデータ・ディクショナリ問合せに適用されるSQL式(つまり、述語)です。これにより、特定のデータベース・オブジェクトを含めるかどうかを決定する条件を示します。

Oracle SQLclでは、次の2つのタイプのフィルタがエクスポートの間にサポートされています:

内部フィルタ

内部フィルタは組み込まれており、エクスポート・プロセスに必ず適用されます。これらのフィルタの変更や無効化はできません。それらでは、システムレベルのスキーマ、および通常のプロジェクト・エクスポートに関連しないオブジェクトは自動的に除外されます。

たとえば、次の内部フィルタでは、セカンダリ・オブジェクト、およびSYSまたはPUBLICが所有するオブジェクトは除外されます:

and (Dba_objects.secondary = 'N') --<-- sqlcl internal.fixed.filters
and (Dba_objects.owner not in ('SYS', 'PUBLIC')) --<-- sqlcl internal.fixed.filters

プロジェクト・フィルタ

プロジェクト・フィルタとは、特定のニーズにあわせてデータベース・オブジェクトの選択内容を絞り込むために作成するカスタム・フィルタです。フィルタを作成して、一時的な開発オブジェクトを除外することや、特定のAPEXアプリケーションのみを含めることや、名前のパターンを基準にしてオブジェクトをフィルタすることができます。

たとえば、次のエクスポート・フィルタでは、名前のパターンを基準にしてオブジェクトが除外されます:
object_name not like 'DBTOOLS$%'
次のフィルタでは、Oracle Machine LearningまたはData Miningで生成された表は除外されます:
not (object_type = 'TABLE' and object_name like 'DM$%')
このフィルタでは、特定のAPEXアプリケーションがエクスポートされます:
application_id in (200, 300)

6.4.2 プロジェクト・フィルタの作成と管理

プロジェクト(またはカスタム)フィルタは、特定のディレクトリ内で作成および管理します。

開始するには、プロジェクトの.dbtools/filters/ディレクトリ内のproject.filtersファイルを見つけます。これは、カスタム・フィルタ用のプライマリ・ファイルです。これには、適用するフィルタを示す述語のカンマ区切りリストが含まれます。このファイルを編集して、すべてのカスタム・フィルタ条件を追加できます。

より適切な編成にするために、.dbtools/filters/フォルダ内に、.filters拡張子を付けて新しいファイルを作成します。これにより、関連するフィルタを個別のファイルにグループ化できます。ファイルの拡張子が.filtersであれば、SQLclによって自動的にそのファイルが読み取られ、エクスポートの間にそのファイル内のフィルタが適用されます。SQLclにより、このディレクトリにあるすべての.filtersファイルが読み取られ適用されます。

6.4.3 高度なフィルタリング手法

より細かく制御するには、フィルタ内のexport_type列とobject_type列を使用します。

6.4.3.1 export_type列を使用したフィルタリング

export_typeは、カテゴリを基準にしてデータベース・オブジェクトをフィルタするために使用できる、特殊な擬似列です。これにより、特定のオブジェクト・タイプを選択的にエクスポートできます(基にあるディクショナリ・ビューに存在しないものも含む)。

使用可能なエクスポート・タイプは、簡単に参照できるように、project.filtersファイルの先頭にリストされています。

使用可能なエクスポート・タイプをすべて含むリストを次に示します:

  • ALL_OBJECTS
  • ALL_INDEXES
  • ALL_TRIGGERS
  • ALL_SYNONYMS
  • ALL_COL_COMMENTS
  • ALL_TAB_COMMENTS
  • ALL_TAB_PRIVS
  • ALL_MVIEW_LOGS
  • ALL_QUEUE_TABLES
  • ALL_QUEUES
  • ALL_DEPENDENCIES
  • APEX_APPLICATIONS
  • ORDS_SCHEMA
  • USER

次に、エクスポート・タイプを使用して定義されたフィルタの例をいくつか示します。

例6-1 ORDSの除外

このフィルタ例では、ORDS_SCHEMAエクスポート・タイプを使用して、エクスポートからOracle REST Data Services (ORDS)を除外しています:
export_type != 'ORDS_SCHEMA'

例6-2 APEXアプリケーションのエクスポート

このフィルタ例では、APEX_APPLICATIONエクスポート・タイプを使用して、APEXアプリケーションのみをエクスポートしています:
export_type = 'APEX_APPLICATION'

6.4.3.2 object_type列を使用したフィルタリング

object_type列を使用すると、タイプ(たとえば、表やビュー)を基準にしてデータベース・オブジェクトをフィルタできます。

これは、特定のタイプまたは名前のオブジェクトすべてを除外する必要がある場合に役立ちます。オブジェクトのタイプが不明な場合は、データベースに直接問い合せることでそれを識別できます。

データベース内のすべてのオブジェクト・タイプの個別リストを取得するには、次の問合せを実行します:
select distinct object_type from all_objects;

結果に基づいて、エクスポートから特定のタイプ(たとえば、MLE_MODULEMLE_ENVIRONMENT)を除外するフィルタを記述できます。

次に、オブジェクト・タイプを使用して定義されたフィルタの例をいくつか示します。

例6-3 MLEオブジェクトの除外

このフィルタ例では、エクスポートからMLE_MODULEおよびMLE_ENVIRONMENTオブジェクト・タイプを除外しています:
object_type not in ('MLE_MODULE', 'MLE_ENVIRONMENT')

例6-4 表の除外

このフィルタでは、すべての表オブジェクトが除外されます:
object_type != 'TABLE'

例6-5 特定のビューの除外

この例では、名前を基準にして特定のビューを除外しています:
not (object_type = 'VIEW' and object_name ='EMP_V')

6.4.4 フィルタの適用のしくみ

エクスポート・プロセスの間に、フィルタにより、データベースのディクショナリ・ビューに対して実行されるSQL問合せに条件を直接挿入することで、データベース・オブジェクトの選択内容が絞り込まれます。基本的に、各フィルタはWHERE句として機能します。これにより、必要なデータのみが取得されるようにビューの問合せが変更されます。

このプロセスは次のように機能します。

  1. 構文の検証:最初に、SQLclにより、各フィルタが解析されて、有効なSQL述語であることが確認されます。フィルタに構文エラーがあった場合は、そのエクスポート・プロセスがただちに停止され、エラー・メッセージを返します。

  2. スコープの評価: フィルタ内のその列名をどのように参照しているかに応じて、SQLclによって各フィルタのスコープが決定されます。修飾列名または非修飾列名のどちらかを使用できます。

    • 非修飾フィルタ:非修飾フィルタは、指定した列を含むすべてのディクショナリ・ビューに適用されます。これは、多数のオブジェクト・タイプにわたり、一般的な条件を適用する場合に役立ちます。

      たとえば、次のフィルタは、owner列があるすべてのビュー(ALL_OBJECTSALL_TABLESAPEX_APPLICATIONSなど)に適用されます。
      owner = 'HR'
    • 修飾フィルタ: 修飾フィルタ(view_name.column_name)は、指定した特定のディクショナリ・ビューのみに適用されます。これにより、正確な、ターゲットを絞った制御が可能になります。

      たとえば、次のフィルタはALL_OBJECTSビューのみに適用されます。
      all_objects.object_name = 'EMPLOYEES'
  3. 問合せの実行: 各フィルタのスコープが決定された後、SQLclにより、そのフィルタが、関連するディクショナリ問合せに挿入されます。その後、それらのディクショナリ問合せに対してそのフィルタが検証されます。
    • フィルタが無効であるか、関連する問合せと競合する場合は、そのエクスポート・プロセスがただちに停止され、エラー・メッセージを返します。
    • フィルタが有効である場合は、SQLclにより、条件に一致するデータのみをエクスポートする最終的な変更された問合せが実行されます。

次の例では、単純なフィルタの適用方法を示します。

例6-6 名前の接頭辞を基準にしたオブジェクトのフィルタリング

名前がHR_で始まるオブジェクトのみをエクスポートするには、次の非修飾フィルタを使用します:
object_name like 'HR_%'

このフィルタでは、そのobject_name列を含むすべてのディクショナリ・ビュー(ALL_OBJECTSALL_INDEXESALL_TRIGGERSなど)が対象となります。エクスポート・プロセスの間に、SQLclにより、関連する各ビューの問合せが、このフィルタを含むように変更されて、名前がHR_で始まるオブジェクトのみが選択されるようになります。

たとえば、ALL_OBJECTSビューに対する問合せは次のようになります:
select * from all_objects where object_name like 'HR_%';

同じフィルタリング・ロジックがALL_INDEXESALL_TRIGGERSなどのその他のビュー、およびそのobject_name列を含むその他のビューに適用されて、エクスポート全体にわたり、一貫性のある、ターゲットを絞ったデータ取得が維持されます。

6.4.5 適用済フィルタのデバッグ

想定している結果がエクスポートで生成されない場合は、project exportコマンドに-debugフラグを追加することで、フィルタリング・プロセスをデバッグできます。

デバッグ出力には、実行された最終的な,SQL問合せが表示されます。それにより、カスタム・フィルタと内部フィルタがどのように適用されたかを確認できます。

デバッグ出力においては、内部フィルタとプロジェクト(またはカスタム)フィルタとでは、異なるコメントが付けられています。これは、各フィルタが最終的な問合せにどのように影響しているかを正確に確認するために役立ちます。

例6-7 デバッグ出力における内部フィルタ

and (Dba_objects.secondary = 'N') --<-- sqlcl internal.fixed.filters

例6-8 デバッグ出力におけるプロジェクト・フィルタ

and (not (object_type = 'VIEW' and object_name ='DATABASECHANGELOG_DETAILS')) --<-- project.filters

6.4.6 一般的なユースケース

ここでは、フィルタを使用してエクスポートを絞り込む方法の、実際の例をいくつか示します。

開発専用オブジェクトの除外

開発環境では、テスト用の一時的なオブジェクトを作成する場合があります。本番環境向けのエクスポートにこれらが含まれないようにするために、ネーミング規則(DEV_ONLY_接頭辞の使用など)を採用します。

その後、次のフィルタを適用して、そのようなオブジェクトを除外できます:

object_name NOT LIKE 'DEV_ONLY_%'

このフィルタを指定してproject exportコマンドを実行すると、DEV_ONLY_TEMP_TABLEなどのオブジェクトがエクスポートに含まれなくなって、それをクリーンな、本番環境向けに準備された状態にできます。

不要な権限付与のフィルタリング

utPLSQLなどのフレームワークを使用する場合、project exportコマンドでは、通常は、プロジェクト・ソースで必要ない可能性がある、フレームワークのスキーマ(UT3など)からのGRANT文が含まれます。

これらの権限付与を除外するには、grantor列でフィルタを定義します:

grantor != 'UT3'

このフィルタを指定してproject exportコマンドを実行すると、UT3ユーザーからの権限付与はすべて省略され、それらがsrc/databaseフォルダに書き込まれることがなくなります。