2017-01-24 9 views
0

Ich habe zwei Tabellen, nennen wir sie Table1 und Table2. Ich habe eine Variable mit dem Namen: roleArbeiten mit Listen oder etwas ähnliches wie DataSet

Jetzt muss ich von Table1 eine select-Anweisung tun (die mehrere Zeilen zurückgeben können):

SELECT roles INTO role FROM TABLE1 

Und dann brauche ich die role in Tabelle 2

einfügen
INSERT INTO Table2(RELATION_ID, ROLES) VALUES (maxID+1, role); 

Jetzt ist mein Problem, dass die erste SELECT-Anweisung mehr als 1 Zeile zurückgibt, und so kann ich den Wert nicht in die Variable setzen. Also brauche ich etwas wie eine ArrayList oder ein DataSet, um die Werte einzufügen, da ich eine Schleife über diese Werte machen und sie in eine andere Tabelle einfügen muss. Wie verwende ich eine Liste und iteriere darüber in SQL (Oracle).

Unten sehen Sie meinen Code, ein wenig vereinfacht, so dass nur mein Problem im Fokus ist. Natürlich wird der Code nicht kompiliert, nur um klar zu machen, was ich brauche. Vielen Dank.

CREATE OR REPLACE PROCEDURE "myProcedure"(eventID IN NUMBER) 
    IS 

    roleNumber NUMBER; 
    maxID NUMBER; 

    BEGIN 
     SELECT roles FROM TABLE1; 
     SELECT MAX(RELATION_ID) INTO maxID FROM SOMEOTHERTABLE; 

    IF maxID IS NULL 
    THEN 
     maxID := 0; 
    END IF; 

    FOR counter IN theListThatINeed  
     INSERT INTO Table2(RELATION_ID, ROLES) VALUES (maxID+1, roleAtCounter); 
    END IF; 

    END "myProcedure" 
+0

, wenn Sie eine Sequenz und einen Trigger Auto erhöhen Ihre RELATION_ID verwenden, wird die Lösung –

Antwort

1

Verwenden Sie eine Sammlung und erledigen Sie Ihre Arbeit. Siehe unten:

CREATE OR REPLACE PROCEDURE myProcedure (eventID IN NUMBER) 
IS 
    ID_max NUMBER; 

    CURSOR cur 
    IS 
     SELECT roles FROM TABLE1; 

    TYPE x IS TABLE OF cur%ROWTYPE 
     INDEX BY PLS_INTEGER; 

    var  x; 
BEGIN 
    OPEN CUR; 

    FETCH cur BULK COLLECT INTO var; 

    CLOSE cur; 

    SELECT MAX (RELATION_ID) INTO ID_max FROM SOMEOTHERTABLE; 

    IF ID_max IS NULL 
    THEN 
     ID_max := 0; 
    END IF; 

    FOR i IN 1 .. var.COUNT 
    LOOP 
     INSERT INTO Table2 (RELATION_ID, ROLES) 
      VALUES ((ID_max + i), var(i).roles); 
    END LOOP; 

    COMMIT; 
END myProcedure; 
1

Ich weiß, das ist nicht gerade Sie fragen, um aber Lösung für Ihr Problem ist:

create sequence seqid start with 1 increment by 1; 
INSERT INTO Table2(RELATION_ID, ROLES) 
    select seqid.nextval, role from table1; 

Wenn ein anderer Prozess auch table2 einfügen können, und Sie müssen wirklich max(id) Sie kann mit gehen:

with maxid as (select max(id) mid from table2) 
    INSERT INTO Table2(RELATION_ID, ROLES) 
     select mid+rownum, role from table1, maxid; 
2

In dieser Situation würde ich nur eine einzige SQL-Anweisung verwenden. Es muss kein Kontext zwischen der SQL-Engine und einer anderen Sprache hin- und hergeschaltet werden, und es ist definitiv nicht nötig, so etwas in einer Zeile zu verarbeiten!

INSERT INTO Table2(RELATION_ID, ROLES) 
SELECT (SELECT NVL(MAX(RELATION_ID),0) FROM SOMEOTHERTABLE)+rownum, roles 
FROM table1; 
+0

Dank sehr einfach sein, ich nicht über die NVL() Funktion nicht kannte. Warum meldest du die '+ rownum', ich folge nicht? –

+1

rownum ist eine Pseudospalte, die Oracle automatisch als Zahl von 1 bis zu vielen Zeilen hinzufügt. Also für die erste Zeile, das fügt 1 hinzu, zweitens fügt es 2 usw. hinzu, um Ihre Schleife über die Ergebnismenge zu imitieren und jedes Mal 1 zu Ihrer Variablen hinzuzufügen. Weitere Informationen finden Sie unter: http://docs.oracle.com/database/122/SQLRF/ROWNUM-Pseudocolumn.htm#SQLRF00255 – Craig

+0

Danke, ich werde auf jeden Fall einen Blick darauf werfen. Ich habe noch viel über SQL zu lernen. Also, wenn Sie die '+ rownum' weglassen, erhalten Sie einen Fehler oder vielleicht Inkonsistenz in Ihren Daten? –

Verwandte Themen