Analysieren Sie Objektabhängigkeiten für partielle Datenbankmigrationen von Oracle nach PostgreSQL - AWS Prescriptive Guidance

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Analysieren Sie Objektabhängigkeiten für partielle Datenbankmigrationen von Oracle nach PostgreSQL

anuradha chintha, Amazon Web Services

Übersicht

Dieses Muster beschreibt, wie wichtig es ist, Systemabhängigkeiten systematisch zu identifizieren und zu verwalten, wenn eine Oracle-Teildatenbank entweder zu Amazon Relational Database Service (Amazon RDS) oder Amazon Aurora PostgreSQL migriert wird. Bei einer teilweisen Migration wird nur eine Teilmenge der Datenbankobjekte und Daten aus der ursprünglichen Datenbank migriert, während die Quelldatenbank weiterhin Anwendungen betreibt und bereitstellt, die von nicht migrierten Komponenten abhängen

Sie müssen den Umfang der Migration ermitteln und analysieren, wenn es um umfangreiche Datenbanken geht, bei denen Anwendungen eng mit Upstream- und Downstream-Abhängigkeiten verknüpft sind. Um mit einer teilweisen Migration zu beginnen, müssen Sie die Bereichsobjekte identifizieren, darunter Tabellen, Trigger, Ansichten, gespeicherte Prozeduren, Funktionen und Pakete. Der Prozess zur Identifizierung des Bereichs folgt einem umfassenden Ansatz:

  • Bereichsobjekte der ersten Ebene werden durch direkte Verweise im Anwendungscode und kritische modulspezifische Jobs identifiziert.

  • Objekte der zweiten Ebene werden durch eine umfassende Abhängigkeitsanalyse abgeleitet.

Wenn Sie verstehen, wie verschiedene Teile Ihres Systems interagieren, können Sie die richtige Reihenfolge für das Verschieben von Datenbankkomponenten besser planen und das Risiko von Migrationsfehlern verringern. In der folgenden Tabelle sind verschiedene Arten der Abhängigkeitsanalyse aufgeführt.

Art der Analyse

Schwerpunktbereiche

Zweck

Objektabhängigkeiten

  • Tabellen

  • Ansichten

  • Gespeicherte Prozeduren

  • Funktionen

  • Auslöser

Identifiziert Beziehungen zwischen Datenbankobjekten und ihren hierarchischen Strukturen

Segmentieren Sie Abhängigkeiten

  • Schlüsselbeziehungen im Ausland

  • Primäre Schlüsselketten

  • Schemaübergreifende Referenzen

Ordnet Datenbeziehungen zu und wahrt die referenzielle Integrität

Sicherheitsabhängigkeiten

  • Benutzerberechtigungen

  • Rollenhierarchien

  • Objektberechtigung

Sorgt für eine ordnungsgemäße Zugriffskontrolle, Migration und Sicherheitswartung

Zugriffsmuster

  • Lesevorgänge

  • Schreibvorgänge

Ermittelt die Interaktionsmuster der Datenbank

Um die Konsistenz zwischen Quell- und Zielsystemen aufrechtzuerhalten, sollten Sie während der Übergangsphase Mechanismen zur Datensynchronisierung einrichten. Sie müssen auch den Anwendungscode und die Funktionen ändern, um die Datenverteilung sowohl in der Oracle-Quelldatenbank als auch in der PostgreSQL-Zieldatenbank zu handhaben.

Voraussetzungen und Einschränkungen

Voraussetzungen

  • Ein aktiver AWS-Konto

  • Eine Oracle-Datenbank (Quelle)

  • Ein Amazon RDS oder Amazon Aurora PostgreSQL (Ziel)

Produktversionen

  • Oracle 19c oder höher

  • PostgreSQL 16 oder höher

Architektur

Quelltechnologie-Stack

  • Oracle 19c oder höher

Zieltechnologie-Stack

  • Amazon RDS oder Amazon Aurora PostgreSQL

Zielarchitektur

Das folgende Diagramm zeigt den Migrationsprozess von einer lokalen Oracle-Datenbank zu Amazon RDS for Oracle, der Folgendes umfasst:

  • Identifizieren von Datenbankabhängigkeiten

  • Migrieren von Datenbankcode und Objekten mit AWS Schema Conversion Tool ()AWS SCT

  • Daten mit AWS Database Migration Service () migrieren AWS DMS

  • Replikation laufender Änderungen durch Change Data Capture (CDC) mithilfe von AWS DMS

Weitere Informationen finden Sie in der Dokumentation unter AWS Schema Conversion Tool Integrieren AWS Database Migration Service mit. AWS

Tools

AWS-Services

  • Amazon Relational Database Service (Amazon RDS) für Oracle unterstützt Sie bei der Einrichtung, dem Betrieb und der Skalierung einer relationalen Oracle-Datenbank in der. AWS Cloud

  • Amazon Aurora ist eine vollständig verwaltete relationale Datenbank-Engine, die für die Cloud entwickelt wurde und mit MySQL und PostgreSQL kompatibel ist.

  • AWS Schema Conversion Tool (AWS SCT) unterstützt heterogene Datenbankmigrationen, indem das Quelldatenbankschema und ein Großteil des benutzerdefinierten Codes automatisch in ein Format konvertiert werden, das mit der Zieldatenbank kompatibel ist.

  • AWS Database Migration Service (AWS DMS) unterstützt Sie bei der Migration von Datenspeichern in die AWS Cloud oder zwischen Kombinationen von Cloud- und lokalen Setups.

Andere Dienste

  • Oracle SQL Developer ist eine integrierte Entwicklungsumgebung, die die Entwicklung und Verwaltung von Oracle-Datenbanken sowohl in herkömmlichen als auch in Cloud-basierten Bereitstellungen vereinfacht. Für dieses Muster können Sie SQL*Plus verwenden.

Bewährte Methoden

Bewährte Methoden zur Bereitstellung und Migration einer Oracle-Datenbank finden Sie unter Bewährte Methoden für die Migration zu Amazon RDS for Oracle.

Epen

AufgabeBeschreibungErforderliche Fähigkeiten

Erstellen Sie eine Objekttabelle.

Identifizieren Sie Objekte, die für die Funktionalität der Anwendung unerlässlich sind, und erstellen Sie eine Tabelle mit dem NamenDEPENDENT_ANALYSIS_BASELINE. Fügen Sie der Tabelle Datensätze für jedes Objekt hinzu. Ein Beispiel finden Sie im Abschnitt Zusätzliche Informationen.

Dateningenieur, DBA

Erstellen Sie eine Datenbankprozedur.

Erstellen Sie eine gespeicherte Prozedur mit dem Namensp_object_dependency_analysis, um Objektabhängigkeiten in beide Richtungen (vorwärts und rückwärts) zu analysieren, indem Sie Daten aus der DBA_DEPENDENCIES Tabelle verwenden. Ein Beispiel finden Sie im Abschnitt Zusätzliche Informationen.

Dateningenieur, DBA

Führen Sie das Verfahren aus.

Führen Sie die Skripts auf jeder nachfolgenden Ebene aus, bis keine neuen Objektabhängigkeiten gefunden werden. Alle Abhängigkeiten und Ebenen werden in der DEPENDENT_ANALYSIS_BASELINE Tabelle gespeichert.

DBA, Dateningenieur
AufgabeBeschreibungErforderliche Fähigkeiten

Erstellen Sie eine Abhängigkeitstabelle.

Erstellen Sie eine Abhängigkeitstabelle auf Segmentebene mit dem Namen. REFERENTIAL_ANALYSIS_BASELINE Wenn alle Abhängigkeiten auf Objektebene erkannt wurden, überprüfen Sie die übergeordneten Tabellen von, DEPENDENT_ANALYSIS_BASELINE indem Sie die Tabelle abfragen. DBA_CONSTRAINT

Schließen Sie Abhängigkeiten aus, bei denen Baseline-Tabellen von anderen Tabellen referenziert werden. Beim Backfilling werden diese Beziehungen behandelt. Im Folgenden finden Sie ein Beispielskript:

CREATE TABLE REFERENTIAL_ANALYSIS_BASELINE (CHILD_OWNER VARCHAR2(50 BYTE), CHILD_NAME VARCHAR2(100 BYTE), PARENT_OWNER VARCHAR2(50 BYTE), PARENT_NAME VARCHAR2(50 BYTE), REFERENCE_PATH VARCHAR2(1000 BYTE));
Dateningenieur, DBA

Erstellen Sie eine Datenbankprozedur.

Erstellen Sie eine Prozedur namens SP_OBJECT_REFERENTIAL_ANALYSIS und generieren Sie eine Referenzanalyse für alle identifizierten Objekte. Ein Beispiel finden Sie im Abschnitt Zusätzliche Informationen.

Dateningenieur, DBA

Führen Sie das Verfahren aus.

Führen Sie die Prozedur aus, um referenzielle Abhängigkeiten abzurufen. Generieren Sie Objektdetails für die referenzielle Analyse in. REFERENTIAL_ANALYSIS_BASELINE

Dateningenieur, DBA
AufgabeBeschreibungErforderliche Fähigkeiten

Erstellen Sie Tabellen für Lese- und Schreibobjekte.

Verwenden Sie das folgende Skript, um eine Lese-Objekttabelle mit dem Namen TABLE_READ_OBJECT_DETAILS und eine Schreibobjekttabelle mit dem Namen zu erstellenTABLE_WRITE_OBJECT_DETAILS:

CREATE TABLE TABLE_READ_OBJECT_DETAILS (OWNER VARCHAR2(50 BYTE), TAB_NAME VARCHAR2(50 BYTE), READER_OWNER VARCHAR2(50 BYTE), READER_NAME VARCHAR2(50 BYTE), READER_TYPE VARCHAR2(50 BYTE));
CREATE TABLE TABLE_WRITE_OBJECT_DETAILS (TABLE_NAME VARCHAR2(100 BYTE), WRITEOBJ_OWNER VARCHAR2(100 BYTE), WRITEOBJ_NAME VARCHAR2(100 BYTE), WRITEOBJ_TYPE VARCHAR2(100 BYTE), LINE VARCHAR2(100 BYTE), TEXT VARCHAR2(4000 BYTE), OWNER VARCHAR2(50 BYTE));
Dateningenieur, DBA

Erstellen Sie ein Verfahren für die Analyse.

Erstellen Sie die SP_READER_OBJECTS_ANALYSIS Prozeduren SP_WRITER_OBJECTS_ANALYSIS für die Analyse von Leseobjekten bzw. Schreibobjekten. Diese Verfahren verwenden Musterabgleich, um verwandte Objekte zu finden. Ein Beispiel finden Sie im Abschnitt Zusätzliche Informationen.

Dateningenieur, DBA

Führen Sie die Prozeduren aus.

Führen Sie diese Verfahren aus, um abhängige Objekte zu identifizieren.

DBA, Dateningenieur
AufgabeBeschreibungErforderliche Fähigkeiten

Erstellen Sie eine Tabelle zur Überprüfung der Rechte.

Erstellen Sie eine Tabelle zur Analyse der genannten RechteOBJECT_PRIVS_ANALYSIS. Verwenden Sie das folgende Skript, um Objektberechtigungen in der DEPENDENT_ANALYSIS_BASELINE Tabelle rekursiv zu erfassen:

CREATE TABLE OBJECT_PRIVS_ANALYSIS (OWNER VARCHAR2(50 BYTE), OBJECT_NAME VARCHAR2(50 BYTE), USER_NAME VARCHAR2(50 BYTE), PRIVS VARCHAR2(50 BYTE));
Dateningenieur, DBA

Erstellen Sie ein Verfahren zur Überprüfung von Rechten.

Erstellen Sie eine Prozedur mit dem NamenSP_OBJECT_PRIVS_ANALYSIS. Generieren Sie eine Rechteanalyse für identifizierte Objekte. Ein Beispiel finden Sie im Abschnitt Zusätzliche Informationen.

DBA, Dateningenieur

Führen Sie das Verfahren aus.

Führen Sie die Prozedur aus, um sie in der OBJECT_PRIVS_ANALYSIS Tabelle zu erfassen.

DBA, Dateningenieur

Fehlersuche

ProblemLösung

Auf Wörterbuchtabellen kann nicht zugegriffen werden

Stellen Sie sicher, dass der Benutzer, der die Analyseobjekte erstellt hat, auf die DBA-Tabellen zugreifen kann.

Zugehörige Ressourcen

AWS-Dokumentation

Andere Dokumentation

Zusätzliche Informationen

Skript für DEPENDENT_ANALYSIS_BASELINE

CREATE TABLE DEPENDENT_ANALYSIS_BASELINE (OWNER VARCHAR2(128 BYTE) NOT NULL ENABLE, OBJECT_NAME VARCHAR2(128 BYTE) NOT NULL ENABLE, OBJECT_TYPE VARCHAR2(20 BYTE), DEPEDNCY_LEVEL NUMBER, PROJECT_NEED VARCHAR2(20 BYTE), CATAGORY VARCHAR2(4000 BYTE), COMMENTS VARCHAR2(4000 BYTE), CATAGORY1 CLOB, COMMENTS1 CLOB, CUSTOMER_COMMENTS VARCHAR2(1000 BYTE), BACKFILL_TO_GUS VARCHAR2(1000 BYTE), BACKFILL_NEAR_REAL_TIME_OR_BATCH VARCHAR2(1000 BYTE), PK_EXISTS VARCHAR2(3 BYTE), UI_EXISTS VARCHAR2(3 BYTE), LOB_EXISTS VARCHAR2(3 BYTE), MASTER_LINK VARCHAR2(100 BYTE), CONSTRAINT PK_DEPENDENT_ANALYSIS_BASELINE PRIMARY KEY (OWNER,OBJECT_NAME,OBJECT_TYPE));

Verfahren für SP_WRITER_OBJECTS_ANALYSIS

CREATE OR REPLACE PROCEDURE SP_WRITER_OBJECTS_ANALYSIS IS BEGIN EXECUTE IMMEDIATE 'TRUNCATE TABLE TABLE_WRITE_OBJECT_DETAILS'; FOR I IN (SELECT OWNER, OBJECT_NAME FROM DEPENDENT_ANALYSIS_BASELINE WHERE OBJECT_TYPE = 'TABLE') LOOP INSERT INTO TABLE_WRITE_OBJECT_DETAILS(OWNER, TABLE_NAME, WRITEOBJ_OWNER, WRITEOBJ_NAME, WRITEOBJ_TYPE, LINE, TEXT) SELECT DISTINCT I.OWNER, I.OBJECT_NAME, OWNER WRITEOBJ_OWNER, NAME, TYPE, LINE, TRIM(TEXT) FROM DBA_SOURCE WHERE UPPER(TEXT) LIKE '%' || I.OBJECT_NAME || '%' AND (UPPER(TEXT) LIKE '%INSERT%' || I.OBJECT_NAME || '%' OR UPPER(TEXT) LIKE '%UPDATE%' || I.OBJECT_NAME || '%' OR UPPER(TEXT) LIKE '%DELETE%' || I.OBJECT_NAME || '%' OR UPPER(TEXT) LIKE '%UPSERT%' || I.OBJECT_NAME || '%' OR UPPER(TEXT) LIKE '%MERGE%' || I.OBJECT_NAME || '%') AND UPPER(TEXT) NOT LIKE '%PROCEDURE%' AND UPPER(TEXT) NOT LIKE 'PROCEDURE%' AND UPPER(TEXT) NOT LIKE '%FUNCTION%' AND UPPER(TEXT) NOT LIKE 'FUNCTION%' AND UPPER(TEXT) NOT LIKE '%TRIGGER%' AND UPPER(TEXT) NOT LIKE 'TRIGGER%' AND UPPER(TRIM(TEXT)) NOT LIKE '%AFTER UPDATE%' AND UPPER(TRIM(TEXT)) NOT LIKE 'BEFORE UPDATE%' AND UPPER(TRIM(TEXT)) NOT LIKE 'BEFORE INSERT%' AND UPPER(TRIM(TEXT)) NOT LIKE 'AFTER INSERT%' AND UPPER(TRIM(TEXT)) NOT LIKE 'BEFORE DELETE%' AND UPPER(TRIM(TEXT)) NOT LIKE 'AFTER DELETE%' AND UPPER(TRIM(TEXT)) NOT LIKE '%GGLOGADM.GG_LOG_ERROR%' AND (TRIM(TEXT) NOT LIKE '/*%' AND TRIM(TEXT) NOT LIKE '--%' ) AND (OWNER, NAME, TYPE) IN (SELECT OWNER, NAME, TYPE FROM DBA_DEPENDENCIES WHERE REFERENCED_NAME = I.OBJECT_NAME); END LOOP; END;

Skript für SP_READER_OBJECTS_ANALYSIS

CREATE OR REPLACE PROCEDURE SP_READER_OBJECTS_ANALYSIS IS BEGIN EXECUTE IMMEDIATE 'TRUNCATE TABLE TABLE_READ_OBJECT_DETAILS'; FOR I IN (SELECT OWNER, OBJECT_NAME FROM DEPENDENT_ANALYSIS_BASELINE WHERE OBJECT_TYPE = 'TABLE') LOOP INSERT INTO TABLE_READ_OBJECT_DETAILS SELECT DISTINCT i.owner, i.object_name, owner, name, type FROM dba_dependencies WHERE referenced_name = I.OBJECT_NAME AND referenced_type = 'TABLE' AND type NOT IN ('SYNONYM', 'MATERIALIZED VIEW', 'VIEW') AND (owner, name, type) NOT IN ( SELECT DISTINCT owner, trigger_name, 'TRIGGER' FROM dba_triggers WHERE table_name = I.OBJECT_NAME AND table_owner = i.owner UNION ALL SELECT DISTINCT owner, name, type FROM dba_source WHERE upper(text) LIKE '%' || I.OBJECT_NAME || '%' AND (upper(text) LIKE '%INSERT %' || I.OBJECT_NAME || '%' OR upper(text) LIKE '%UPDATE% ' || I.OBJECT_NAME || '%' OR upper(text) LIKE '%DELETE %' || I.OBJECT_NAME || '%' OR upper(text) LIKE '%UPSERT %' || I.OBJECT_NAME || '%' OR upper(text) LIKE '%MERGE %' || I.OBJECT_NAME || '%') AND upper(text) NOT LIKE '%PROCEDURE %' AND upper(text) NOT LIKE 'PROCEDURE %' AND upper(text) NOT LIKE '%FUNCTION %' AND upper(text) NOT LIKE 'FUNCTION %' AND upper(text) NOT LIKE '%TRIGGER %' AND upper(text) NOT LIKE 'TRIGGER %' AND upper(trim(text)) NOT LIKE 'BEFORE INSERT %' AND upper(trim(text)) NOT LIKE 'BEFORE UPDATE %' AND upper(trim(text)) NOT LIKE 'BEFORE DELETE %' AND upper(trim(text)) NOT LIKE 'AFTER INSERT %' AND upper(trim(text)) NOT LIKE 'AFTER UPDATE %' AND upper(trim(text)) NOT LIKE 'AFTER DELETE %' AND (trim(text) NOT LIKE '/*%' AND trim(text) NOT LIKE '--%')); END LOOP; END;

Drehbuch für SP_OBJECT_REFERENTIAL_ANALYSIS

CREATE OR REPLACE PROCEDURE SP_OBJECT_REFERENTIAL_ANALYSIS IS BEGIN EXECUTE IMMEDIATE 'TRUNCATE TABLE REFERENTIAL_ANALYSIS_BASELINE'; INSERT INTO REFERENTIAL_ANALYSIS_BASELINE WITH rel AS ( SELECT DISTINCT c.owner, c.table_name, c.r_owner r_owner, (SELECT table_name FROM dba_constraints WHERE constraint_name = c.r_constraint_name AND owner = c.r_owner) r_table_name FROM dba_constraints c WHERE constraint_type = 'R' AND c.owner NOT IN (SELECT username FROM dba_users WHERE oracle_maintained = 'Y') AND c.r_owner NOT IN (SELECT username FROM dba_users WHERE oracle_maintained = 'Y')), tab_list AS ( SELECT OWNER, object_name FROM DEPENDENT_ANALYSIS_BASELINE WHERE UPPER(OBJECT_TYPE) = 'TABLE') SELECT DISTINCT owner child_owner, table_name child, r_owner parent_owner, r_table_name parent, SYS_CONNECT_BY_PATH(r_table_name, ' -> ') || ' -> ' || table_name PATH FROM rel START WITH (r_owner, r_table_name) IN (SELECT * FROM tab_list) CONNECT BY NOCYCLE (r_owner, r_table_name) = ((PRIOR owner, PRIOR table_name)) UNION SELECT DISTINCT owner child_owner, table_name child, r_owner parent_owner, r_table_name parent, SYS_CONNECT_BY_PATH(table_name, ' -> ') || ' -> ' || r_table_name PATH FROM rel START WITH (owner, table_name) IN (SELECT * FROM tab_list) CONNECT BY NOCYCLE (owner, table_name) = ((PRIOR r_owner, PRIOR r_table_name)); END;

Drehbuch für SP_OBJECT_PRIVS_ANALYSIS

CREATE OR REPLACE PROCEDURE SP_OBJECT_PRIVS_ANALYSIS IS V_SQL VARCHAR2(4000); V_CNT NUMBER; BEGIN V_SQL := 'TRUNCATE TABLE OBJECT_PRIVS_ANALYSIS'; EXECUTE IMMEDIATE V_SQL; FOR I IN (SELECT OWNER, OBJECT_NAME FROM DEPENDENT_ANALYSIS_BASELINE WHERE OBJECT_TYPE = 'TABLE') LOOP INSERT INTO OBJECT_PRIVS_ANALYSIS(OWNER, OBJECT_NAME, USER_NAME, PRIVS) WITH obj_to_role AS ( SELECT DISTINCT GRANTEE role_name, DECODE(privilege, 'SELECT', 'READ', 'REFERENCE', 'READ', 'INSERT', 'WRITE', 'UPDATE', 'WRITE', 'DELETE', 'WRITE', privilege) privs FROM DBA_TAB_PRIVS t, DBA_ROLES r WHERE OWNER = I.OWNER AND TYPE = 'TABLE' AND TABLE_NAME = I.OBJECT_NAME AND t.GRANTEE = r.ROLE AND r.ROLE IN (SELECT ROLE FROM DBA_ROLES WHERE ORACLE_MAINTAINED = 'N') ) SELECT I.OWNER, I.OBJECT_NAME, grantee, privs FROM ( -- Recursively Role to User mapping with privilege SELECT DISTINCT grantee, privs FROM (SELECT rp.granted_role, rp.grantee, privs, (SELECT DECODE(COUNT(*), 0, 'ROLE', 'USER') FROM (SELECT 'User' FROM DBA_users WHERE username = rp.GRANTEE)) grantee_type FROM DBA_role_privs rp, obj_to_role r WHERE rp.granted_role = r.role_name AND grantee IN ((SELECT USERNAME FROM DBA_USERS WHERE ORACLE_MAINTAINED = 'N') UNION (SELECT ROLE FROM DBA_ROLES WHERE ORACLE_MAINTAINED = 'N')) AND granted_role IN (SELECT ROLE FROM DBA_ROLES WHERE ORACLE_MAINTAINED = 'N') START WITH granted_role IN (SELECT DISTINCT role_name FROM obj_to_role) CONNECT BY granted_role = PRIOR grantee) WHERE grantee_type = 'USER' ) UNION ( -- Direct Object grants to User SELECT I.OWNER, I.OBJECT_NAME, GRANTEE, DECODE(privilege, 'SELECT', 'READ', 'REFERENCE', 'READ', 'INSERT', 'WRITE', 'UPDATE', 'WRITE', 'DELETE', 'WRITE', privilege) privs FROM DBA_TAB_PRIVS, DBA_USERS WHERE GRANTEE = USERNAME AND OWNER = I.OWNER AND TYPE = 'TABLE' AND TABLE_NAME = I.OBJECT_NAME ) ORDER BY 2 DESC; END LOOP; END;

Verfahren für SP_OBJECT_DEPENDENCY_ANALYSIS

CREATE OR REPLACE PROCEDURE SP_OBJECT_DEPENDENCY_ANALYSIS (v_level NUMBER) IS TYPE typ IS RECORD ( schema VARCHAR2(100), obj_type VARCHAR2(100), obj_name VARCHAR2(100), path VARCHAR2(5000) ); TYPE array IS TABLE OF typ; l_data array; c SYS_REFCURSOR; l_errors NUMBER; l_errno NUMBER; l_msg VARCHAR2(4000); l_idx NUMBER; l_level NUMBER; BEGIN l_level := v_level + 1; OPEN c FOR WITH obj_list AS ( SELECT owner schema_name, object_type, object_name FROM DEPENDENT_ANALYSIS_BASELINE WHERE depedncy_level = v_level ), fw_dep_objects AS ( SELECT level lvl, owner, name, type, referenced_owner, referenced_name, referenced_type, SYS_CONNECT_BY_PATH(name, ' -> ') || ' -> ' || referenced_name PATH FROM dba_dependencies START WITH (owner, CASE WHEN type = 'PACKAGE BODY' THEN 'PACKAGE' ELSE type END, name) IN (SELECT schema_name, object_type, object_name FROM obj_list) CONNECT BY NOCYCLE (owner, type, name) = ((PRIOR referenced_owner, PRIOR referenced_type, PRIOR referenced_name)) ), bw_dep_objects AS ( SELECT level lvl, owner, name, type, referenced_owner, referenced_name, referenced_type, SYS_CONNECT_BY_PATH(name, ' <- ') || ' <- ' || referenced_name PATH FROM dba_dependencies START WITH (referenced_owner, CASE WHEN referenced_type = 'PACKAGE BODY' THEN 'PACKAGE' ELSE referenced_type END, referenced_name) IN (SELECT schema_name, object_type, object_name FROM obj_list) CONNECT BY NOCYCLE (referenced_owner, referenced_type, referenced_name) = ((PRIOR owner, PRIOR type, PRIOR name)) ) SELECT * FROM ( (SELECT DISTINCT referenced_owner schema, referenced_type obj_type, referenced_name obj_name, path FROM fw_dep_objects) UNION (SELECT DISTINCT owner schema, type obj_type, name obj_name, path FROM bw_dep_objects) ) WHERE schema IN (SELECT username FROM all_users WHERE oracle_maintained = 'N') ORDER BY obj_type; LOOP FETCH c BULK COLLECT INTO l_data LIMIT 100; BEGIN FORALL i IN 1..l_data.count SAVE EXCEPTIONS INSERT INTO DEPENDENT_ANALYSIS_BASELINE ( owner, object_name, object_type, catagory, depedncy_level, project_need, comments ) VALUES ( l_data(i).schema, l_data(i).obj_name, CASE WHEN l_data(i).obj_type = 'PACKAGE BODY' THEN 'PACKAGE' ELSE l_data(i).obj_type END, 'level ' || l_level || ' dependency', l_level, '', 'from dependency proc' || l_data(i).path ); EXCEPTION WHEN OTHERS THEN l_errors := sql%bulk_exceptions.count; FOR i IN 1..l_errors LOOP l_errno := sql%bulk_exceptions(i).error_code; l_msg := SQLERRM(-l_errno); l_idx := sql%bulk_exceptions(i).error_index; UPDATE DEPENDENT_ANALYSIS_BASELINE SET catagory1 = catagory1 || ', found in level' || l_level || ' dependent of ' || l_data(l_idx).path, comments1 = comments1 || ', from dependency proc exception ' || l_data(i).path WHERE owner = l_data(l_idx).schema AND object_name = l_data(l_idx).obj_name AND object_type = l_data(l_idx).obj_type; END LOOP; END; EXIT WHEN c%NOTFOUND; END LOOP; CLOSE c; END;