Disable all table constraints in Oracle

后端 未结 11 912
耶瑟儿~
耶瑟儿~ 2020-11-28 18:35

How can I disable all table constrains in Oracle with a single command? This can be either for a single table, a list of tables, or for all tables.

相关标签:
11条回答
  • 2020-11-28 18:54

    You can execute all the commands returned by the following query :

    select 'ALTER TABLE '||substr(c.table_name,1,35)|| ' DISABLE CONSTRAINT '||constraint_name||' ;' from user_constraints c --where c.table_name = 'TABLE_NAME' ;

    0 讨论(0)
  • 2020-11-28 18:59

    To take in count the dependencies between the constraints:

    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;
    /
    
    0 讨论(0)
  • 2020-11-28 19:03

    This is another way for disabling constraints (it came from https://asktom.oracle.com/pls/asktom/f?p=100:11:2402577774283132::::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;
    

    works like a charm

    0 讨论(0)
  • 2020-11-28 19:05
    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; 
    

    This statement returns the commands which turn off all the constraints including primary key, foreign keys, and another constraints.

    0 讨论(0)
  • 2020-11-28 19:07

    It is better to avoid writing out temporary spool files. Use a PL/SQL block. You can run this from SQL*Plus or put this thing into a package or procedure. The join to USER_TABLES is there to avoid view constraints.

    It's unlikely that you really want to disable all constraints (including NOT NULL, primary keys, etc). You should think about putting constraint_type in the WHERE clause.

    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;
    /
    

    Enabling the constraints again is a bit tricker - you need to enable primary key constraints before you can reference them in a foreign key constraint. This can be done using an ORDER BY on constraint_type. 'P' = primary key, 'R' = foreign key.

    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;
    /
    
    0 讨论(0)
提交回复
热议问题