[sql] Oracle에서 모든 테이블 제약 조건 비활성화

단일 명령으로 Oracle의 모든 테이블 제한을 비활성화하려면 어떻게해야합니까? 이는 단일 테이블, 테이블 목록 또는 모든 테이블에 대한 것일 수 있습니다.



답변

임시 스풀 파일을 작성하지 않는 것이 좋습니다. PL / SQL 블록을 사용하십시오. SQL * Plus에서 실행하거나 패키지 나 프로 시저에 넣을 수 있습니다. USER_TABLES에 대한 조인은 뷰 제약을 피하기 위해 있습니다.

모든 제약 조건 (NOT NULL, 기본 키 등 포함)을 실제로 비활성화하고 싶지는 않습니다. WHERE 절에 constraint_type을 넣어야합니다.

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

제약 조건을 다시 활성화하는 것은 약간 까다 롭습니다. 외래 키 제약 조건에서 참조하려면 먼저 기본 키 제약 조건을 활성화해야합니다. constraint_type에서 ORDER BY를 사용하여 수행 할 수 있습니다. ‘P’= 기본 키, ‘R’= 외래 키.

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


답변

제약 조건 간의 종속성을 계산하려면 :

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


답변

단일 명령이 아니지만 여기에 내가 수행하는 방법이 있습니다. 다음 스크립트는 SQL * Plus에서 실행되도록 설계되었습니다. 참고로, 현재 스키마 내에서만 작동하도록 의도적으로 작성했습니다.

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

드롭하는 항목을 제한하려면 select 문에 where 절을 필터 추가합니다.

  • 특정 유형의 제약 조건 만 삭제하도록 constraint_type을 필터링합니다.
  • 하나 또는 몇 개의 테이블에 대해서만 수행하려면 table_name을 필터링하십시오.

현재 스키마 이상에서 실행하려면 user_constraints가 아닌 all_constraints에서 선택하도록 select 문을 수정합니다.

참고 -어떤 이유로 이전 단락에서 이탤릭체처럼 작동하지 않도록 밑줄을 표시 할 수 없습니다. 누군가가 그것을 고치는 방법을 알고 있다면이 답변을 자유롭게 편집하십시오.


답변

다음 커서를 사용하여 모든 제약 조건을 비활성화합니다. 그리고 제약 조건 활성화에 대한 쿼리를 변경합니다.

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


답변

이것은 DBA / ALL / USER_CONSTRAINTS 시스템 뷰를 기반으로 아주 간단하게 PL / SQL에서 스크립팅 할 수 있지만 다양한 세부 사항은 소리만큼 사소한 것은 아닙니다. 수행되는 순서에주의해야하며 고유 인덱스의 존재도 고려해야합니다.

외래 키가 참조하는 고유 키 또는 기본 키를 삭제할 수없고 자신의 기본 키를 참조하는 다른 스키마의 테이블에 외래 키가있을 수 있으므로 순서가 중요하므로 ALTER ANY TABLE 권한이없는 경우 PK와 UK를 삭제할 수 없습니다. 또한 고유 인덱스를 고유하지 않은 인덱스로 전환 할 수 없으므로 제약 조건을 삭제하기 위해 삭제해야합니다 (이 때문에 고유 제약 조건을 비 고유 인덱스가 지원하는 “실제”제약 조건으로 구현하는 것이 거의 항상 좋습니다. -고유 색인).


답변

단일 명령으로이 작업을 수행 할 수있는 것 같지 않지만 여기 에 내가 찾을 수있는 가장 가까운 것이 있습니다.


답변

이것은 제약 조건을 비활성화하는 또 다른 방법입니다 ( 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;

매력처럼 작동