Không thể loại bỏ ràng buộc không tồn tại và không thể tạo ra nó


16

Trong khi thử nghiệm một số tập lệnh di chuyển với một bản sao của dữ liệu sản xuất (tập lệnh chạy tốt với dữ liệu phát triển) tôi thấy một tình huống tò mò. CONSTRAINT đã thay đổi nên tôi đang phát lệnh DROP + ADD:

ALTER TABLE A_DUP_CALLE
DROP CONSTRAINT A_DUP_CALLE_UK1;

ALTER TABLE A_DUP_CALLE
ADD CONSTRAINT A_DUP_CALLE_UK1 UNIQUE (
    CONTROL_ID,
    CALLE_AYTO_DUPL
)
ENABLE;

Lệnh DROP hoạt động tốt nhưng THÊM thất bại. Bây giờ, tôi vào một vòng luẩn quẩn. Tôi không thể loại bỏ các ràng buộc vì nó không tồn tại (thả ban đầu hoạt động như mong đợi):

ORA-02443: Không thể thả ràng buộc - ràng buộc không tồn tại

Và tôi không thể tạo nó vì tên đã tồn tại:

ORA-00955: tên đã được sử dụng bởi một đối tượng hiện có

Tôi gõ A_DUP_CALLE_UK1vào hộp Tìm kiếm của Nhà phát triển SQL và ... nó đây rồi! Chủ sở hữu, tên bảng, cảnh bảng ... mọi thứ đều khớp: đó không phải là một đối tượng khác có cùng tên, đó ràng buộc ban đầu của tôi. Bảng xuất hiện trong các chi tiết ràng buộc nhưng ràng buộc không xuất hiện trong các chi tiết của bảng.

Những câu hỏi của tôi:

  • Giải thích cho điều này là gì?
  • Làm cách nào tôi có thể đảm bảo điều đó sẽ không xảy ra khi tôi thực hiện nâng cấp thực sự trên máy chủ trực tiếp?

(Máy chủ là 10g XE, tôi không có đủ danh tiếng để tạo thẻ.)


Có lẽ nó được tạo ra như một loại đối tượng khác và không phải là một ràng buộc duy nhất? Có lẽ chỉ số duy nhất ..
Marian

Có thể tạo ban đầu đã được chạy với dấu ngoặc kép quanh tên bảng? Điều này sẽ làm cho trường hợp tên nhạy cảm. Nếu vậy bạn có thể thả với dấu ngoặc kép và trường hợp tương tự.
Adam Butler

Câu trả lời:


13

Theo phỏng đoán, tôi cho rằng Marian đúng và điều này được gây ra bởi một chỉ mục và ràng buộc duy nhất có cùng tên, ví dụ:

create table t( k1 integer, k2 integer, 
                constraint u1 unique(k1,k2) using index(create unique index u1 on t(k1,k2)),
                constraint u2 unique(k2,k1) using index u1);

select count(*) from user_indexes where index_name='U1';

COUNT(*)               
---------------------- 
1  

alter table t drop constraint u1;

select count(*) from user_indexes where index_name='U1';

COUNT(*)               
---------------------- 
1  

Thông thường khi bạn thêm một ràng buộc duy nhất, một chỉ mục duy nhất có cùng tên được tạo - nhưng chỉ mục và ràng buộc không giống nhau. Có một cái nhìn all_indexesđể xem nếu có một chỉ mục được gọi A_DUP_CALLE_UK1và thử và tìm hiểu nếu nó được sử dụng bởi một cái gì khác trước khi bạn bỏ nó!


Đây là vấn đề. Tệp kết xuất được tạo bởi explệnh chứa một CREATE UNIQUE INDEX "A_DUP_CALLE_UK1" ...câu lệnh không có trong tập lệnh gốc.
Álvaro González

6

Có vẻ rất lạ.

Bạn có thể chạy:

 SELECT *
 FROM user_objects
 WHERE object_name = 'A_DUP_CALLE_UK1'

để kiểm tra xem Oracle có phàn nàn về loại đối tượng nào không. Sau đó, bạn có thể chạy câu lệnh DROP approriate cho điều đó.

Điều khác duy nhất tôi có thể nghĩ đến là bỏ bảng hoàn toàn bằng cách sử dụng DROP TABLE A_DUP_CALLE CASCADE CONSTRAINTSđể loại bỏ mọi thứ thuộc về bảng đó và sau đó tạo lại hoàn toàn.

Nếu bảng chứa dữ liệu có giá trị, bạn có thể tạo bản sao lưu trước đó:

CREATE TABLE old_data
AS
SELECT *
FROM A_DUP_CALLE;

Một khi bạn đã tạo lại bảng, bạn có thể làm

INSERT INTO A_DUP_CALLE (col1, col2, col3) 
SELECT col1, col2, col3
FROM old_data

để khôi phục dữ liệu.


4

Tôi đã có cùng một vấn đề chỉ một vài phút trước đây ... và tôi đã tìm thấy một lời giải thích.

Bằng cách tạo Khóa chính, Oracle tạo ra hai đối tượng: ràng buộc và chỉ mục, điều khiển phần "ĐỘC ĐÁO".

Bằng cách loại bỏ ràng buộc, chỉ mục vẫn ở đó, sử dụng cùng tên của chỉ mục, vì vậy nếu bạn thực hiện chỉ

alter table t drop constraint u1;

Bạn sẽ chỉ bỏ các ràng buộc. Để xóa chỉ mục, bạn sẽ cần phải thực thi

drop index u1;

Điều này nên làm công việc. Ngoài ra, bạn có thể thực hiện cả hai lệnh này cùng một lúc với lệnh

alter table t drop constraint u1 including indexes;

db nào? bao gồm cả không hoạt động trong nhà tiên tri
Derick

1

Ràng buộc khóa chính đi kèm với chỉ mục. Bạn thả ràng buộc nhưng không lập chỉ mục. Kiểm tra:

select * from ALL_OBJECTS where OBJECT_NAME = 'PK_TBL_CONSTR';

và bạn thấy OBJECT_TYPEINDEX.

Cả hai đều làm như vậy:

alter table TBL drop constraint PK_TBL_CONSTR;
drop index PK_TBL_CONSTR;

1

Làm cái này

ALTER TABLE A_DUP_CALLE
DROP CONSTRAINT "A_DUP_CALLE_UK1";

Nó sẽ làm việc.

HÌNH ẢNH: nhập mô tả hình ảnh ở đây


Không, nó sẽ không hoạt động. Câu lệnh của bạn hoàn toàn giống với câu lệnh đầu tiên trong câu hỏi:ALTER TABLE A_DUP_CALLE DROP CONSTRAINT A_DUP_CALLE_UK1;
a_horse_with_no_name

Nó làm việc thực sự. Tôi đã gặp vấn đề tương tự kể từ trưa hôm nay, và tìm kiếm giải pháp tôi đã gặp phải điều này. Đôi khi CONSTRAINTS có thể đã được tạo theo cách phân biệt chữ hoa chữ thường, trong trường hợp đó, bạn sẽ cần đặt tên ràng buộc trong dấu ngoặc kép khi bạn thả nó.
Sachin

Và nó đã làm việc cho tôi. Tôi đã không đặt tên rõ ràng cho các ràng buộc, do đó hệ thống đặt cho nó tên riêng được tạo Relationship142và các NOT NULLràng buộc khác được đặt tên SYS_C0015910. Vì vậy, SYS_C0015910đã bị xóa thành công với truy vấn ALTER đơn giản, nhưng Relationship142cần NHIỀU SỐ ĐÔI
Sachin

1
Bạn đã tạo các ràng buộc bằng cách sử dụng dấu ngoặc kép, ví dụ: alter table ... add constraint "Relationship143" ... "Relationship143"thực sự là một tên khác với RELATIONSHIP143. Nhưng "RELATIONSHIP143"RELATIONSHIP143giống hệt nhau
a_horse_with_no_name

2
Oracle (cơ sở dữ liệu) sẽ không bao giờ tự tạo một cái tên như thế "Relationship143". Nó có thể là một trong những công cụ của bạn đã làm điều này. Dù sao: vì nó đứng, câu trả lời của bạn chỉ đơn giản là sai trong bối cảnh của câu hỏi ban đầu.
a_horse_with_no_name
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.