Kursory/Wyjątki - problem

0

Witam mam oto taki problem ze gdy wpisuje złą nazwę stanowiska to nie wyskakuje mi błąd że Nie istnieje stanowisko o takiej nazwie tylko wyskakuje "pracownicy na stanowisku sdsadsad i nie podaje pracowników bo oczywiście ich nie ma" ,... moglibyście doradzić gdzie mam błąd :/ ??

DECLARE
    V_STANOWISKO EMPLOYEES.JOB_ID%TYPE:='&NAZWA_STANOWISKA';
CURSOR ZADANIE2 IS
    SELECT LAST_NAME FROM EMPLOYEES
                    WHERE JOB_ID = V_STANOWISKO;
BEGIN
    DBMS_OUTPUT.PUT_LINE('Pracownicy na stanowisku: ' || v_stanowisko);
FOR
V_STANOWISKO IN ZADANIE2
LOOP
IF ZADANIE2%NOTFOUND THEN
    raise_application_error(-20001,'Nie istnieje stanowisko o takiej nazwie ');
    ELSE
        DBMS_OUTPUT.PUT_LINE(V_STANOWISKO.LAST_NAME );
    END IF;
END LOOP;
END;
2

Skoro kursor jest pusty, wnętrze pętli nie zostaje uruchomione (a zatem i Twój warunek jest pomijany); spróbuj przenieść if zadanie2%notfound przed pętlę.

0
Patryk27 napisał(a):

Skoro kursor jest pusty, wnętrze pętli nie zostaje uruchomione (a zatem i Twój warunek jest pomijany); spróbuj przenieść if zadanie2%notfound przed pętlę.

kiedy dałem przed pętle to wtedy po else "DBMS_OUTPUT.PUT_LINE(V_STANOWISKO.LAST_NAME );" jest podkreślone na czerwono jakby nie mogło tam być

IF ZADANIE2%NOTFOUND THEN
FOR
V_STANOWISKO IN ZADANIE2
LOOP
    raise_application_error(-20001,'Nie istnieje departament onazwie ');
    ELSE
        DBMS_OUTPUT.PUT_LINE(V_STANOWISKO.LAST_NAME );
    END IF;
0

A mógłbyś sformatować ten kod? ;-]

0
Patryk27 napisał(a):

A mógłbyś sformatować ten kod? ;-]

DECLARE
    V_STANOWISKO EMPLOYEES.JOB_ID%TYPE:=UPPER('&NAZWA_STANOWISKA');
CURSOR ZADANIE2 IS
    SELECT LAST_NAME FROM EMPLOYEES
                    WHERE JOB_ID = V_STANOWISKO;
BEGIN
    DBMS_OUTPUT.PUT_LINE('Pracownicy na stanowisku: ' || v_stanowisko);
    IF ZADANIE2%NOTFOUND THEN
FOR
V_STANOWISKO IN ZADANIE2
LOOP
    raise_application_error(-20001,'Nie istnieje stanowisko o takiej nazwie ');
    else
        DBMS_OUTPUT.PUT_LINE(V_STANOWISKO.LAST_NAME );
    END IF;
END LOOP;
END;
ORA-06550: linia 13, kolumna 5:
PLS-00103: Napotkano symbol "ELSE" gdy oczekiwano jednego z następujących:

   ( begin case declare end exit for goto if loop mod null
   pragma raise return select update while with <an identifier>
   <a double-quoted delimited-identifier> <a bind variable> <<
   continue close current delete fetch lock insert open rollback
   savepoint set sql execute commit forall merge pipe purge
   json_exists json_value json_query json_object json_array
ORA-06550: linia 16, kolumna 1:
PLS-00103: Napotkano symbol "END" 
06550. 00000 -  "line %s, column %s:\n%s"
*Cause:    Usually a PL/SQL compilation error.
*Action:
0

Prawie, prawie:

BEGIN
    DBMS_OUTPUT.PUT_LINE('Pracownicy na stanowisku: ' || v_stanowisko);
    IF ZADANIE2%NOTFOUND THEN
        FOR V_STANOWISKO IN ZADANIE2 LOOP
            raise_application_error(-20001,'Nie istnieje stanowisko o takiej nazwie '); -- jesteś pewien, że chcesz to mieć _wewnątrz_ pętli?
            else -- do czego to się odnosi?
                DBMS_OUTPUT.PUT_LINE(V_STANOWISKO.LAST_NAME );
            END IF; -- do czego to się odnosi?
        END LOOP;
    END; -- dopiero tutaj na prawdę kończy się instrukcja warunkowa
END;
0
DECLARE
    V_STANOWISKO EMPLOYEES.JOB_ID%TYPE:=UPPER('&NAZWA_STANOWISKA');
CURSOR ZADANIE2 IS
    SELECT LAST_NAME FROM EMPLOYEES
                    WHERE JOB_ID = V_STANOWISKO;
BEGIN
    DBMS_OUTPUT.PUT_LINE('Pracownicy na stanowisku: ' || v_stanowisko);
    IF ZADANIE2%FOUND THEN
FOR
V_STANOWISKO IN ZADANIE2
LOOP
    DBMS_OUTPUT.PUT_LINE(V_STANOWISKO.LAST_NAME ); 
END LOOP;
END IF;
END;
EXCEPTION WHEN NO_DATA_FOUND
THEN 
raise_application_error(-20001,'Nie istnieje stanowisko o takiej nazwie ');
END;

kombinuje kombinuje ale nadal źle

0
  1. Formatowanie kodu.
  2. Co to znaczy nadal źle? Policja Cię chce aresztować? Komputer Ci wybuchnął? Istotne są wszystkie detale.
0
DECLARE
    V_STANOWISKO EMPLOYEES.JOB_ID%TYPE:=UPPER('&NAZWA_STANOWISKA');
CURSOR ZADANIE2 IS
    SELECT LAST_NAME FROM EMPLOYEES
                    WHERE JOB_ID = V_STANOWISKO;
BEGIN
    DBMS_OUTPUT.PUT_LINE('Pracownicy na stanowisku: ' || v_stanowisko);
    IF ZADANIE2%FOUND THEN
FOR
V_STANOWISKO IN ZADANIE2
LOOP
    DBMS_OUTPUT.PUT_LINE(V_STANOWISKO.LAST_NAME ); 
END LOOP;
END IF;
END;
EXCEPTION WHEN NO_DATA_FOUND
THEN 
raise_application_error(-20001,'Nie istnieje stanowisko o takiej nazwie ');
END;

Error report -
ORA-06550: linia 19, kolumna 6:
PLS-00103: Napotkano symbol "" 
06550. 00000 -  "line %s, column %s:\n%s"
*Cause:    Usually a PL/SQL compilation error.
*Action:
0

Nie poprawiłeś formatowania kodu - porównaj wcięcia w Twoim vs moim.

0
DECLARE
    V_STANOWISKO EMPLOYEES.JOB_ID%TYPE:=UPPER('&NAZWA_STANOWISKA');
CURSOR ZADANIE2 IS
    SELECT LAST_NAME FROM EMPLOYEES
                    WHERE JOB_ID = V_STANOWISKO;
BEGIN
        DBMS_OUTPUT.PUT_LINE('Pracownicy na stanowisku: ' || v_stanowisko);
        IF ZADANIE2%FOUND THEN
            FOR V_STANOWISKO IN ZADANIE2 LOOP
            DBMS_OUTPUT.PUT_LINE(V_STANOWISKO.LAST_NAME ); 
        END LOOP;
    END IF;
END;
    EXCEPTION WHEN NO_DATA_FOUND
        THEN 
        raise_application_error(-20001,'Nie istnieje stanowisko o takiej nazwie ');
END;
0

No, prawie :-)

BEGIN
    DBMS_OUTPUT.PUT_LINE('Pracownicy na stanowisku: ' || v_stanowisko);
    IF ZADANIE2%FOUND THEN
        FOR V_STANOWISKO IN ZADANIE2 LOOP
            DBMS_OUTPUT.PUT_LINE(V_STANOWISKO.LAST_NAME ); 
        END LOOP;
    END IF;
END;
EXCEPTION
    WHEN NO_DATA_FOUND THEN 
        raise_application_error(-20001,'Nie istnieje stanowisko o takiej nazwie ');
END;

Teraz dostrzegasz błąd?

0

błąd teraz wskazuje na linie 17 czyli jak się zaczyna od exception...

Error report -
ORA-06550: linia 17, kolumna 6:
PLS-00103: Napotkano symbol "" 
06550. 00000 -  "line %s, column %s:\n%s"
*Cause:    Usually a PL/SQL compilation error.
*Action:
0
BEGIN
  -- /* ... */
END; -- ta instrukcja kończy cały blok (zakańcza `BEGIN`)
EXCEPTION -- .. podczas gdy `EXCEPTION` musi znajdować się jeszcze _wewnątrz_ bloku
  -- /* ... */
END;

Prawidłowo powinno to wyglądać tak:

BEGIN
  -- /* ... */
EXCEPTION
  -- /* ... */
END;
0

niestety jak poprawiłem exception przed END wskazuje nadal na ten sam błąd

ORA-06550: linia 17, kolumna 6:
PLS-00103: Napotkano symbol "" 
0

Ponownie: wrzuć cały kod.

0
DECLARE
    V_STANOWISKO EMPLOYEES.JOB_ID%TYPE:=UPPER('&NAZWA_STANOWISKA');
CURSOR ZADANIE2 IS
    SELECT LAST_NAME FROM EMPLOYEES
                    WHERE JOB_ID = V_STANOWISKO;
BEGIN
        DBMS_OUTPUT.PUT_LINE('Pracownicy na stanowisku: ' || v_stanowisko);
        IF ZADANIE2%FOUND THEN
            FOR V_STANOWISKO IN ZADANIE2 LOOP
            DBMS_OUTPUT.PUT_LINE(V_STANOWISKO.LAST_NAME ); 
        END LOOP;
    END IF;
    EXCEPTION 
        WHEN NO_DATA_FOUND THEN 
            raise_application_error(-20001,'Nie istnieje stanowisko o takiej nazwie');
    END;
END;
0

Wersja z poprawionym formatowaniem:

BEGIN
    DBMS_OUTPUT.PUT_LINE('Pracownicy na stanowisku: ' || v_stanowisko);
    IF ZADANIE2%FOUND THEN
        FOR V_STANOWISKO IN ZADANIE2 LOOP
            DBMS_OUTPUT.PUT_LINE(V_STANOWISKO.LAST_NAME);
        END LOOP;
    END IF;
EXCEPTION 
    WHEN NO_DATA_FOUND THEN 
        raise_application_error(-20001,'Nie istnieje stanowisko o takiej nazwie');
END;
END; -- do czego odnosi się ten `end`?
0
DECLARE
    V_STANOWISKO EMPLOYEES.JOB_ID%TYPE:=UPPER('&NAZWA_STANOWISKA');
CURSOR ZADANIE2 IS
    SELECT LAST_NAME FROM EMPLOYEES
                    WHERE JOB_ID = V_STANOWISKO;
BEGIN
        DBMS_OUTPUT.PUT_LINE('Pracownicy na stanowisku: ' || v_stanowisko);
        IF ZADANIE2%FOUND THEN
            FOR V_STANOWISKO IN ZADANIE2 LOOP
            DBMS_OUTPUT.PUT_LINE(V_STANOWISKO.LAST_NAME ); 
        END LOOP;
    END IF;
 EXCEPTION 
    WHEN NO_DATA_FOUND THEN 
            raise_application_error(-20001,'Nie istnieje stanowisko o takiej nazwie');
END;
Error report -
ORA-01001: niepoprawny kursor
ORA-06512: przy linia 8
01001. 00000 -  "invalid cursor"
*Cause:    
*Action:
0

Nie powinieneś otworzyć kursora przed rozpoczęciem pracy na nim?

0
DECLARE
    V_STANOWISKO EMPLOYEES.JOB_ID%TYPE:=UPPER('&NAZWA_STANOWISKA');
CURSOR ZADANIE2 IS
    SELECT LAST_NAME FROM EMPLOYEES
                    WHERE JOB_ID = V_STANOWISKO;
BEGIN
    OPEN ZADANIE2;
        DBMS_OUTPUT.PUT_LINE('Pracownicy na stanowisku: ' || v_stanowisko);
    IF ZADANIE2%FOUND THEN
        FOR V_STANOWISKO IN ZADANIE2 LOOP
        DBMS_OUTPUT.PUT_LINE(V_STANOWISKO.LAST_NAME ); 
        END LOOP;
    END IF;
 EXCEPTION 
    WHEN NO_DATA_FOUND THEN 
            raise_application_error(-20001,'Nie istnieje stanowisko o takiej nazwie');
    CLOSE zadanie2;
END;

jak źle wpisuje to nie wyskakuje błąd a jak dobrze wpisuje to juz nie pokazuje nazwisk pracowników

Pracownicy na stanowisku: SADSA

Pracownicy na stanowisku: IT_PROG


0

Hmm - dlaczego tak właściwie myślisz, że w tym wypadku zostanie rzucony wyjątek NO_DATA_FOUND?

Mógłbyś przytoczyć jakiś fragment z dokumentacji, który o tym mówi? :-)

0

czyli exception trzeba rzucić wyżej?? lub else tam gdzie if i raise_application_error
dopiero sie ucze :D

0

Sorki....
"SQL zgłasza predefiniowany wyjątek NO_DATA_FOUND, jeśli instrukcja SELECT INTO nie zwraca wierszy." czyli nie ma takiej instrukcji

0

Tak - nie masz tutaj select into, a zatem nie otrzymasz no_data_found :-)

Twoje początkowe podejście było IMO sensowniejsze:

BEGIN
    OPEN ZADANIE2;

    IF ZADANIE2%NOT_FOUND THEN
        raise_application_error(...);
    END IF;

    DBMS_OUTPUT.PUT_LINE('Pracownicy na stanowisku: ' || v_stanowisko);

    FOR V_STANOWISKO IN ZADANIE2 LOOP
        DBMS_OUTPUT.PUT_LINE(V_STANOWISKO.LAST_NAME);
    END LOOP;
END;
0
DECLARE
    V_STANOWISKO EMPLOYEES.JOB_ID%TYPE:=UPPER('&NAZWA_STANOWISKA');
CURSOR ZADANIE2 IS
    SELECT LAST_NAME FROM EMPLOYEES
                    WHERE JOB_ID = V_STANOWISKO;
BEGIN
    OPEN ZADANIE2;
    IF ZADANIE2%NOTFOUND THEN
        raise_application_error(-20001,'Nie istnieje stanowisko o takiej nazwie');
    END IF;
            DBMS_OUTPUT.PUT_LINE('Pracownicy na stanowisku: ' || v_stanowisko);
        FOR V_STANOWISKO IN ZADANIE2 LOOP
            DBMS_OUTPUT.PUT_LINE(V_STANOWISKO.LAST_NAME ); 
        END LOOP;
    CLOSE ZADANIE2;
END;
ORA-06511: PL/SQL: kursor jest już otwarty
ORA-06512: przy linia 4
ORA-06512: przy linia 12
06511. 00000 -  "PL/SQL: cursor already open"
*Cause:    An attempt was made to open a cursor that was already open.
*Action:   Close cursor first before reopening.
1

Nie jestem Oraclo-specem, więc te komunikaty są dla mnie równie nieczytelne - być może for próbuje otworzyć kursor drugi raz; spróbuj zamienić for na klasyczną pętlę z wykorzystaniem fetch.

0

w zadaniu mam niestety użyć pętli for :/

0

W takim razie na pałę wrzucone close zadanie2; tuż przed pętlą pewnie wystarczy :-P

0
DECLARE
    V_STANOWISKO EMPLOYEES.JOB_ID%TYPE:=UPPER('&NAZWA_STANOWISKA');
CURSOR ZADANIE2 IS
    SELECT LAST_NAME FROM EMPLOYEES
                    WHERE JOB_ID = V_STANOWISKO;
BEGIN
    OPEN ZADANIE2;
    IF ZADANIE2%NOTFOUND THEN
        raise_application_error(-20001,'Nie istnieje stanowisko o takiej nazwie');
    END IF; 
            DBMS_OUTPUT.PUT_LINE('Pracownicy na stanowisku: ' || v_stanowisko);
    CLOSE ZADANIE2;
        FOR V_STANOWISKO IN ZADANIE2 LOOP
            DBMS_OUTPUT.PUT_LINE(V_STANOWISKO.LAST_NAME ); 
           
        END LOOP;
END;

Jak daję przed for zamknięcie to działa tylko w jedną stronę ( przy podaniu poprawnej nazwy , przy błędnej nie wyskakuje nic oprócz

Pracownicy na stanowisku: ASDSA

(i tutaj nic ) 

a w oknie output :

PL/SQL procedure successfully completed.

1 użytkowników online, w tym zalogowanych: 0, gości: 1