

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
<a name="multilevel-object-analysis-for-database-migration-from-oracle-to-postgresql"></a>

*anuradha chintha, Amazon Web Services*

## Zusammenfassung
<a name="multilevel-object-analysis-for-database-migration-from-oracle-to-postgresql-summary"></a>

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 | TabellenAnsichtenGespeicherte ProzedurenFunktionenAuslöser | Identifiziert Beziehungen zwischen Datenbankobjekten und ihren hierarchischen Strukturen | 
| Segmentieren Sie Abhängigkeiten | Schlüsselbeziehungen im AuslandPrimäre SchlüsselkettenSchemaübergreifende Referenzen | Ordnet Datenbeziehungen zu und wahrt die referenzielle Integrität | 
| Sicherheitsabhängigkeiten | BenutzerberechtigungenRollenhierarchienObjektberechtigung | Sorgt für eine ordnungsgemäße Zugriffskontrolle, Migration und Sicherheitswartung | 
| Zugriffsmuster | LesevorgängeSchreibvorgä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
<a name="multilevel-object-analysis-for-database-migration-from-oracle-to-postgresql-prereqs"></a>

**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
<a name="multilevel-object-analysis-for-database-migration-from-oracle-to-postgresql-architecture"></a>

**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](https://docs.aws.amazon.com/SchemaConversionTool/latest/userguide/CHAP_DMSIntegration.html). AWS 

![](http://docs.aws.amazon.com/de_de/prescriptive-guidance/latest/patterns/images/pattern-img/90160825-3199-4382-95a8-ad63139c5c89/images/b09c36a4-27fa-412e-877e-57a31bcce0dc.png)


## Tools
<a name="multilevel-object-analysis-for-database-migration-from-oracle-to-postgresql-tools"></a>

**AWS-Services**
+ [Amazon Relational Database Service (Amazon RDS)](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Oracle.html) 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)](https://docs.aws.amazon.com/dms/latest/userguide/Welcome.html) 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](https://www.oracle.com/database/technologies/appdev/sqldeveloper-landing.html) 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](https://docs.oracle.com/cd/B19306_01/server.102/b14357/qstart.htm) verwenden.

## Best Practices
<a name="multilevel-object-analysis-for-database-migration-from-oracle-to-postgresql-best-practices"></a>

Bewährte Methoden zur Bereitstellung und Migration einer Oracle-Datenbank finden Sie unter [Bewährte Methoden für die Migration zu Amazon RDS](https://docs.aws.amazon.com/prescriptive-guidance/latest/migration-oracle-database/best-practices.html) for Oracle.

## Epen
<a name="multilevel-object-analysis-for-database-migration-from-oracle-to-postgresql-epics"></a>

### Identifizieren Sie Objektabhängigkeiten
<a name="identify-object-dependencies"></a>


| Aufgabe | Description | Erforderliche 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 Namen`DEPENDENT_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 Namen`sp_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 | 

### Erstellen Sie ein Verfahren für Abhängigkeiten auf Segmentebene
<a name="create-a-procedure-for-segment-level-dependencies"></a>


| Aufgabe | Description | Erforderliche 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`<br />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:<pre>CREATE TABLE REFERENTIAL_ANALYSIS_BASELINE<br />(CHILD_OWNER VARCHAR2(50 BYTE),<br />CHILD_NAME VARCHAR2(100 BYTE),<br />PARENT_OWNER VARCHAR2(50 BYTE),<br />PARENT_NAME VARCHAR2(50 BYTE),<br />REFERENCE_PATH VARCHAR2(1000 BYTE));</pre> | 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 | 

### Identifizieren Sie Objekte, die lesen und schreiben
<a name="identify-objects-that-read-and-write"></a>


| Aufgabe | Description | Erforderliche 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 erstellen`TABLE_WRITE_OBJECT_DETAILS`:<pre>CREATE TABLE TABLE_READ_OBJECT_DETAILS<br />(OWNER VARCHAR2(50 BYTE),<br />TAB_NAME VARCHAR2(50 BYTE),<br />READER_OWNER VARCHAR2(50 BYTE),<br />READER_NAME VARCHAR2(50 BYTE),<br />READER_TYPE VARCHAR2(50 BYTE));</pre><pre>CREATE TABLE TABLE_WRITE_OBJECT_DETAILS<br />(TABLE_NAME VARCHAR2(100 BYTE),<br />WRITEOBJ_OWNER VARCHAR2(100 BYTE),<br />WRITEOBJ_NAME VARCHAR2(100 BYTE),<br />WRITEOBJ_TYPE VARCHAR2(100 BYTE),<br />LINE VARCHAR2(100 BYTE),<br />TEXT VARCHAR2(4000 BYTE),<br />OWNER VARCHAR2(50 BYTE));</pre> | Dateningenieur, DBA | 
| Erstellen Sie ein Analyseverfahren. | 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 Verfahren aus. | Führen Sie diese Verfahren aus, um abhängige Objekte zu identifizieren. | DBA, Dateningenieur | 

### Überprüfen Sie die Datenbankberechtigungen
<a name="review-database-privileges"></a>


| Aufgabe | Description | Erforderliche Fähigkeiten | 
| --- | --- | --- | 
| Erstellen Sie eine Tabelle zur Überprüfung der Rechte. | Erstellen Sie eine Tabelle zur Analyse der genannten Rechte`OBJECT_PRIVS_ANALYSIS`. Verwenden Sie das folgende Skript, um Objektberechtigungen in der `DEPENDENT_ANALYSIS_BASELINE` Tabelle rekursiv zu erfassen:<pre>CREATE TABLE OBJECT_PRIVS_ANALYSIS<br />(OWNER VARCHAR2(50 BYTE),<br />OBJECT_NAME VARCHAR2(50 BYTE),<br />USER_NAME VARCHAR2(50 BYTE),<br />PRIVS VARCHAR2(50 BYTE));</pre> | Dateningenieur, DBA | 
| Erstellen Sie ein Verfahren zur Überprüfung von Rechten. | Erstellen Sie eine Prozedur mit dem Namen`SP_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 | 

## Fehlerbehebung
<a name="multilevel-object-analysis-for-database-migration-from-oracle-to-postgresql-troubleshooting"></a>


| Problem | Lö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
<a name="multilevel-object-analysis-for-database-migration-from-oracle-to-postgresql-resources"></a>

**AWS-Dokumentation**
+ [Dokumentation zu Amazon RDS und Aurora](https://docs.aws.amazon.com/rds/)
+ [Leitfaden für die Migration von Oracle Database 19c zu Amazon Aurora PostgreSQL](https://docs.aws.amazon.com/dms/latest/oracle-to-aurora-postgresql-migration-playbook/chap-oracle-aurora-pg.html)
+ [AWS Database Migration Service Was ist?](https://docs.aws.amazon.com/dms/latest/userguide/)
+ [Was ist das AWS Schema Conversion Tool?](https://docs.aws.amazon.com/SchemaConversionTool/latest/userguide/)

**Andere Dokumentation**
+ [Oracle-Datenbankobjekte](https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/Database-Objects.html)

## Zusätzliche Informationen
<a name="multilevel-object-analysis-for-database-migration-from-oracle-to-postgresql-additional"></a>

**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;
```