ไม่สามารถวางข้อ จำกัด ที่ไม่มีอยู่และไม่สามารถสร้างได้


16

ในขณะที่ทดสอบสคริปต์การย้ายข้อมูลบางส่วนด้วยสำเนาข้อมูลการผลิต (สคริปต์ทำงานได้ดีกับข้อมูลการพัฒนา) ฉันพบสถานการณ์ที่น่าสงสัย ข้อ จำกัด มีการเปลี่ยนแปลงดังนั้นฉันจึงออกคำสั่ง DROP + เพิ่ม:

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;

คำสั่ง DROP ทำงานได้ดี แต่ ADD ล้มเหลว ตอนนี้ฉันเข้าสู่วงจรอุบาทว์ ฉันไม่สามารถวางข้อ จำกัด ได้เนื่องจากไม่มีอยู่ (การดรอปเริ่มต้นทำงานตามที่คาดไว้):

ORA-02443: ไม่สามารถวางข้อ จำกัด - ข้อ จำกัด ที่ไม่มีอยู่

และฉันไม่สามารถสร้างได้เพราะมีชื่ออยู่แล้ว:

ORA-00955: ชื่อนี้ถูกใช้โดยวัตถุที่มีอยู่แล้ว

ฉันพิมพ์A_DUP_CALLE_UK1ลงในช่องค้นหาของนักพัฒนา SQL และ ... มีอยู่! เจ้าของชื่อตาราง tablescape ... ทุกอย่างตรงกัน: ไม่ใช่วัตถุอื่นที่มีชื่อเดียวกันมันเป็นข้อ จำกัด ดั้งเดิมของฉัน ตารางจะปรากฏในรายละเอียดข้อ จำกัด แต่ข้อ จำกัด จะไม่ปรากฏในรายละเอียดของตาราง

คำถามของฉัน:

  • คำอธิบายสำหรับสิ่งนี้คืออะไร?
  • ฉันจะมั่นใจได้อย่างไรว่ามันจะไม่เกิดขึ้นเมื่อฉันทำการอัปเกรดจริงในเซิร์ฟเวอร์สด

(เซิร์ฟเวอร์คือ 10g XE ฉันไม่มีชื่อเสียงเพียงพอที่จะสร้างแท็ก)


บางทีมันอาจถูกสร้างเป็นวัตถุประเภทอื่นและไม่ใช่ข้อ จำกัด ที่ไม่เหมือนใคร อาจจะเป็นดัชนีที่ไม่ซ้ำกัน ..
แมเรียน

การสร้างเริ่มต้นสามารถรันด้วยเครื่องหมายคำพูดรอบชื่อตารางได้หรือไม่ สิ่งนี้จะทำให้ชื่อตัวพิมพ์เล็กและใหญ่ ถ้าเป็นเช่นนั้นคุณสามารถวางด้วยคำพูดและกรณีเดียวกัน
Adam Butler

คำตอบ:


13

ฉันเดาได้ว่า Marian นั้นถูกต้องและเกิดจากดัชนีและข้อ จำกัด ที่มีชื่อเดียวกันเช่น:

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  

โดยปกติเมื่อคุณเพิ่มข้อ จำกัด ที่ไม่ซ้ำกันดัชนีเฉพาะที่มีชื่อเดียวกันจะถูกสร้างขึ้น แต่ดัชนีและข้อ จำกัด จะไม่เหมือนกัน ลองดูall_indexesเพื่อดูว่ามีดัชนีเรียกหรือไม่A_DUP_CALLE_UK1และลองคิดดูว่ามันถูกใช้โดยอย่างอื่นก่อนที่คุณจะปล่อยมันหรือไม่!


นี่คือปัญหา ไฟล์ดัมพ์ที่สร้างโดยexpคำสั่งมีCREATE UNIQUE INDEX "A_DUP_CALLE_UK1" ...คำสั่งที่ไม่มีอยู่ในชุดสคริปต์ดั้งเดิม
ÁlvaroGonzález

6

ดูเหมือนจะแปลกมาก

คุณสามารถเรียกใช้:

 SELECT *
 FROM user_objects
 WHERE object_name = 'A_DUP_CALLE_UK1'

เพื่อตรวจสอบว่าชนิดของวัตถุที่ Oracle บ่นเกี่ยวกับ จากนั้นคุณสามารถเรียกใช้คำสั่ง DROP ที่น่ากลัวได้

สิ่งเดียวที่ฉันคิดได้ก็คือการวางตารางทั้งหมดโดยใช้DROP TABLE A_DUP_CALLE CASCADE CONSTRAINTSเพื่อกำจัดทุกสิ่งที่เป็นของตารางนั้นแล้วสร้างใหม่ทั้งหมด

หากตารางมีข้อมูลที่มีค่าคุณสามารถสำรองข้อมูลก่อน:

CREATE TABLE old_data
AS
SELECT *
FROM A_DUP_CALLE;

เมื่อคุณสร้างตารางขึ้นใหม่แล้วคุณสามารถทำได้

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

เพื่อเรียกคืนข้อมูล


4

ฉันมีปัญหาเดียวกันเมื่อไม่กี่นาทีที่ผ่านมา ... และฉันพบคำอธิบายแล้ว

ด้วยการสร้างคีย์หลักออราเคิลจะสร้างวัตถุสองรายการ: ข้อ จำกัด และดัชนีซึ่งควบคุมส่วน "UNIQUE"

โดยการวางข้อ จำกัด ดัชนียังคงอยู่โดยใช้ชื่อเดียวกันของดัชนีดังนั้นหากคุณดำเนินการเพียง

alter table t drop constraint u1;

คุณจะทิ้งข้อ จำกัด เท่านั้น หากต้องการวางดัชนีคุณจะต้องดำเนินการ

drop index u1;

สิ่งนี้ควรทำงาน หรือคุณสามารถทำทั้งสองคำสั่งพร้อมกันด้วยคำสั่ง

alter table t drop constraint u1 including indexes;

db ตัวไหน รวมถึงไม่ทำงานใน oracle
Derick

1

ข้อ จำกัด คีย์หลักมาพร้อมกับดัชนี คุณวางข้อ จำกัด แต่ไม่ทำดัชนี ตรวจสอบ:

select * from ALL_OBJECTS where OBJECT_NAME = 'PK_TBL_CONSTR';

และคุณจะเห็นมีOBJECT_TYPEINDEX

ดังนั้นทั้งสอง:

alter table TBL drop constraint PK_TBL_CONSTR;
drop index PK_TBL_CONSTR;

1

ทำเช่นนี้

ALTER TABLE A_DUP_CALLE
DROP CONSTRAINT "A_DUP_CALLE_UK1";

มันจะทำงาน.

ภาพ: ป้อนคำอธิบายรูปภาพที่นี่


ไม่มันจะไม่ทำงาน คำสั่งของคุณตรงกับคำสั่งแรกในคำถาม:ALTER TABLE A_DUP_CALLE DROP CONSTRAINT A_DUP_CALLE_UK1;
a_horse_with_no_name

มันใช้งานได้จริง ฉันมีปัญหาเดียวกันตั้งแต่เที่ยงวันนี้และค้นหาวิธีแก้ปัญหาที่ฉันเจอ ในบางครั้ง CONSTRAINTS อาจถูกสร้างด้วยวิธีเล็ก ๆ น้อย ๆ ในกรณีนี้คุณจะต้องใส่ชื่อข้อ จำกัด ในเครื่องหมายคำพูดคู่เมื่อคุณวาง
Sachin

และมันก็ได้ผลกับฉันด้วย ผมไม่ได้ตั้งชื่อ จำกัด อย่างชัดเจนระบบจึงให้มันมันชื่อที่สร้างตัวเองRelationship142และอื่น ๆ ที่NOT NULLจำกัด SYS_C0015910ได้รับชื่อ ดังนั้นจึงSYS_C0015910ถูกลบเรียบร้อยแล้วด้วยแบบสอบถาม ALTER แบบธรรมดา แต่Relationship142จำเป็นต้องมีสองเท่า
Sachin

1
ที่คุณสร้างข้อ จำกัด การใช้คำพูดสองเช่น: ย่อมเป็นชื่อที่แตกต่างกว่าalter table ... add constraint "Relationship143" ... "Relationship143" RELATIONSHIP143แต่"RELATIONSHIP143"และRELATIONSHIP143มีความเหมือน
a_horse_with_no_name

2
Oracle (ฐานข้อมูล) จะไม่สร้างชื่ออย่าง"Relationship143"เป็นของตัวเอง อาจเป็นหนึ่งในเครื่องมือของคุณที่ทำสิ่งนี้ อย่างไรก็ตามคำตอบของคุณนั้นผิดในบริบทของคำถามเดิม
a_horse_with_no_name
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.