Pierwsze nieudane identyfikatorów ze wszystkim zaoszczędzić wyjątki

głosy
1

Próbuję zaktualizować wynagrodzenia pracowników korzystających forall. Gdy wystąpi jakiś błąd podczas aktualizacji muszę zapisać, dla którego id pracownik wystąpił błąd. Ale daje następujący błąd podczas kompilacji błąd (14,24): PLS-00201: identyfikator 'INDX muszą być zadeklarowane

Poniżej jest kod

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;
Utwórz 15/02/2017 o 04:26
użytkownik
W innych językach...                            


2 odpowiedzi

głosy
2

Użyj tego: Błąd jest, że exception blockpróbujesz uzyskać dostęp do zmiennej pętli, który jest używany w begin block.

Więc || ' for'||V_EMP_ID(INDX);powinno być|| ' 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;

Nie wiem, dlaczego używasz Execute Immediate, kiedy można łatwo zrobić jak poniżej:

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;
Odpowiedział 15/02/2017 o 05:31
źródło użytkownik

głosy
0

Proponuję, aby przejść z jednej instrukcji DML. I tak DML Loggins błędu jest possible.Hope to pomaga

--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
Odpowiedział 15/02/2017 o 07:37
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more