ปิดใช้งานข้อ จำกัด ของตารางทั้งหมดใน Oracle


96

ฉันจะปิดใช้งานข้อ จำกัด ของตารางทั้งหมดใน Oracle ด้วยคำสั่งเดียวได้อย่างไร ซึ่งอาจเป็นได้ทั้งตารางเดียวรายการตารางหรือสำหรับตารางทั้งหมด

คำตอบ:


148

ควรหลีกเลี่ยงการเขียนไฟล์สปูลชั่วคราว ใช้บล็อก PL / SQL คุณสามารถเรียกใช้สิ่งนี้จาก SQL * Plus หรือใส่สิ่งนี้ลงในแพ็คเกจหรือขั้นตอน เข้าร่วมกับ USER_TABLES เพื่อหลีกเลี่ยงข้อ จำกัด ในการดู

ไม่น่าเป็นไปได้ที่คุณต้องการปิดการใช้งานข้อ จำกัด ทั้งหมด (รวมถึงไม่ใช่ NULL คีย์หลัก ฯลฯ ) คุณควรคิดถึงการใส่ constraint_type ในคำสั่ง WHERE

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

การเปิดใช้งานข้อ จำกัด อีกครั้งเป็นเรื่องยุ่งยากเล็กน้อย - คุณต้องเปิดใช้งานข้อ จำกัด ของคีย์หลักก่อนจึงจะสามารถอ้างอิงได้ในข้อ จำกัด ของ Foreign Key สามารถทำได้โดยใช้ ORDER BY บน constraint_type '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;
/

2
ส่วนรหัสแรกนั้นจะพยายามปิดใช้งานคีย์หลักก่อนที่จะปิดใช้งานคีย์ต่างประเทศหรือไม่
David Aldridge

@David ฉันคิดว่าฉันพบปัญหานี้กับส่วนแรก ฉันแก้ไขได้โดยเพิ่ม 'DESC' ระหว่าง 'ORDER BY c.constraint_type' และปิด ')'
AndreiM

@WW ขอขอบคุณ สิ่งนี้ช่วยให้ฉันประหยัดปัญหาในการเขียนคำสั่ง SQL เพื่อสร้างคำสั่ง Enable and Disable constraint
dave

1
ไม่สามารถปิดใช้งานคีย์หลักบนตารางที่จัดทำดัชนี คุณสามารถจัดการสิ่งเหล่านี้ได้โดยเพิ่มAND NOT (t.iot_type IS NOT NULL AND c.constraint_type = 'P')ลงในส่วนรหัสแรก
Andrew Miller

2
คำเตือน: หากคุณได้ปิดการใช้งานข้อ จำกัด ไปแล้วข้อ จำกัด ทั้งหมดจะเปิดใช้งานโดยใช้โพรซีเดอร์ PL / SQL นั้น คุณต้องกรองข้อห้ามเหล่านั้นเพื่อให้แน่ใจว่าปิดใช้งานอยู่
nachouve

11

ในการนับการอ้างอิงระหว่างข้อ จำกัด :

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

5

ไม่ใช่คำสั่งเดียว แต่มีวิธีการทำดังนี้ สคริปต์ต่อไปนี้ได้รับการออกแบบให้ทำงานใน 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

หากต้องการ จำกัด สิ่งที่คุณวางให้กรองเพิ่ม where clause ในคำสั่ง select: -

  • กรอง constraint_type เพื่อวางเฉพาะข้อ จำกัด บางประเภท
  • กรอง table_name เพื่อทำเพียงหนึ่งหรือสองสามตาราง

หากต้องการรันมากกว่า schema ปัจจุบันให้แก้ไขคำสั่ง select เพื่อเลือกจาก all_constraints แทนที่จะเป็น user_constraints

หมายเหตุ - ด้วยเหตุผลบางประการฉันไม่สามารถขีดล่างเพื่อไม่ทำหน้าที่เหมือนตัวเอียงในย่อหน้าก่อนหน้า หากมีใครทราบวิธีแก้ไขโปรดแก้ไขคำตอบนี้


หากคุณต้องการปิดใช้งานข้อ จำกัด แทนการปล่อยให้แก้ไขคำสั่ง SELECT ด้านบน: 'drop constraint' เพื่ออ่าน 'disable constraint' HTH: o)
Andrew

ใช่นี่เป็นข้อเสนอแนะที่ดี - ในอนาคตคุณสามารถแก้ไขโพสต์เพื่อเพิ่มข้อมูลนี้ได้ นั่นเป็นเหตุผลที่ฉันมีโพสต์ของฉันเป็นวิกิชุมชนที่แก้ไขได้
Mike McAllister

5

ใช้เคอร์เซอร์ต่อไปนี้เพื่อปิดการใช้งานข้อ จำกัด ทั้งหมด .. และแก้ไขแบบสอบถามเพื่อเปิดใช้งานข้อ จำกัด ...

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

4

สิ่งนี้สามารถเขียนสคริปต์ใน PL / SQL ได้อย่างง่ายดายโดยใช้มุมมองระบบ DBA / ALL / USER_CONSTRAINTS แต่รายละเอียดต่าง ๆ ไม่น่าสนใจเท่าที่ควร คุณต้องระมัดระวังเกี่ยวกับลำดับที่จะเสร็จสิ้นและคุณต้องคำนึงถึงการมีอยู่ของดัชนีที่ไม่ซ้ำกันด้วย

ลำดับมีความสำคัญเนื่องจากคุณไม่สามารถวางคีย์ที่ไม่ซ้ำกันหรือคีย์หลักที่อ้างอิงโดยคีย์ต่างประเทศและอาจมีคีย์ต่างประเทศบนตารางในสกีมาอื่นที่อ้างอิงคีย์หลักด้วยตัวคุณเองดังนั้นหากคุณไม่เปลี่ยนแปลงสิทธิ์ในตารางใด ๆ ไม่สามารถทิ้ง PK และสหราชอาณาจักรเหล่านั้นได้ นอกจากนี้คุณไม่สามารถเปลี่ยนดัชนีที่ไม่ซ้ำกันให้เป็นดัชนีที่ไม่ซ้ำกันได้ดังนั้นคุณจึงต้องวางดัชนีเพื่อลดข้อ จำกัด (ด้วยเหตุนี้การใช้ข้อ จำกัด เฉพาะเป็นข้อ จำกัด "จริง" จึงดีกว่าเกือบตลอดเวลาซึ่งได้รับการสนับสนุนโดยสิ่งที่ไม่ใช่ - ดัชนีเฉพาะ)



0

นี่เป็นอีกวิธีหนึ่งในการปิดการใช้งานข้อ จำกัด (มาจาก 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;

ทำงานเหมือนมีเสน่ห์


0

ในสคริปต์ "ปิดการใช้งาน" ลำดับตามอนุประโยคควรเป็นดังนี้:

ORDER BY c.constraint_type DESC, c.last_change DESC

เป้าหมายของประโยคนี้คือปิดการใช้งานข้อ จำกัด ในลำดับที่ถูกต้อง


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

คำสั่งนี้ส่งคืนคำสั่งที่ปิดข้อ จำกัด ทั้งหมดรวมถึงคีย์หลักคีย์นอกและข้อ จำกัด อื่น ๆ


0

ด้วยเคอร์เซอร์สำหรับลูป (ผู้ใช้ = 'TRANEE', ตาราง = '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;
/

(หากคุณเปลี่ยนปิดการใช้งานเพื่อเปิดใช้งานคุณสามารถเปิดใช้งานข้อ จำกัด ทั้งหมดได้)


0

คุณสามารถรันคำสั่งทั้งหมดที่ส่งคืนโดยแบบสอบถามต่อไปนี้:

เลือก 'ALTER TABLE' || substr (c.table_name, 1,35) || 'ข้อ จำกัด ที่ปิดใช้งาน' || constraint_name || ' ; ' จาก user_constraints c - โดยที่ c.table_name = 'TABLE_NAME';

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.