it-swarm.dev

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

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_UK1 do SQL Developer's Pole wyszukiwania i ... gotowe! Właściciel, nazwa tabeli, układ tabel ... wszystko pasuje: to nie jest inny obiekt o tej samej nazwie, to is moje oryginalne 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.)

16

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. Spójrz na all_indexes, aby sprawdzić, czy istnieje indeks o nazwie A_DUP_CALLE_UK1 i spróbuj dowiedzieć się, czy jest używany przez coś innego, zanim go upuścisz!

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 myślę, jest całkowite upuszczenie tabeli przy użyciu DROP TABLE A_DUP_CALLE CASCADE CONSTRAINTS, aby pozbyć się wszystkiego, co należy do tej tabeli, a następnie całkowicie ją ponownie utworzyć.

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.

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;
5

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

select * from ALL_OBJECTS where OBJECT_NAME = 'PK_TBL_CONSTR';

i widzisz OBJECT_TYPE to INDEX.

Więc wykonaj oba:

alter table TBL drop constraint PK_TBL_CONSTR;
drop index PK_TBL_CONSTR;
1
gavenkoa

Zrób to

ALTER TABLE A_DUP_CALLE
DROP CONSTRAINT "A_DUP_CALLE_UK1";

To będzie działać.

OBRAZ: enter image description here

1
Sachin