2017-02-15 1 views
1

Ich versuche, Gehalt der Mitarbeiter mit Forall aktualisieren. Wenn während der Aktualisierung ein Fehler auftritt, muss ich speichern, für welchen Mitarbeiter-ID-Fehler aufgetreten ist. Aber es gibt Fehler folgende während Fehler Kompilieren (14,24): PLS-00201: Bezeichner 'INDX'Erhalten von IDs fehlgeschlagen für alle Ausnahmen speichern

deklariert werden muss, ist

Unter meinen Code

PROCEDURE PROC1 (V_EMP_ID DBMS_SQL.NUMBER_TABLE) 
IS 
    lv_error_string VARCHAR2(4000); 
BEGIN 
    FORALL INDX IN V_EMP_ID.FIRST..V_EMP_ID.LAST SAVE EXCEPTIONS 
    EXECUTE IMMEDIATE 'UPDATE EMPLOYEES SET SALARY=SALARY+10000 WHERE EMP_ID=:1' 
    USING V_EMP_ID(INDX); 
EXCEPTION 
    WHEN OTHERS 
    THEN 
    FOR J IN 1 .. SQL%BULK_EXCEPTIONS.COUNT 
    LOOP 
     lv_error_string:=lv_error_string 
        ||sqlerrm (-sql%bulk_exceptions(j).error_code) 
        || ' for'||V_EMP_ID(INDX); 
    END LOOP; 
END; 

Antwort

2

verwenden: Der Fehler ist, dass in exception block Sie versuchen, auf eine Schleifenvariable zuzugreifen, die in begin block verwendet wird.

So Ihr || ' for'||V_EMP_ID(INDX); sollte || ' for'||V_EMP_ID(J);

CREATE OR REPLACE PROCEDURE PROC1 (V_EMP_ID DBMS_SQL.NUMBER_TABLE) 
IS 
    lv_error_string VARCHAR2(4000); 
BEGIN 
    FORALL INDX IN V_EMP_ID.FIRST..V_EMP_ID.LAST SAVE EXCEPTIONS 
    EXECUTE IMMEDIATE 'UPDATE EMPLOYEES SET SALARY=SALARY+10000 WHERE EMP_ID=:1' 
    USING V_EMP_ID(INDX); 
EXCEPTION 
    WHEN OTHERS 
    THEN 
    FOR J IN 1 .. SQL%BULK_EXCEPTIONS.COUNT 
    LOOP 
     lv_error_string:=lv_error_string 
        ||sqlerrm (-sql%bulk_exceptions(j).error_code) 
        || ' for'||V_EMP_ID(J); 
    END LOOP; 
END; 

Nicht sicher, warum Sie Execute Immediate verwenden, wenn Sie leicht wie unten tun können:

CREATE OR REPLACE PROCEDURE PROC1 (V_EMP_ID DBMS_SQL.NUMBER_TABLE) 
IS 
    lv_error_string VARCHAR2(4000); 
BEGIN 
    FORALL INDX IN V_EMP_ID.FIRST..V_EMP_ID.LAST SAVE EXCEPTIONS 
    UPDATE EMPLOYEES 
    SET SALARY=SALARY+10000 
    WHERE EMP_ID= V_EMP_ID(INDX); 

EXCEPTION 
    WHEN OTHERS 
    THEN 
    FOR J IN 1 .. SQL%BULK_EXCEPTIONS.COUNT 
    LOOP 
     lv_error_string:=lv_error_string 
        ||sqlerrm (-sql%bulk_exceptions(j).error_code) 
        || ' for'||V_EMP_ID(J); 
    END LOOP; 
END; 
+0

Das funktioniert aber nicht geben Sie mir ein Mitarbeiter-ID, für die Fehler @ XING aufgetreten – PTK

+0

So zu Ihrer Frage kommenden bin nicht sicher, warum machst du ein 'ausführen sofort 'wenn Sie das' update' direkt ausführen können. Siehe meinen aktualisierten Beitrag. Sie erhalten keine 'employee_id', denn Orakel findet keine Ausnahme. – XING

0

Ich würde vorschlagen, mit einer einzigen DML-Anweisung zu gehen. Und ja DML Fehler loggins ist possible.Hope das hilft

--Creating a error log table 
BEGIN 
    DBMS_ERRLOG.create_error_log (dml_table_name => 'EMPLOYEES'); 
END; 
/
--ERR$_EMPLOYEES --> Errro table created 


--Insertion with erroreous record 
UPDATE EMPLOYEES 
SET SALARY   = SALARY + 10000 
where EMP_ID    in (<EMP_ID COLLECTION array 
OR simple EMP_IDs>) LOG ERRORS 
INTO ERR$_EMPLOYEES ('UPDATE') REJECT LIMIT UNLIMITED; 

--Error will be logged into ERR$_EMPLOYEES table 
+1

LOG ERRORS ist eine großartige Idee, aber denken Sie daran, dass Zeilen, die erfolgreich in einer einzelnen Anweisung geändert wurden, erhalten bleiben. Dies unterscheidet sich sehr von SAVE EXCEPTIONS (Unterdrückung von Fehler auf Anweisungsebene). –

+0

Ja. Ich habe hier nur Zeilenfehler behandelt –

Verwandte Themen