it-swarm.com.de

Nicht vorhandene Einschränkungen können nicht gelöscht und auch nicht erstellt werden

Beim Testen einiger Migrationsskripte mit einer Kopie der Produktionsdaten (Skripte funktionieren gut mit Entwicklungsdaten) fand ich eine merkwürdige Situation. Ein CONSTRAINT hat sich geändert, daher gebe ich DROP + ADD-Befehle aus:

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;

Der Befehl DROP hat einwandfrei funktioniert, der Befehl ADD ist jedoch fehlgeschlagen. Jetzt bin ich in einem Teufelskreis. Ich kann die Einschränkung nicht löschen, da sie nicht vorhanden ist (das anfängliche Löschen hat wie erwartet funktioniert):

ORA-02443: Einschränkung kann nicht gelöscht werden - nicht vorhandene Einschränkung

Und ich kann es nicht erstellen, weil der Name bereits existiert:

ORA-00955: Name wird bereits von einem vorhandenen Objekt verwendet

Ich tippe A_DUP_CALLE_UK1 in das Suchfeld von SQL Developer und ... da ist es! Besitzer, Tabellenname, Tabellenlandschaft ... alles stimmt überein: Es ist kein anderes Objekt mit demselben Namen, es ist meine ursprüngliche Einschränkung. Die Tabelle wird in den Einschränkungsdetails angezeigt, aber die Einschränkung wird nicht in den Details der Tabelle angezeigt.

Meine Fragen:

  • Was ist die Erklärung dafür?
  • Wie kann ich sicherstellen, dass dies nicht geschieht, wenn ich das echte Upgrade auf dem Live-Server durchführe?

(Server ist 10g XE, ich habe nicht genug Ruf, um das Tag zu erstellen.)

16

Vermutlich würde ich sagen, dass Marian Recht hat und dies durch einen eindeutigen Index und eine Einschränkung mit demselben Namen verursacht wird, z.

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  

Wenn Sie eine eindeutige Einschränkung hinzufügen, wird normalerweise ein eindeutiger Index mit demselben Namen erstellt. Index und Einschränkung sind jedoch nicht identisch. Schauen Sie sich all_indexes An, um festzustellen, ob es einen Index namens A_DUP_CALLE_UK1 Gibt, und versuchen Sie herauszufinden, ob er von etwas anderem verwendet wird, bevor Sie ihn löschen!

Scheint sehr seltsam.

Du kannst rennen:

 SELECT *
 FROM user_objects
 WHERE object_name = 'A_DUP_CALLE_UK1'

um zu überprüfen, ob über welche Art von Objekt sich Oracle beschwert. Dann können Sie die entsprechende DROP-Anweisung dafür ausführen.

Das einzige andere, was mir einfällt, ist, die Tabelle vollständig mit DROP TABLE A_DUP_CALLE CASCADE CONSTRAINTS Zu löschen, um alles zu entfernen, was zu dieser Tabelle gehört, und sie dann vollständig neu zu erstellen.

Wenn die Tabelle wertvolle Daten enthält, können Sie diese zuvor sichern:

CREATE TABLE old_data
AS
SELECT *
FROM A_DUP_CALLE;

Sobald Sie die Tabelle neu erstellt haben, können Sie dies tun

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

um die Daten wiederherzustellen.

Ich hatte vor ein paar Minuten das gleiche Problem ... und ich habe eine Erklärung gefunden.

Durch das Erstellen eines Primärschlüssels erstellt Oracle zwei Objekte: eine Einschränkung und einen Index, der den Teil "UNIQUE" steuert.

Durch das Löschen der Einschränkung bleibt der Index dort und verwendet denselben Namen wie der Index. Wenn Sie also nur ausführen

alter table t drop constraint u1;

Sie werden nur die Einschränkung löschen. Um den Index zu löschen, müssen Sie ausführen

drop index u1;

Dies sollte die Arbeit erledigen. Alternativ können Sie beide Befehle gleichzeitig mit dem Befehl ausführen

alter table t drop constraint u1 including indexes;
5

Primärschlüsseleinschränkung wird mit Index geliefert. Sie lassen die Einschränkung fallen, aber nicht den Index. Prüfen:

select * from ALL_OBJECTS where OBJECT_NAME = 'PK_TBL_CONSTR';

und du siehst OBJECT_TYPE ist INDEX.

Also beides:

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

Mach das

ALTER TABLE A_DUP_CALLE
DROP CONSTRAINT "A_DUP_CALLE_UK1";

Es wird klappen.

BILD : enter image description here

1
Sachin