it-swarm.com.de

Deaktivieren Sie alle Tabelleneinschränkungen in Oracle

Wie kann ich alle Tabelleneinschränkungen in Oracle mit einem einzigen Befehl deaktivieren? Dies kann entweder für eine einzelne Tabelle, eine Liste von Tabellen oder für alle Tabellen gelten.

81
oneself

Es ist besser, das Schreiben von temporären Spooldateien zu vermeiden. Verwenden Sie einen PL/SQL-Block. Sie können dies von SQL * Plus aus ausführen oder dieses Objekt in ein Paket oder eine Prozedur einfügen. Der Join zu USER_TABLES dient dazu, Sichteinschränkungen zu vermeiden.

Es ist unwahrscheinlich, dass Sie wirklich alle Einschränkungen (einschließlich NOT NULL, Primärschlüssel usw.) deaktivieren möchten. Sie sollten darüber nachdenken, constraint_type in die WHERE-Klausel einzufügen.

BEGIN
  FOR c IN
  (SELECT c.owner, c.table_name, c.constraint_name
   FROM user_constraints c, user_tables t
   WHERE c.table_name = t.table_name
   AND c.status = 'ENABLED'
   AND NOT (t.iot_type IS NOT NULL AND c.constraint_type = 'P')
   ORDER BY c.constraint_type DESC)
  LOOP
    dbms_utility.exec_ddl_statement('alter table "' || c.owner || '"."' || c.table_name || '" disable constraint ' || c.constraint_name);
  END LOOP;
END;
/

Das erneute Aktivieren der Einschränkungen ist ein bisschen Trick - Sie müssen Primärschlüssel-Einschränkungen aktivieren, bevor Sie sie in einer Fremdschlüssel-Einschränkung referenzieren können. Dies kann mit einem ORDER BY für constraint_type durchgeführt werden. 'P' = Primärschlüssel, 'R' = Fremdschlüssel.

BEGIN
  FOR c IN
  (SELECT c.owner, c.table_name, c.constraint_name
   FROM user_constraints c, user_tables t
   WHERE c.table_name = t.table_name
   AND c.status = 'DISABLED'
   ORDER BY c.constraint_type)
  LOOP
    dbms_utility.exec_ddl_statement('alter table "' || c.owner || '"."' || c.table_name || '" enable constraint ' || c.constraint_name);
  END LOOP;
END;
/
129
WW.

Um die Abhängigkeiten zwischen den Einschränkungen zu berücksichtigen: 

SET Serveroutput ON
BEGIN
    FOR c IN
    (SELECT c.owner,c.table_name,c.constraint_name
    FROM user_constraints c,user_tables t
    WHERE c.table_name=t.table_name
    AND c.status='ENABLED'
    ORDER BY c.constraint_type DESC,c.last_change DESC
    )
    LOOP
        FOR D IN
        (SELECT P.Table_Name Parent_Table,C1.Table_Name Child_Table,C1.Owner,P.Constraint_Name Parent_Constraint,
            c1.constraint_name Child_Constraint
        FROM user_constraints p
        JOIN user_constraints c1 ON(p.constraint_name=c1.r_constraint_name)
        WHERE(p.constraint_type='P'
        OR p.constraint_type='U')
        AND c1.constraint_type='R'
        AND p.table_name=UPPER(c.table_name)
        )
        LOOP
            dbms_output.put_line('. Disable the constraint ' || d.Child_Constraint ||' (on table '||d.owner || '.' ||
            d.Child_Table || ')') ;
            dbms_utility.exec_ddl_statement('alter table ' || d.owner || '.' ||d.Child_Table || ' disable constraint ' ||
            d.Child_Constraint) ;
        END LOOP;
    END LOOP;
END;
/
9
Cyryl1972

Es ist kein einzelner Befehl, aber so mache ich es. Das folgende Skript wurde zur Ausführung in SQL * Plus entwickelt. Hinweis: Ich habe dies absichtlich so geschrieben, dass es nur im aktuellen Schema funktioniert.

set heading off

spool drop_constraints.out

select
    'alter table ' || 
    owner || '.' || 
    table_name || 
    ' disable constraint ' || -- or 'drop' if you want to permanently remove
    constraint_name || ';'
from
    user_constraints;

spool off

set heading on

@drop_constraints.out

Um das Löschen einzuschränken, fügen Sie der select-Anweisung eine where-Klausel hinzu: -

  • filter on constraint_type, um nur bestimmte Arten von Einschränkungen zu löschen
  • filtern Sie nach Tabellenname, um dies nur für eine oder wenige Tabellen zu tun.

Um mehr als das aktuelle Schema auszuführen, ändern Sie die select-Anweisung so, dass sie aus all_constraints anstelle von user_constraints auswählt.

Hinweis - Aus irgendeinem Grund kann ich den Unterstrich nicht dazu bringen, im vorherigen Absatz NICHT wie eine Kursivschrift zu wirken. Wenn jemand weiß, wie er das Problem beheben soll, können Sie diese Antwort gerne bearbeiten.

5
Mike McAllister

Verwenden Sie den folgenden Cursor, um alle Einschränkungen zu deaktivieren. Und ändern Sie die Abfrage für Aktivierungsbedingungen.

DECLARE

cursor r1 is select * from user_constraints;
cursor r2 is select * from user_tables;

BEGIN
  FOR c1 IN r1
  loop
    for c2 in r2
    loop
       if c1.table_name = c2.table_name and c1.status = 'ENABLED' THEN
        dbms_utility.exec_ddl_statement('alter table ' || c1.owner || '.' || c1.table_name || ' disable constraint ' || c1.constraint_name);
       end if;
    end loop;
  END LOOP;
END;
/
5
user486360

Dies kann in PL/SQL auf einfache Weise anhand der Systemansicht DBA/ALL/USER_CONSTRAINTS simuliert werden, aber verschiedene Details sind nicht so trivial, wie es klingt. Sie müssen auf die Reihenfolge achten, in der sie ausgeführt wird, und Sie müssen auch das Vorhandensein eindeutiger Indizes berücksichtigen.

Die Reihenfolge ist wichtig, da Sie keinen eindeutigen Schlüssel oder Primärschlüssel löschen können, auf den ein Fremdschlüssel verweist, und dass Fremdschlüssel in Tabellen in anderen Schemas vorhanden sein könnten, die auf Primärschlüssel in Ihrem eigenen Verzeichnis verweisen Diese PKs und UKs können nicht gelöscht werden. Außerdem können Sie einen eindeutigen Index nicht in einen nicht eindeutigen Index umwandeln. Daher müssen Sie ihn löschen, um die Einschränkung zu löschen. Aus diesem Grund ist es fast immer besser, eindeutige Einschränkungen als "echte" Einschränkung zu implementieren, die von einem nicht unterstützt wird -indeutiger Index).

4
David Aldridge

Im "disable" -Skript sollte die order by-Klausel Folgendes sein:

ORDER BY c.constraint_type DESC, c.last_change DESC

Das Ziel dieser Klausel ist das Deaktivieren der Einschränkungen in der richtigen Reihenfolge.

0
bpelhos

Dies ist eine andere Möglichkeit zum Deaktivieren von Einschränkungen (sie stammt aus https://asktom.Oracle.com/pls/asktom/f?p=100:11:240257777883232::::P11_QUESTION_ID:399218963817 )

WITH qry0 AS
       (SELECT    'ALTER TABLE '
               || child_tname
               || ' DISABLE CONSTRAINT '
               || child_cons_name
                 disable_fk
              ,   'ALTER TABLE '
               || parent_tname
               || ' DISABLE CONSTRAINT '
               || parent.parent_cons_name
                 disable_pk
          FROM (SELECT a.table_name child_tname
                      ,a.constraint_name child_cons_name
                      ,b.r_constraint_name parent_cons_name
                      ,LISTAGG ( column_name, ',') WITHIN GROUP (ORDER BY position) child_columns
                  FROM user_cons_columns a
                      ,user_constraints b
                 WHERE a.constraint_name = b.constraint_name AND b.constraint_type = 'R'
                GROUP BY a.table_name, a.constraint_name
                        ,b.r_constraint_name) child
              ,(SELECT a.constraint_name parent_cons_name
                      ,a.table_name parent_tname
                      ,LISTAGG ( column_name, ',') WITHIN GROUP (ORDER BY position) parent_columns
                  FROM user_cons_columns a
                      ,user_constraints b
                 WHERE a.constraint_name = b.constraint_name AND b.constraint_type IN ('P', 'U')
                GROUP BY a.table_name, a.constraint_name) parent
         WHERE child.parent_cons_name = parent.parent_cons_name
           AND (parent.parent_tname LIKE 'V2_%' OR child.child_tname LIKE 'V2_%'))
SELECT DISTINCT disable_pk
  FROM qry0
UNION
SELECT DISTINCT disable_fk
  FROM qry0;

klappt wunderbar

0
Cyryl1972

Sie können alle Befehle ausführen, die von der folgenden Abfrage zurückgegeben werden:

wählen Sie 'ALTER TABLE' || substr (c.table_name, 1,35) || ' DISABLE CONSTRAINT '|| constraint_name ||' ; ' aus user_constraints c -- wobei c.table_name = 'TABLE_NAME' ist;

0
Cristina Bazar

Es sieht nicht so aus, als könnten Sie dies mit einem einzigen Befehl tun, aber here ' ist das, was ich am nächsten finden könnte.

0
Adam Bellaire

mit Cursor für Schleife (user = 'TRANEE', table = 'D')

declare
    constr all_constraints.constraint_name%TYPE;
begin
    for constr in
        (select constraint_name from all_constraints
        where table_name = 'D'
        and owner = 'TRANEE')
    loop
        execute immediate 'alter table D disable constraint '||constr.constraint_name;
    end loop;
end;
/

(Wenn Sie deaktivieren, um zu aktivieren, können Sie alle Einschränkungen aktivieren.)

0
diaphol
SELECT 'ALTER TABLE '||substr(c.table_name,1,35)|| 
' DISABLE CONSTRAINT '||constraint_name||' ;' 
FROM user_constraints c, user_tables u 
WHERE c.table_name = u.table_name; 

Diese Anweisung gibt die Befehle zurück, die alle Einschränkungen, einschließlich Primärschlüssel, Fremdschlüssel und andere Einschränkungen, deaktivieren.

0
Ankireddy Polu