2016-07-02 8 views
1

In einer Oracle-Datenbank (11gR2), habe ich eine Tabelle my_table mit Spalten (Sequenz, col1, col2, col3). Ich möchte Werte in die Tabelle einfügen, die von anderen Tabellen abgefragt werden, d. H. insert into my_table select <query from other tables>. Das Problem ist, dass der Primärschlüssel die vier Spalten ist, daher muss ich eine Sequenz beginnend von 0 bis zur Zählung der einzufügenden Zeilen hinzufügen (die Reihenfolge ist kein Problem).Wie fügt man Spalten mit der Sequenzspalte hinzu?

Ich habe versucht, eine Schleife wie folgt aus:

DECLARE 
    j NUMBER; 
    r_count number; 
BEGIN 
    select count(1) into r_count from <my query to be inserted>; 
    FOR j IN 0 .. r_count 
    LOOP 
     INSERT INTO my_table 
       select <my query, incorporating r_count as sequence column> ; 
    END LOOP; 
END; 

Aber es hat nicht funktioniert, geschleift tatsächlich r_count mal versucht, die ganze Zeilen jedes Mal einzufügen, es als logisch tun soll. Wie kann ich das erwartete Ziel erreichen und Zeilen einfügen, indem ich eine Sequenzspalte hinzufüge?

Antwort

1

Lassen Sie uns Tabelle erstellen mit Beispieldaten mit der ID und 3 Datenspalten

-- This is your source query table (can be anything) 
CREATE TABLE source_table 
    (
    source_a VARCHAR(255), 
    source_b VARCHAR(255), 
    source_c VARCHAR(255) 
); 

insert into source_table (source_a, source_b, source_c) values ('A', 'B', 'C'); 
insert into source_table (source_a, source_b, source_c) values ('D', 'E', 'F'); 
insert into source_table (source_a, source_b, source_c) values ('G', 'H', 'I'); 

Dann erstellen Zieltabelle (Ihre Datenquelle zu simulieren).

-- This is your target_table 
CREATE TABLE target_table 
    (
    id  NUMBER(9,0), 
    target_a VARCHAR2(255), 
    target_b VARCHAR2(255), 
    target_c VARCHAR2(255) 
); 

-- This is sequence used to ensure unique number in 1st column 
CREATE sequence target_table_id_seq start with 0 minvalue 0 increment BY 1; 

Schließlich führt insert, Laden-ID von Sequenz Rest der Daten aus der Quellentabelle.

INSERT INTO target_table 
SELECT target_table_id_seq.nextval, 
    source_a, 
    source_b, 
    source_c 
FROM source_table; 

Ergebnisse aussehen könnte

1 A B C 
2 D E F 
3 G H I 

Wenn Sie einige Werte später hinzugefügt, sie mit Nummerierung 4,5,6 usw. fortsetzen wird .. Oder wollen Sie nur innerhalb der Gruppe zu erhalten, um ?Wenn Sie also 2 hinzugefügt mehr Reihen JKL und MNO, Zieltabelle wie diese

1 A B C 
2 D E F 
3 G H I 
1 J K L 
2 M N O 

Dazu suchen würden Sie andere Lösung benötigen (nicht einmal Sequenzer benötigen)

SELECT 
    RANK() OVER (ORDER BY source_a, source_b, source_c), 
    source_a, 
    source_b, 
    source_c 
FROM source_table; 

Technisch Sie ROWNUM verwenden könnte direkt, ABER ich entscheide mich für RANK() OVER analytische Funktion aufgrund des konsistenten Ergebnisses. Bitte beachten Sie, dass dies Ihren komplexen Primärschlüssel verletzt, wenn Sie versuchen, dieselben Zeilen zweimal einzufügen (Meine erste Lösung nicht)

+0

Wie um alles in der Welt hast du nur einen Vertreter? :) Danke – amyassin

2

Tun Sie dies nicht in einer Schleife. Nur row_number() verwenden:

INSERT INTO my_table(seq, . . .) 
    select row_number() over (order by NULL) - 1, . . . 
    from . . .; 
0

Also, Sie bereits auf den Tisch haben, hat es die erforderliche Anzahl von Zeilen, und jetzt möchten Sie Zahlen von 0 bis Gesamtanzahl der Zeilen minus einem in der Spalte mit dem Namen Sequenz hinzufügen? (Vielleicht nicht „Sequenz“, sondern etwas weniger wahrscheinlich, dass mit Oracle Worten vorbehalten kollidieren?)

Dann sollte diese Arbeit:

update my_table set seq = rownum - 1; 
+0

Nein, ich habe bereits die Tabelle, aber das sind neue Zeilen, die ich einfügen möchte. Ich suche von anderen Tabellen und möchte eine Sequenz hinzufügen. – amyassin

+0

... aber dann müssen Sie sicherstellen, dass die neuen Zahlen nicht mit bereits bestehenden Zahlen in der Reihenfolge kollidieren? – mathguy

+0

Sie haben Recht. Zum Glück ist in diesem speziellen Szenario col1 ein neuer eindeutiger Wert nur für diese bestimmte Einfügung, so dass andere Sequenzen nicht kollidieren, weil sie eine andere Farbe haben. – amyassin

2

Offensichtlich sollten Sie Oracle-Sequenz verwenden.
Zuerst erzeugt eine Sequenz:

INSERT INTO my_table (sequence, ...) 
select seq_my_table.nextval, <the rest of my query>; 

Sequenznummern in Aufeinanderfolge eingefügt werden:

create sequence seq_my_table start with 0 minvalue 0 increment by 1; 

dann verwenden.