Câu trả lời:
Tốt hơn là tránh ghi ra các tệp ống đệm tạm thời. Sử dụng một khối PL / SQL. Bạn có thể chạy điều này từ SQL * Plus hoặc đưa thứ này vào một gói hoặc thủ tục. Việc tham gia USER_TABLES là có để tránh các hạn chế về chế độ xem.
Không chắc rằng bạn thực sự muốn vô hiệu hóa tất cả các ràng buộc (bao gồm NOT NULL, khóa chính, v.v.). Bạn nên suy nghĩ về việc đặt kiểu_kết_thức trong mệnh đề 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;
/
Việc kích hoạt lại các ràng buộc khó hơn một chút - bạn cần bật các ràng buộc khóa chính trước khi có thể tham chiếu chúng trong một ràng buộc khóa ngoại. Điều này có thể được thực hiện bằng cách sử dụng ORDER BY trên bind_type. 'P' = khóa chính, 'R' = khóa ngoài.
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;
/
AND NOT (t.iot_type IS NOT NULL AND c.constraint_type = 'P')
vào đoạn mã đầu tiên.
Để tính các phụ thuộc giữa các ràng buộc:
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;
/
Đó không phải là một lệnh duy nhất, nhưng đây là cách tôi thực hiện. Tập lệnh sau đã được thiết kế để chạy trong SQL * Plus. Lưu ý, tôi đã cố ý viết điều này để chỉ hoạt động trong lược đồ hiện tại.
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
Để hạn chế những gì bạn bỏ qua, hãy lọc thêm mệnh đề where vào câu lệnh select: -
Để chạy trên nhiều giản đồ hiện tại, hãy sửa đổi câu lệnh select để chọn từ all_constraints thay vì user_constraints.
Lưu ý - vì một số lý do, tôi không thể lấy dấu gạch dưới để KHÔNG hoạt động giống như in nghiêng trong đoạn trước. Nếu ai đó biết cách sửa nó, xin vui lòng chỉnh sửa câu trả lời này.
Sử dụng con trỏ sau để tắt tất cả các ràng buộc .. Và thay đổi truy vấn để kích hoạt các ràng buộc ...
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;
/
Điều này có thể được viết trong PL / SQL khá đơn giản dựa trên chế độ xem hệ thống DBA / ALL / USER_CONSTRAINTS, nhưng các chi tiết khác nhau không hề đơn giản như nó nghe. Bạn phải cẩn thận về thứ tự thực hiện và bạn cũng phải tính đến sự hiện diện của các chỉ mục duy nhất.
Thứ tự quan trọng vì bạn không thể bỏ khóa duy nhất hoặc khóa chính được tham chiếu bởi khóa ngoại và có thể có khóa ngoại trên các bảng trong các lược đồ khác tham chiếu khóa chính của riêng bạn, vì vậy trừ khi bạn có đặc quyền ALTER BẤT KỲ BẢNG nào thì bạn không thể bỏ PKs và UKs. Ngoài ra, bạn không thể chuyển một chỉ mục duy nhất thành một chỉ mục không phải là duy nhất, vì vậy bạn phải loại bỏ nó để loại bỏ ràng buộc (vì lý do này, hầu như luôn tốt hơn nếu triển khai các ràng buộc duy nhất như một ràng buộc "thực" được hỗ trợ bởi một không -chỉ số đồng nhất).
Có vẻ như bạn không thể làm điều này với một lệnh duy nhất, nhưng đây là điều gần nhất với nó mà tôi có thể tìm thấy.
Đây là một cách khác để tắt các ràng buộc (nó đến từ 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;
hoạt động như một sự quyến rũ
Trong tập lệnh "vô hiệu hóa", thứ tự theo mệnh đề phải là:
ORDER BY c.constraint_type DESC, c.last_change DESC
Mục tiêu của điều khoản này là vô hiệu hóa các ràng buộc theo đúng thứ tự.
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;
Câu lệnh này trả về các lệnh tắt tất cả các ràng buộc bao gồm khóa chính, khóa ngoại và các ràng buộc khác.
với con trỏ cho vòng lặp (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;
/
(Nếu bạn thay đổi tắt thành bật, bạn có thể bật tất cả các ràng buộc)
Bạn có thể thực hiện tất cả các lệnh được trả về bởi truy vấn sau:
chọn 'ALTER TABLE' || substr (c.table_name, 1,35) || 'HIỆU HÓA CONSTRAINT' || tên_chỉ_lệnh || " ; ' từ user_constraints c --where c.table_name = 'TABLE_NAME';