我有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 |
甲骨文:
带有示例程序:
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 */