Beim Testen einiger Migrationsskripte mit einer Kopie der Produktionsdaten (Skripte funktionieren einwandfrei mit Entwicklungsdaten) stieß ich auf 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 DROP-Befehl hat gut funktioniert, aber der ADD-Befehl ist fehlgeschlagen. Jetzt bin ich in einem Teufelskreis. Ich kann die Einschränkung nicht löschen, da sie nicht vorhanden ist (anfängliches 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 dem SQL Developer Suchfeld und ... da ist es! Eigentümer, Tabellenname, Tabellenumfeld ... alles passt zusammen: Es ist kein anderes Objekt mit demselben Namen, es ist meine ursprüngliche Einschränkung. Die Tabelle wird in den Details der Einschränkung 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 passiert, wenn ich ein echtes Upgrade in Live Server durchführe?
(Server ist 10g XE, ich habe nicht genug Reputation, um das Tag zu erstellen.)
quelle
Antworten:
Vermutlich hat Marian Recht und dies wird durch einen eindeutigen Index und eine Einschränkung mit demselben Namen verursacht, z.
Normalerweise wird beim Hinzufügen einer eindeutigen Einschränkung ein eindeutiger Index mit demselben Namen erstellt, aber der Index und die Einschränkung sind nicht dasselbe. Sehen Sie sich an
all_indexes
, ob ein Index aufgerufen wird,A_DUP_CALLE_UK1
und versuchen Sie herauszufinden, ob er von etwas anderem verwendet wird, bevor Sie ihn löschen!quelle
exp
Befehl generierte Dump-Datei enthält eineCREATE UNIQUE INDEX "A_DUP_CALLE_UK1" ...
Anweisung, die im ursprünglichen Script-Set nicht vorhanden ist.Scheint sehr seltsam.
Du kannst rennen:
um zu überprüfen, über welche Art von Objekt sich Oracle beschwert. Dann können Sie die entsprechende DROP-Anweisung dafür ausführen.
Das einzige andere, was ich mir vorstellen kann, ist, die Tabelle vollständig
DROP TABLE A_DUP_CALLE CASCADE CONSTRAINTS
zu löschen, um alles loszuwerden, 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 vorher sichern:
Sobald Sie die Tabelle neu erstellt haben, können Sie dies tun
um die Daten wiederherzustellen.
quelle
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 "EINZIGARTIGEN" Teil steuert.
Wenn Sie die Einschränkung löschen, bleibt der Index dort und verwendet denselben Namen wie der Index. Wenn Sie also nur ausführen, wird der Index beibehalten
Sie lassen nur die Einschränkung fallen. Um den Index zu löschen, müssen Sie ausführen
Dies sollte die Arbeit erledigen. Alternativ können Sie beide Befehle gleichzeitig mit dem Befehl ausführen
quelle
Primärschlüsselbeschränkung wird mit Index geliefert. Sie löschen die Einschränkung, aber nicht den Index. Prüfen:
und du siehst
OBJECT_TYPE
istINDEX
.Also mach beides:
quelle
Mach das
Es wird klappen.
BILD:
quelle
ALTER TABLE A_DUP_CALLE DROP CONSTRAINT A_DUP_CALLE_UK1;
Relationship142
und anderenNOT NULL
Einschränkungen wurde der Name gegebenSYS_C0015910
. SoSYS_C0015910
wurde erfolgreich mit einfachen ALTER-Abfrage gelöscht, aber DOUBLE QUOTESRelationship142
alter table ... add constraint "Relationship143" ...
"Relationship143"
ist in der Tat ein anderer Name alsRELATIONSHIP143
. Aber"RELATIONSHIP143"
undRELATIONSHIP143
sind identisch"Relationship143"
. Es war wahrscheinlich eines Ihrer Werkzeuge, die dies taten. Wie dem auch sei: Wie es aussieht, Ihre Antwort ist im Kontext der ursprünglichen Frage einfach falsch.