Varolmayan kısıtlamayı bırakamaz ve oluşturamaz


16

Bazı geçiş komut dosyalarını üretim verilerinin bir kopyasıyla test ederken (komut dosyaları geliştirme verileriyle iyi çalışır) ilginç bir durum buldum. Bir CONSTRAINT değişti, bu yüzden DROP + ADD komutları veriyorum:

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 komutu iyi çalıştı ancak ADD komutu başarısız oldu. Şimdi bir kısır döngüye girdim. Ben (çünkü ilk damla beklendiği gibi çalıştı) kısıtlama bırakamıyorum:

ORA-02443: Kısıtlama bırakılamıyor - var olmayan kısıtlama

Ve adı zaten var çünkü oluşturamıyorum:

ORA-00955: isim zaten mevcut bir nesne tarafından kullanılıyor

A_DUP_CALLE_UK1SQL Developer'ın Arama kutusuna yazıyorum ve ... işte orada! Sahip, tablo adı, tablescape ... her şey eşleşiyor: aynı ada sahip farklı bir nesne değil , orijinal kısıtlamam. Tablo, kısıtlama ayrıntılarında görünür, ancak kısıtlama tablonun ayrıntılarında görünmez.

Sorularım:

  • Bunun açıklaması ne?
  • Canlı sunucuda gerçek yükseltmeyi yaptığımda bunun olmamasını nasıl sağlayabilirim?

(Sunucu 10g XE, etiketi oluşturmak için yeterli itibarım yok.)


Belki başka bir nesne türü olarak yaratıldı, benzersiz bir kısıtlama değil? Belki benzersiz endeks ..
Marian

İlk oluşturma tablo adı etrafında tırnak işaretleri ile çalıştırılmış olabilir mi? Bu durum büyük / küçük harfe duyarlı hale gelir. Öyleyse tırnak işaretleri ve aynı durumla düşebilirsiniz.
Adam Butler

Yanıtlar:


13

Bir tahminte Marian'ın haklı olduğunu ve bunun aynı adı taşıyan benzersiz bir dizin ve kısıtlamadan kaynaklandığını söyleyebilirim, örneğin:

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  

Normalde benzersiz bir kısıtlama eklediğinizde, aynı ada sahip benzersiz bir dizin oluşturulur - ancak dizin ve kısıtlama aynı şey değildir. all_indexesBir indeks olup olmadığını görmek için bir göz atın A_DUP_CALLE_UK1ve onu bırakmadan önce başka bir şey tarafından kullanılıp kullanılmadığını anlamaya çalışın!


Sorun buydu. expKomut tarafından oluşturulan döküm dosyası CREATE UNIQUE INDEX "A_DUP_CALLE_UK1" ..., orijinal komut dosyası kümesinde bulunmayan bir ifade içerir .
Álvaro González

6

Çok garip görünüyor.

Koşabilirsin:

 SELECT *
 FROM user_objects
 WHERE object_name = 'A_DUP_CALLE_UK1'

Oracle'ın ne tür bir nesneden şikayet edip etmediğini kontrol etmek. Sonra bunun için DROP onayı deyimini çalıştırabilirsiniz.

Aklıma gelen tek şey DROP TABLE A_DUP_CALLE CASCADE CONSTRAINTS, o tabloya ait her şeyden kurtulmak için tabloyu tamamen bırakmak ve daha sonra tamamen yeniden oluşturmaktır.

Tablo değerli veriler içeriyorsa, daha önce bunun bir yedeğini alabilirsiniz:

CREATE TABLE old_data
AS
SELECT *
FROM A_DUP_CALLE;

Masayı yeniden oluşturduktan sonra,

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

verileri geri yüklemek için.


4

Aynı sorunu sadece birkaç dakika önce yaşadım ... ve bir açıklama buldum.

Birincil Anahtar oluşturarak Oracle iki nesne oluşturur: "BENZERSİZ" kısmı kontrol eden bir sınırlama ve bir dizin.

Kısıtlamayı bırakarak dizin, dizinin aynı adını kullanarak orada kalır, bu nedenle yalnızca

alter table t drop constraint u1;

Sadece kısıtı bırakacaksınız. Dizini bırakmak için çalıştırmanız gerekir

drop index u1;

Bu işi yapmalı. Alternatif olarak, bu komutların her ikisini de komutla aynı anda yapabilirsiniz

alter table t drop constraint u1 including indexes;

hangi db? dahil oracle çalışmıyor
Derick

1

Birincil anahtar kısıtlaması dizinle birlikte gelir. Kısıtlama bırakırsınız, ancak dizin oluşturmazsınız. Kontrol:

select * from ALL_OBJECTS where OBJECT_NAME = 'PK_TBL_CONSTR';

ve gördüğünüz OBJECT_TYPEIS INDEX.

Her ikisini de yapın:

alter table TBL drop constraint PK_TBL_CONSTR;
drop index PK_TBL_CONSTR;

1

Bunu yap

ALTER TABLE A_DUP_CALLE
DROP CONSTRAINT "A_DUP_CALLE_UK1";

Çalışacak.

GÖRÜNTÜ: resim açıklamasını buraya girin


Hayır işe yaramayacak. Kişisel ifadesi aynen söz konusu birinci deyimi aynı deyimi:ALTER TABLE A_DUP_CALLE DROP CONSTRAINT A_DUP_CALLE_UK1;
a_horse_with_no_name

Aslında ÇALIŞTI. Bugün öğle saatinden beri aynı problem yaşıyordum ve karşılaştığım çözümü araştırıyordum. Bazen CONSTRAINTS büyük / küçük harfe duyarlı bir şekilde oluşturulmuş olabilir, bu durumda, kısıtlama adını bıraktığınızda çift ​​tırnak içine almanız gerekir.
Sachin

Ve benim için çalıştı. Kısıtlamaları açıkça adlandırmamıştım, bu yüzden sistem ona kendi oluşturduğu adı verdi Relationship142ve diğer NOT NULLKısıtlama adı verildi SYS_C0015910. Bu yüzden SYS_C0015910basit ALTER sorgusu ile başarıyla silindi, ancak ÇİFT TEKLİFLERRelationship142 gerekli
Sachin

1
Eğer oluşturduğunuz örneğin çift tırnak kullanarak kısıtlamaları: alter table ... add constraint "Relationship143" ... "Relationship143"gerçekten de farklı bir adıdır RELATIONSHIP143. Ama "RELATIONSHIP143"ve RELATIONSHIP143olan özdeş
a_horse_with_no_name

2
Oracle (veritabanı) hiçbir zaman"Relationship143" kendi başına bir ad oluşturmaz . Muhtemelen bunu yapan araçlarınızdan biriydi. Her neyse: olduğu gibi, cevabınız orijinal soru bağlamında yanlıştır.
a_horse_with_no_name
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.