2016-07-29 56 views
0

Ich versuche, eine Prozedur zu erstellen, die Daten aus einer Tabelle in einer anderen Tabelle auffüllt. Wenn die Kombination von Spalten vorhanden ist, werden zwei Spalten in der Zieltabelle aktualisiert. Wenn keine Kombination von Spalten vorhanden ist, wird in der Zieltabelle ein Datensatz erstellt oder überschrieben.Oracle Prozedurfehler PLS-00330, ORA-00904: ungültiger Bezeichner und Fehler (37,24): PLS-00382

Kann jemand/jemand bitte mir helfen, die genannten Fehler zu beheben? Ich werde dir verpflichtet sein.

Hier ist das Verfahren.

create or replace PROCEDURE   "PRO_1_Table_2_another" AS 

CURSOR C1_CUR IS 
SELECT D.D1 
      ,SUBSTR(SISR.S1,1,4) 
      ,SISR.S2 
      ,SISR.S3 
      ,SISR.S4 
      ,SISR.S5 
      ,SISR.S6 
      ,SISR.S7 
      ,SISR.S8 
      ,SISR.S9 
    FROM something_in_system_record SISR 
     ,Dump D 
    WHERE SUBSTR(SISR.A1,1,4)=D.D1; 

    TYPE C1_TA is table of C1_CUR%ROWTYPE; 
    V_C1 C1_TA; 

    BEGIN 


    FOR i in C1_CUR LOOP 

    V_C1 := C1_TA; --Error(26,12): PLS-00330: invalid use of type name or subtype name 
      MERGE INTO In_something TGT 
      USING 
      (SELECT V_C1(i).A1 AS A1, 
        V_C1(i).A2 AS A2, 
        V_C1(i).A3 AS A3, 
        V_C1(i).A4 AS A4, 
        V_C1(i).A5 AS A5, 
        V_C1(i).A6 AS A6, 
        V_C1(i).A7 AS A7, 
        V_C1(i).A8 AS A8, 
        V_C1(i).A9 AS A9 --Error(37,19): PL/SQL: ORA-00904: :invalid identifier &&& Error(37,24): PLS-00382: expression is of wrong type 
      FROM DUAL) SRC 
      ON  (SRC.A1 = TGT.A1 
       AND SRC.A2 = TGT.A2 
       AND SRC.A3 = TGT.A3 
       AND SRC.A4 = TGT.A4 
       AND SRC.A5 = TGT.A5 
       AND SRC.A6 = TGT.A6 
       AND SRC.A7 = TGT.A7 
     ) 
      WHEN MATCHED THEN 
      UPDATE SET TGT.A8 = SRC.A8, 
         TGT.A9 = SRC.A9 
      WHEN NOT MATCHED THEN 
      INSERT (TGT.A1 
       ,TGT.A2 
       ,TGT.A3 
       ,TGT.A4 
       ,TGT.A5 
       ,TGT.A6 
       ,TGT.A7 
       ,TGT.A8 
       ,TGT.A9) 
      VALUES 
       (SRC.S1 
       ,SRC.S2 
       ,SRC.S3 
       ,SRC.S4 
       ,SRC.S5 
       ,SRC.S6 
       ,SRC.S7 
       ,SRC.S8 
       ,SRC.S9);   
    END LOOP; 
    COMMIT; 
    EXCEPTION 
    WHEN OTHERS THEN 
    DBMS_OUTPUT.PUT_LINE(SQLCODE||' - '||SQLERRM); 
END PRO_1_Table_2_another; 
+0

Ich habe meine Frage aktualisiert, die angibt, wo die Fehler generiert werden. – ishan

+0

Sie scheinen A1 und S1 usw. zu mischen, sind sie alle in beiden Tabellen gleich? –

Antwort

0

Die ORA-00904: : invalid identifier kommt, wenn Sie den Spaltennamen falsch buchstabieren.

Wie Sie haben eine Tabelle Employee, die die folgende Spalte haben.

|ID|Name|Address| 

und schreiben Sie eine DML-Anweisung wie folgt,

select * from Employee where Adress like '%abcpqr%' 

Dann wird es diese Ausnahme werfen. ORA-00904: : invalid identifier

Ich hoffe, es wird helfen.

+0

Ich habe alle Spalten überprüft. Sie sind nicht falsch geschrieben. Danke für Ihre Hilfe. – ishan

0

Ihre C1_TA Typ ist eine Sammlung, so

V_C1 := C1_TA; 

sein sollte:

V_C1 := C1_TA(); 

... aber Sie brauchen es nicht; Sie mischen verschiedene Cursortypen. Sie scheinen einen Teil davon geschrieben zu haben, als ob Sie in Ihrem Tabellentyp gesammelt hätten und dann i als Index verwendet hätten; aber hier ist i ein Datensatztyp. Sie benötigen weder den Tabellentyp noch die Variableninstanz.

Sie haben auch keinen Spaltenalias für SUBSTR(SISR.S1,1,4) hinzugefügt, daher ist die Bezugnahme auf S1 später nicht gültig; und Sie haben die A1/S1-Namen an einigen Stellen durcheinander gebracht, was vielleicht daran liegt, dass Sie die Namen Ihrer echten Spalten manuell ändern, um sie zu verbergen (was in Ordnung ist, aber tun Sie es konsequent).

Also all das korrigieren Sie würden erhalten:

create or replace PROCEDURE   "PRO_1_Table_2_another" AS 

CURSOR C1_CUR IS 
SELECT D.D1 
      ,SUBSTR(SISR.S1,1,4) AS S1 
      ,SISR.S2 
      ,SISR.S3 
      ,SISR.S4 
      ,SISR.S5 
      ,SISR.S6 
      ,SISR.S7 
      ,SISR.S8 
      ,SISR.S9 
    FROM something_in_system_record SISR 
     ,Dump D 
    WHERE SUBSTR(SISR.S1,1,4)=D.D1; 

    BEGIN 

    FOR i in C1_CUR LOOP 

      MERGE INTO In_something TGT 
      USING 
      (SELECT i.S1 AS A1, 
        i.S2 AS A2, 
        i.S3 AS A3, 
        i.S4 AS A4, 
        i.S5 AS A5, 
        i.S6 AS A6, 
        i.S7 AS A7, 
        i.S8 AS A8, 
        i.S9 AS A9 
      FROM DUAL) SRC 
      ON  (SRC.A1 = TGT.A1 
       AND SRC.A2 = TGT.A2 
       AND SRC.A3 = TGT.A3 
       AND SRC.A4 = TGT.A4 
       AND SRC.A5 = TGT.A5 
       AND SRC.A6 = TGT.A6 
       AND SRC.A7 = TGT.A7 
     ) 
      WHEN MATCHED THEN 
      UPDATE SET TGT.A8 = SRC.A8, 
         TGT.A9 = SRC.A9 
      WHEN NOT MATCHED THEN 
      INSERT (TGT.A1 
       ,TGT.A2 
       ,TGT.A3 
       ,TGT.A4 
       ,TGT.A5 
       ,TGT.A6 
       ,TGT.A7 
       ,TGT.A8 
       ,TGT.A9) 
      VALUES 
       (SRC.A1 
       ,SRC.A2 
       ,SRC.A3 
       ,SRC.A4 
       ,SRC.A5 
       ,SRC.A6 
       ,SRC.A7 
       ,SRC.A8 
       ,SRC.A9);   
    END LOOP; 
    COMMIT; 
    EXCEPTION 
    WHEN OTHERS THEN 
    DBMS_OUTPUT.PUT_LINE(SQLCODE||' - '||SQLERRM); 
END "PRO_1_Table_2_another"; 
/

... aber Sie eine separate merge tun für jede Zeile, die Sie in Ihren Cursor finden, was nicht wirklich Sinn macht. Sie können einfach tun:

MERGE INTO In_something TGT 
USING (
    SELECT D.D1 
      ,SUBSTR(SISR.S1,1,4) AS S1 
      ,SISR.S2 
      ,SISR.S3 
      ,SISR.S4 
      ,SISR.S5 
      ,SISR.S6 
      ,SISR.S7 
      ,SISR.S8 
      ,SISR.S9 
    FROM something_in_system_record SISR 
    JOIN Dump D 
    ON SUBSTR(SISR.S1,1,4)=D.D1 
    ) SRC 
ON (
     SRC.S1 = TGT.A1 
    AND SRC.S2 = TGT.A2 
    AND SRC.S3 = TGT.A3 
    AND SRC.S4 = TGT.A4 
    AND SRC.S5 = TGT.A5 
    AND SRC.S6 = TGT.A6 
    AND SRC.S7 = TGT.A7 
) 
WHEN MATCHED THEN 
    UPDATE SET TGT.A8 = SRC.S8, 
      TGT.A9 = SRC.S9 
WHEN NOT MATCHED THEN 
INSERT (TGT.A1 
    ,TGT.A2 
    ,TGT.A3 
    ,TGT.A4 
    ,TGT.A5 
    ,TGT.A6 
    ,TGT.A7 
    ,TGT.A8 
    ,TGT.A9) 
VALUES 
    (SRC.S1 
    ,SRC.S2 
    ,SRC.S3 
    ,SRC.S4 
    ,SRC.S5 
    ,SRC.S6 
    ,SRC.S7 
    ,SRC.S8 
    ,SRC.S9); 

..., die das gleiche tun sollte; und Sie können das immer noch in eine Prozedur stecken, wenn Sie wollen. Es wird normalerweise nicht als eine gute Idee angesehen, innerhalb einer Prozedur zu begehen, aber Sie haben möglicherweise einen legitimen Grund, dies zu tun.

+0

@Alex .... Danke, Sire! Möge das Dach über dir niemals hereinfallen, Und diejenigen, die sich darunter versammelt haben, fallen niemals aus. - Irisches Sprichwort (lesen Sie es irgendwo) – ishan