Frage

Wir haben einen einzigen Tisch, dass wir in einen Baum von Tabellen auf einer bestimmten Quellspalte basierend brechen wollen. Ich wollte ein Multi-Säulen-Einsatz versuchen verwenden, aber es scheint, dass, wenn ich einen Klecks in einem Sub-Tabelle einfügen, ich mit einem Fremdschlüssel Verletzung aufzuwickeln.

Ich glaube nicht, das verstößt gegen die Regeln über Multi-Table-Einsätze aber ich konnte ...

falsch

Ich hoffe, dass jemand mich auf einige tiefen gehende Ressourcen um, was hier eigentlich los ist, zeigen könnte, so dass ich darauf vertrauen kann, dass das, was Lösung als Teil einer Liquibase changeset auf Oracle-Datenbanken 9i arbeiten -> 11g .

Hoffentlich Simplified Szenario

CREATE TABLE source (
    pk NUMBER NOT NULL PRIMARY KEY,
    type VARCHAR2(20) NOT NULL,
    content VARCHAR2(20) NOT NULL
);

INSERT INTO source (pk,type,content) values (1,'two','n/a');
INSERT INTO source (pk,type,content) values (2,'one','Content');

CREATE TABLE dest (
    pk NUMBER NOT NULL PRIMARY KEY,
    type VARCHAR2(20) NOT NULL
);


CREATE TABLE dest_one  (
    pkfk NUMBER NOT NULL PRIMARY KEY,
    data BLOB NOT NULL,
    CONSTRAINT XFK1DEST_ONE FOREIGN KEY (pkfk) REFERENCES dest (pk)
);


CREATE TABLE dest_two  (
    pkfk NUMBER NOT NULL PRIMARY KEY,
    CONSTRAINT XFK1DEST_TWO FOREIGN KEY (pkfk) REFERENCES dest (pk)
 );

Quelle enthält unsere ursprünglichen Daten. DEST unsere Eltern-Tabelle, mit Kindern dest_one und dest_two sein (die Informationen über die Dinge des Typs ‚ein‘ oder ‚zwei‘, die jeweils enthalten). Dinge vom Typ eines haben Inhalt, aber die Dinge vom Typ zwei nicht.

Der gescheiterte Versuch

INSERT ALL
WHEN 1=1 THEN INTO dest (pk,type) VALUES (pk,type)
WHEN type='one' THEN INTO dest_one (pkfk,data) VALUES (pk,content)
WHEN type='two' THEN INTO dest_two (pkfk) VALUES (pk)
SELECT pk,type,utl_raw.cast_to_raw(content) as content from source where type in ('one','two');

Wie bereits erwähnt, Wund ich hier mit einer Fremdschlüssel Einschränkungsverletzung auf. Zur weiteren Veranschaulichung, dass der Blob war die Frage, die ich zwei separate ähnliche Abfragen versucht (siehe unten) die Realisierung der eine ohne das Blob Einsatz gearbeitet, aber mit dem Blob Insert fehlgeschlagen.

INSERT ALL
WHEN 1=1 THEN INTO dest (pk,type) VALUES (pk,type)
WHEN type='two' THEN INTO dest_two (pkfk) VALUES (pk)
SELECT pk,type,utl_raw.cast_to_raw(content) as content from source where type = 'two';
/* Successful */

INSERT ALL
WHEN 1=1 THEN INTO dest (pk,type) VALUES (pk,type)
WHEN type='one' THEN INTO dest_one (pkfk,data) VALUES (pk,content)
SELECT pk,type,utl_raw.cast_to_raw(content) as content from source where type = 'one';
/* ORA-02291: integrity constraint violated, no parent key */

Lösung 1 - Traditionelle Einsätze

INSERT INTO dest (pk,type) SELECT pk,type from source where type in ('one','two');
INSERT INTO dest_two (pkfk) SELECT pk from source where type = 'two';
INSERT INTO dest_one (pkfk,data) SELECT pk,utl_raw.cast_to_raw(content) from source where type = 'one';

Eine Option Ich bin unter Berücksichtigung zurück in mehr separaten Insert-Anweisungen gehen, aber im Gegensatz zu, wie ich sie hier gesagt habe, ich bin besorgt darüber, dass ich dafür sorgen muß, werde ich meine Untertabelle Einsätze schreiben, um nur zu versuchen, Insert die Zeilen, die in Mutter dest Tabelle ... ich brauche auf mehr Forschung zu tun, wie Liquibase mehrere sQL-Anweisungen in dem gleichen changeset behandelt.

Lösung 2 - Zeitweilig Fremdschlüssel-Constraints

deaktivieren

ALTER TABLE dest_one DISABLE CONSTRAINT XFK1DEST_ONE;

INSERT ALL WHEN 1=1 THEN INTO dest (pk,type) VALUES (pk,type) WHEN type='one' THEN INTO dest_one (pkfk,data) VALUES (pk,content) WHEN type='two' THEN INTO dest_two (pkfk) VALUES (pk) SELECT pk,type,utl_raw.cast_to_raw(content) as content from source where type in ('one','two');

ALTER TABLE dest_one ENABLE CONSTRAINT XFK1DEST_ONE;

Dies ist die Lösung, die ich bin Neigung zu. Während Deaktivierung scheint den Fremdschlüssels auf meinem blob Tisch, um es in meiner Testumgebung (10 g - 10.2.0.1.0) funktioniert, ich bin nicht sicher, ob ich auch als auch den Fremdschlüssel auf der Nicht-BLOB-Tabelle deaktivieren werden soll (aufgrund wie 9i, 11g oder andere Versionen von 10g können sich verhalten). Die Mittel, auch hier würde geschätzt.

Dank einem Haufen!

War es hilfreich?

Lösung

Eine andere Lösung wäre die Einschränkung Bewertung aufzuschieben, bis COMMIT. Ich vermute (bin aber nicht sicher), dass der Multi-Table Einsatz Zeilen in einer anderen Reihenfolge als das Einfügen Sie erwarten und wollen. Erstellen Sie Ihre Einschränkungen wie folgt:

ALTER TABLE DEST_ONE DROP CONSTRAINT XFK1DEST_ONE;

ALTER TABLE DEST_ONE
  ADD CONSTRAINT XFK1DEST_ONE
    FOREIGN KEY (pkfk) REFERENCES dest (pk) 
    INITIALLY DEFERRED DEFERRABLE;

ALTER TABLE DEST_TWO DROP CONSTRAINT XFK1DEST_TWO;

ALTER TABLE DEST_TWO
  ADD CONSTRAINT XFK1DEST_TWO
    FOREIGN KEY (pkfk) REFERENCES dest (pk)
    INITIALLY DEFERRED DEFERRABLE;

Das erstellt die Zwänge, so dass sie verschoben werden können, und werden ab dem Zeitpunkt verschoben sie erstellt. Dann versuchen Sie Ihre ursprüngliche INSERT erneut.

Teile und genießen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top