这是我很久以前编写的一个大型 pl/sql 程序,旨在遍历员工/老板报告树一直到顶部(CEO)。这个版本是 Peoplesoft 特有的,但只要您阅读的内容在记录中具有父/子关系,它就可以处理任何事情......我还有其他更动态的版本,但这可能是最容易破译的。我删除了一些你不会关心的绒毛东西。此外,由于报告工具可以使用它,因此该特定解决方案会出于许多不同原因将其交付给表格...
此外,它动态确定级别,因此您不必像使用连接解决方案那样知道有多少级别。
希望能帮助到你:
CREATE OR REPLACE PROCEDURE DW."SPW_T_RESOURCE_HIERARCHY" (iCommit In Integer Default 1000,
pdBegin In Date Default trunc(Sysdate) - 3,
pdEnd In Date Default trunc(Sysdate) + 1,
vTruncate In Varchar2 Default 'Y' ) Is
------------------------------------------------------
-- DECLARATIONS
------------------------------------------------------
Cursor curDataSource Is
---**********************************----
---****BEGIN CUSTOMIZE THIS BLOCK****----
---**********************************----
Select
Eh.empl_id F_DESCENDANT_ID
,Eh.Super_Empl_Id F_IMMEDIATE_ANCESTOR_ID
From
Employee_Header EH
Where
EH.SUPER_EMPL_ID IS NOT NULL OR EH.TERM_DATE IS NULL;
---**********************************----
---****END CUSTOMIZE THIS BLOCK******----
---**********************************----
dNow Date := Sysdate;
iTotalRows Integer := 0;
iTotalErrors Integer := 0;
---**********************************----
---****BEGIN CUSTOMIZE THIS BLOCK****----
---**********************************----
vDescendentID Varchar2(20);
iDescendentLevel Integer := 1;
iAncestorLevel Integer := 0;
vAncestorID Varchar2(20);
vTmpAncestorID Varchar2(20);
vTmpEmployeeID Varchar2(20);
---**********************************----
---****END CUSTOMIZE THIS BLOCK******----
---**********************************----
------------------------------------------------------
-- END DECLARATIONS
------------------------------------------------------
------------------------------------------------------
-- BEGIN MAIN
------------------------------------------------------
Begin
-- Loop over source records
For recDataSource In curDataSource
Loop
iDescendentLevel := 1;
vAncestorID := recDataSource.f_Immediate_Ancestor_Id;
-- Start Transaction
Begin
while (Trim(vAncestorID) is not null)
loop
Begin
-- Fetch Next Ancestor
Select EH.SUPER_EMPL_ID
Into vTmpAncestorID
From
EMPLOYEE_HEADER EH
Where
EH.EMPL_ID = vAncestorID;
Exception
When Others Then
vTmpAncestorID := null;
End;
If NVL(vTmpAncestorID,'-XYZ-') = NVL(vAncestorID,'-123-') Then
vTmpAncestorID := null;
End If;
vAncestorID := vTmpAncestorID;
iDescendentLevel := iDescendentLevel + 1;
end loop;
-- Insert Resource Base
Insert Into T_RESOURCE_HIERARCHY
(
T_RESOURCE_HIERARCHY.F_HIERARCHY_NAME,
T_RESOURCE_HIERARCHY.F_DESCENDANT_LEVEL,
T_RESOURCE_HIERARCHY.F_DESCENDANT_ID,
T_RESOURCE_HIERARCHY.F_ANCESTOR_LEVEL,
T_RESOURCE_HIERARCHY.F_ANCESTOR_ID
)
Values
(
'Physical Org Chart',
iDescendentLevel,
recDataSource.f_Descendant_Id,
To_Number(Decode(iDescendentLevel,1,2,iDescendentLevel) - 1),
NVL(recDataSource.f_Immediate_Ancestor_Id,'ROOT')
);
-- Insert MySelf Into Resource Base as well for full hierarchy research
Insert Into T_RESOURCE_HIERARCHY
(
T_RESOURCE_HIERARCHY.F_HIERARCHY_NAME,
T_RESOURCE_HIERARCHY.F_DESCENDANT_LEVEL,
T_RESOURCE_HIERARCHY.F_DESCENDANT_ID,
T_RESOURCE_HIERARCHY.F_ANCESTOR_LEVEL,
T_RESOURCE_HIERARCHY.F_ANCESTOR_ID
)
Values
(
'Physical Org Chart',
iDescendentLevel,
recDataSource.f_Descendant_Id,
iDescendentLevel,
NVL(recDataSource.f_Descendant_Id,'ROOT')
);
-- Now Its Time To Climb The Tree
-- For This Employee
vAncestorID := recDataSource.f_Immediate_Ancestor_Id;
iAncestorLevel := iDescendentLevel-1;
vTmpAncestorID := null;
-- Loop over parents
while (Trim(vAncestorID) is not null)
loop
Begin
-- Fetch Next Ancestor
Select EH.SUPER_EMPL_ID
Into vTmpAncestorID
From
EMPLOYEE_HEADER EH
Where
EH.EMPL_ID = vAncestorID;
Exception
When Others Then
vTmpAncestorID := null;
End;
If NVL(vTmpAncestorID,'-XYZ-') = '-XYZ-' Then
vTmpAncestorID := null;
End If;
vAncestorID := vTmpAncestorID;
iAncestorLevel := iAncestorLevel - 1;
If vAncestorID is not null Then
-- Insert Resource Base
Insert Into T_RESOURCE_HIERARCHY
(
T_RESOURCE_HIERARCHY.F_HIERARCHY_NAME,
T_RESOURCE_HIERARCHY.F_DESCENDANT_LEVEL,
T_RESOURCE_HIERARCHY.F_DESCENDANT_ID,
T_RESOURCE_HIERARCHY.F_ANCESTOR_LEVEL,
T_RESOURCE_HIERARCHY.F_ANCESTOR_ID
)
Values
(
'Physical Org Chart',
iDescendentLevel,
recDataSource.f_Descendant_Id,
iAncestorLevel,
vAncestorID
);
End If;
end loop;
-- TRANSACTION EXCEPTION HANDLING
Exception
When Others Then
End;
-- ASSIGN HOW MANY RECORDS PROCESSED
iTotalRows := curDataSource%Rowcount;
-- CONDITIONAL/INCREMENTAL TRANSACTION COMMIT
If Mod(iTotalRows, iCommit) = 0
Then
Commit;
End If;
End Loop;
-- FINAL COMMIT AND MD UPDATE
Commit;
-- MAIN EXCEPTION HANDLING
Exception
When Others Then
Begin
iExceptionCode := Sqlcode;
vExceptionMessage := Sqlerrm;
Raise_application_error(Sqlcode, Sqlerrm);
End;
------------------------------------------------------
-- END MAIN
------------------------------------------------------
End SPW_T_RESOURCE_HIERARCHY;
/