sql >> データベース >  >> RDS >> Oracle

Oracleパッケージ内の依存関係を見つける方法は?

    PL / Scopeを使用して、パッケージ内のプロシージャの呼び出しを次のように取得できます。

    alter session set plscope_settings = 'IDENTIFIERS:ALL';
    

    その後、パッケージを再コンパイルする場合は、ここで説明に基づいた簡単なアウトラインを使用します:

    create or replace package p42 as
      procedure a;
      procedure b;
      procedure c;
      procedure d;
      function f return number;
    end p42;
    /
    
    create or replace package body p42 as
    
      procedure a is
      begin
        b;
        c;
      end a;
    
      procedure b is
        n number;
      begin
        n := f;
      end b;
    
      procedure c is
        n number;
      begin
        n := f;
      end c;
    
      procedure d is
      begin
        null;
      end d;
    
      function f return number is
      begin
        return 42;
      end f;
    end p42;
    /
    

    次に、user_identifiersでさまざまな参照を確認できます 見る。ドキュメントの例を使用して概要を取得します:

    WITH v AS (
      SELECT    Line,
                Col,
                INITCAP(NAME) Name,
                LOWER(TYPE)   Type,
                LOWER(USAGE)  Usage,
                USAGE_ID,
                USAGE_CONTEXT_ID
        FROM USER_IDENTIFIERS
          WHERE Object_Name = 'P42'
            AND Object_Type = 'PACKAGE BODY'
    )
    SELECT RPAD(LPAD(' ', 2*(Level-1)) ||
                     Name, 20, '.')||' '||
                     RPAD(Type, 20)||
                     RPAD(Usage, 20)
                     IDENTIFIER_USAGE_CONTEXTS
      FROM v
      START WITH USAGE_CONTEXT_ID = 0
      CONNECT BY PRIOR USAGE_ID = USAGE_CONTEXT_ID
      ORDER SIBLINGS BY Line, Col
    /
    
    IDENTIFIER_USAGE_CONTEXTS                                   
    -------------------------------------------------------------
    P42................. package             definition          
      A................. procedure           definition          
        B............... procedure           call                
        C............... procedure           call                
      B................. procedure           definition          
        N............... variable            declaration         
          Number........ number datatype     reference           
        N............... variable            assignment          
          F............. function            call                
      C................. procedure           definition          
        N............... variable            declaration         
          Number........ number datatype     reference           
        N............... variable            assignment          
          F............. function            call                
      D................. procedure           definition          
      F................. function            definition          
        Number.......... number datatype     reference           
    

    必要なものに近づけるには、他のプロシージャ/関数を呼び出す各プロシージャ/関数の名前を見つけるための階層クエリが必要です。これは、割り当てステップ(たとえば、それらが発生した場所)には関心がないためです。

    >

    出発点として、次のことができます。

    select *
    from (
      select name, type, connect_by_root(name) as root_name,
        connect_by_root(type) as root_type, connect_by_isleaf as isleaf
      from user_identifiers
      start with object_type = 'PACKAGE BODY'
      and object_name = 'P42'
      and type in ('FUNCTION', 'PROCEDURE')
      and usage = 'DEFINITION'
      connect by object_type = prior object_type
      and object_name = prior object_name
      and usage_context_id = prior usage_id
    )
    where type in ('FUNCTION', 'PROCEDURE');
    
    NAME TYPE               ROOT_NAME ROOT_TYPE     ISLEAF
    ---- ------------------ --------- --------- ----------
    A    PROCEDURE          A         PROCEDURE          0
    B    PROCEDURE          A         PROCEDURE          1
    C    PROCEDURE          A         PROCEDURE          1
    B    PROCEDURE          B         PROCEDURE          0
    F    FUNCTION           B         PROCEDURE          1
    C    PROCEDURE          C         PROCEDURE          0
    F    FUNCTION           C         PROCEDURE          1
    D    PROCEDURE          D         PROCEDURE          1
    F    FUNCTION           F         FUNCTION           0
    

    次に、リーフノードをフィルタリングし、呼び出し元を結合します。

    select root_name, root_type,
      listagg(case when name = root_name then null else name end, ', ')
        within group (order by name) as callers
    from (
      select name, type, connect_by_root(name) as root_name,
        connect_by_root(type) as root_type, connect_by_isleaf as isleaf
      from user_identifiers
      start with object_type = 'PACKAGE BODY'
      and object_name = 'P42'
      and type in ('FUNCTION', 'PROCEDURE')
      and usage = 'DEFINITION'
      connect by object_type = prior object_type
      and object_name = prior object_name
      and usage_context_id = prior usage_id
    )
    where type in ('FUNCTION', 'PROCEDURE')
    and isleaf = 1
    group by root_name, root_type;
    
    ROOT_NAME ROOT_TYPE CALLERS            
    --------- --------- --------------------
    A         PROCEDURE B, C                
    B         PROCEDURE F                   
    C         PROCEDURE F                   
    D         PROCEDURE                     
    

    ただし、Fは表示されません;これを取得するために外部結合を追加できます:

    with ui as (
      select * from user_identifiers
      where object_type = 'PACKAGE BODY'
      and object_name = 'P42'
    ),
    calls as (
      select object_type, object_name, name, type, signature,
        connect_by_root(name) as root_name,
        connect_by_root(type) as root_type,
        connect_by_root(signature) as root_signature,
        connect_by_isleaf as isleaf
      from ui
      start with type in ('FUNCTION', 'PROCEDURE')
      and usage = 'DEFINITION'
      connect by usage_context_id = prior usage_id
      and prior usage != 'CALL'
    )
    select ui.name, ui.type,
      listagg(case when c.name = c.root_name then null else c.name end, ', ')
        within group (order by c.name) as callers
    from ui
    left join calls c on c.object_type = ui.object_type
    and c.object_name = ui.object_name
    and c.root_type = ui.type
    and c.root_name = ui.name
    and c.root_signature = ui.signature
    and c.type in ('FUNCTION', 'PROCEDURE')
    and c.isleaf = 1
    where ui.type in ('FUNCTION', 'PROCEDURE')
    and ui.usage = 'DEFINITION'
    group by ui.name, ui.type;
    
    NAME TYPE               CALLERS            
    ---- ------------------ --------------------
    A    PROCEDURE          B, C                
    B    PROCEDURE          F                   
    C    PROCEDURE          F                   
    D    PROCEDURE                              
    F    FUNCTION                               
    

    単純化できると確信しています...

    メイン/スレーブ/独立フラグを取得するのは少し難しいです。これらのそれぞれが何を意味するかを決定する必要があります(たとえば、メインには発信はあるが着信はない、独立には着信または発信がない、他のすべてをスレーブにする)、場合によってはさらに結合して問題を把握します。

    したがって、これは情報の一部を取得するための開始点であり、必要な形式で必要なすべての情報を取得するために探索することを示していることを願っています。




    1. 検索条件に「%」が含まれる「%」を使用したSQL「LIKE」クエリ

    2. MariaDBで英数字以外の文字のみを含む行を返す2つの方法

    3. SQL Server SHOWPLAN_ALL

    4. インスタンス間でのバックアップの監視