Nie można usunąć nieistniejącego ograniczenia i nie można go również utworzyć


16

Podczas testowania niektórych skryptów migracji z kopią danych produkcyjnych (skrypty działają poprawnie z danymi programistycznymi) znalazłem ciekawą sytuację. CONSTRAINT zmieniło się, dlatego wydajemy polecenia 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;

Polecenie DROP działało dobrze, ale polecenie DODAJ nie powiodło się. Teraz jestem w błędnym kole. Nie mogę usunąć ograniczenia, ponieważ nie istnieje (początkowe upuszczenie działało zgodnie z oczekiwaniami):

ORA-02443: Nie można usunąć ograniczenia - nieistniejące ograniczenie

Nie mogę go utworzyć, ponieważ nazwa już istnieje:

ORA-00955: nazwa jest już używana przez istniejący obiekt

Piszę A_DUP_CALLE_UK1w polu wyszukiwania dewelopera SQL i ... gotowe! Właściciel, nazwa tabeli, Tablescape ... wszystko mecze: nie jest inny obiekt o tej samej nazwie, to jest mój oryginalny ograniczenie. Tabela pojawia się w szczegółach ograniczenia, ale ograniczenie nie pojawia się w szczegółach tabeli.

Moje pytania:

  • Jakie jest tego wytłumaczenie?
  • Jak mogę się upewnić, że tak się nie stanie, gdy dokonam prawdziwej aktualizacji na serwerze na żywo?

(Serwer to 10 g XE, nie mam wystarczającej reputacji, aby utworzyć tag).


Może został stworzony jako inny typ obiektu, a nie wyjątkowe ograniczenie? Może unikalny indeks ..
Marian

Czy można utworzyć początkowe tworzenie z cudzysłowami wokół nazwy tabeli? W ten sposób w nazwie rozróżniana jest wielkość liter. Jeśli tak, możesz upuścić z cytatami i tym samym przypadkiem.
Adam Butler,

Odpowiedzi:


13

Domyślam się, że Marian ma rację, a jest to spowodowane unikalnym indeksem i ograniczeniem o tej samej nazwie, np .:

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  

Zwykle po dodaniu unikalnego ograniczenia tworzony jest unikalny indeks o tej samej nazwie - ale indeks i ograniczenie nie są tym samym. Sprawdź, all_indexesczy istnieje wywoływany indeks A_DUP_CALLE_UK1i spróbuj dowiedzieć się, czy jest on używany przez coś innego, zanim go upuścisz!


To był problem. Plik zrzutu wygenerowany przez exppolecenie zawiera CREATE UNIQUE INDEX "A_DUP_CALLE_UK1" ...instrukcję, której nie ma w oryginalnym zestawie skryptów.
Álvaro González

6

Wydaje się bardzo dziwne.

Możesz uruchomić:

 SELECT *
 FROM user_objects
 WHERE object_name = 'A_DUP_CALLE_UK1'

aby sprawdzić, czy na jaki obiekt narzeka Oracle. Następnie możesz uruchomić w tym celu odpowiednią instrukcję DROP.

Jedyną rzeczą, o której mogę myśleć, jest całkowite upuszczenie stołu, DROP TABLE A_DUP_CALLE CASCADE CONSTRAINTSaby pozbyć się wszystkiego, co należy do tego stołu, a następnie odtworzenie go całkowicie.

Jeśli tabela zawiera wartościowe dane, możesz wykonać ich kopię zapasową przed:

CREATE TABLE old_data
AS
SELECT *
FROM A_DUP_CALLE;

Po odtworzeniu tabeli możesz to zrobić

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

przywrócić dane.


4

Kilka minut temu miałem ten sam problem ... i znalazłem wyjaśnienie.

Tworząc klucz podstawowy, Oracle tworzy dwa obiekty: ograniczenie i indeks, który kontroluje część „UNIQUE”.

Po usunięciu ograniczenia indeks pozostaje tam, używając tej samej nazwy indeksu, więc jeśli wykonasz tylko

alter table t drop constraint u1;

Zrzucisz tylko ograniczenie. Aby usunąć indeks, musisz wykonać

drop index u1;

To powinno wystarczyć. Alternatywnie możesz wykonać obie te komendy jednocześnie z komendą

alter table t drop constraint u1 including indexes;

który db? w tym nie działa w wyroczni
Derick

1

Ograniczenia klucza podstawowego pochodzą z indeksem. Upuszczasz ograniczenie, ale nie indeksujesz. Czek:

select * from ALL_OBJECTS where OBJECT_NAME = 'PK_TBL_CONSTR';

i widzisz, że OBJECT_TYPEjest INDEX.

Więc wykonaj oba:

alter table TBL drop constraint PK_TBL_CONSTR;
drop index PK_TBL_CONSTR;

1

Zrób to

ALTER TABLE A_DUP_CALLE
DROP CONSTRAINT "A_DUP_CALLE_UK1";

To będzie działać.

WIZERUNEK: wprowadź opis zdjęcia tutaj


Nie, to nie zadziała. Twoje oświadczenie jest dokładnie tym samym stwierdzeniem, co pierwsze oświadczenie w pytaniu:ALTER TABLE A_DUP_CALLE DROP CONSTRAINT A_DUP_CALLE_UK1;
a_horse_w_no_name

TO faktycznie działało. Miałem ten sam problem od dzisiejszego południa i szukałem rozwiązania. Czasami OGRANICZENIA mogły zostać utworzone z rozróżnianiem wielkości liter, w takim przypadku po upuszczeniu trzeba będzie umieścić nazwę ograniczenia w podwójnych cudzysłowach .
Sachin

I zadziałało dla mnie. Nie nazwałam ograniczeń wyraźnie, dlatego system nadał mu swoją własną wygenerowaną nazwę, Relationship142a inne NOT NULLOgraniczenie zostało nazwane SYS_C0015910. Tak więc SYS_C0015910został pomyślnie usunięty za pomocą prostego zapytania ALTER, ale Relationship142potrzebował PODWÓJNYCH CYTATÓW
Sachin

1
Rzecz ty stworzony ograniczeń używając cudzysłowia, np: alter table ... add constraint "Relationship143" ... "Relationship143"jest rzeczywiście inna nazwa niż RELATIONSHIP143. Ale "RELATIONSHIP143"i RELATIONSHIP143identyczne
a_horse_with_no_name

2
Oracle (baza danych) nigdy nie stworzy nazwy takiej jak "Relationship143"sama. Prawdopodobnie było to jedno z twoich narzędzi. W każdym razie: w obecnej formie Twoja odpowiedź jest po prostu błędna w kontekście pierwotnego pytania.
a_horse_w_na_name
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.