按执行顺序显示过程中调用的所有过程名称

问题描述 投票:0回答:1

我有4个程序,pr_x是我的主要程序 并在

CREATE OR REPLACE NONEDITIONABLE PROCEDURE pr_X AS
    v_first_name VARCHAR2(100);
    pr_y(v_first_name);
    pr_z(v_first_name);

按顺序调用

CREATE OR REPLACE NONEDITIONABLE PROCEDURE pr_y AS
    v_first_name VARCHAR2(100);
    pr_t(v_first_name);


pr_t 在 pr_y 内部被调用。

我希望这些过程按其运行顺序显示,但我使用此代码得到以下结果。

WITH procedure_calls (called_procedure, depth) AS (
    SELECT 
        referenced_name AS called_procedure,
        1 AS depth
    FROM 
        all_dependencies
    WHERE 
        name = 'PR_X'
        AND type = 'PROCEDURE'
        AND referenced_type = 'PROCEDURE'
    UNION ALL
    SELECT 
        ad.referenced_name AS called_procedure,
        pc.depth + 1 AS depth
    FROM 
        all_dependencies ad
    INNER JOIN 
        procedure_calls pc ON ad.name = pc.called_procedure
    WHERE 
        ad.type = 'PROCEDURE'
        AND ad.referenced_type = 'PROCEDURE'
)
SELECT 
    called_procedure,
    depth,
    ROW_NUMBER() OVER (ORDER BY depth) AS execution_order
FROM 
    procedure_calls
WHERE 
    called_procedure LIKE 'PR%';

我尝试了这个解决方案,但不是我想要的

CALLED_PROCEDURE 深度 执行_订单
PR_Y 1 1
PR_Z 1 2
PR_T 2 3

我想要这个结果

CALLED_PROCEDURE 深度 执行_订单
PR_Y 1 1
PR_T 2 2
PR_Z 1 3
sql
1个回答
0
投票

甲骨文:
带有示例程序:

CREATE OR REPLACE NONEDITIONABLE PROCEDURE pr_t AS
BEGIN
    DBMS_OUTPUT.PUT_LINE('Function pr_t');
END pr_t;
--
CREATE OR REPLACE NONEDITIONABLE PROCEDURE pr_y AS
BEGIN
    DBMS_OUTPUT.PUT_LINE('Function pr_y');
    pr_t;
END pr_y;
--
CREATE OR REPLACE NONEDITIONABLE PROCEDURE pr_z AS
BEGIN
    DBMS_OUTPUT.PUT_LINE('Function pr_z');
END pr_z;
--
CREATE OR REPLACE NONEDITIONABLE PROCEDURE pr_x AS
BEGIN
    DBMS_OUTPUT.PUT_LINE('Function pr_x');
    pr_y();
    pr_z();
END pr_x;

运行 pr_x 进行测试:

SET SERVEROUTPUT ON
Begin
    pr_x;
End;
/
/*  R e s u l t :
Function pr_x
Function pr_y
Function pr_t
Function pr_z

PL/SQL procedure successfully completed.        */

一种选择可能是使用递归 cte,就像问题中的那样:

WITH    
    procedure_calls ( OWNER, NAME, REFERENCED_NAME, REFERENCED_OWNER, SUB_REF, DEPTH, TYPE, REFERENCED_TYPE) AS 
      ( SELECT  ad.OWNER, ad.NAME, 
                ad.REFERENCED_NAME, REFERENCED_OWNER, 
                (Select REFERENCED_NAME From all_dependencies Where Name = ad.REFERENCED_NAME And OWNER = REFERENCED_OWNER) as SUB_REF, 
                0, ad.TYPE, ad.REFERENCED_TYPE
        FROM    all_dependencies ad
        WHERE   ad.NAME = 'PR_X' And ad.TYPE = 'PROCEDURE' And ad.REFERENCED_TYPE = 'PROCEDURE'
     UNION ALL
        Select  OWNER, NAME, REFERENCED_NAME, REFERENCED_OWNER, SUB_REF, DEPTH + 1, TYPE, REFERENCED_TYPE 
        From    procedure_calls
        Where   SUB_REF Is Not Null
      ) CYCLE NAME Set IS_LOOP To 'Y' Default 'N'
--    S Q L :
Select  Case When DEPTH = 0 Then REFERENCED_NAME Else SUB_REF End as PROC_NAME, 
        DEPTH + 1 as DEPTH, 
        Row_Number() Over(Order By NAME, SUB_REF ) "EXEC_ORDER"
From    procedure_calls
/*    R e s u l t : 
PROC_NAME  DEPTH EXEC_ORDER
---------  ----- ----------
PR_Y           1          1
PR_T           2          2
PR_Z           1          3  */
© www.soinside.com 2019 - 2024. All rights reserved.