ORA-01422 - przy próbie UPDATE kilku rekordów

0

Cześć,
napisałem poniższy trigger który ma przy spełnieniu pewnego warunku zrobić UPDATE w jednej kolumnie ale na jednym lub wielu rekordach w zależności od tego co wybierze kursor. Zrobiłem sobie tabelkę pomocniczą w której zapisywałem wybrane przez kursor rekordy czy jest prawidłowo i to co wybrał zgadzało się z tym co powinien zUpdatować.
Niestety przy próbie uruchomienia triggera mam błąd :(

Error report -
SQL Error: ORA-01422: dokładne pobranie zwraca większą liczbę wierszy niż zamówiono
ORA-06512: przy "HR.AKT_POLOWANIA", linia 9
ORA-04088: błąd w trakcie wykonywania wyzwalacza 'HR.AKT_POLOWANIA'
ORA-06512: przy "HR.AKT_POLOWANIA", linia 20
ORA-04088: błąd w trakcie wykonywania wyzwalacza 'HR.AKT_POLOWANIA'
01422. 00000 - "exact fetch returns more than requested number of rows"
*Cause: The number specified in exact fetch is less than the rows returned.
*Action: Rewrite the query or change number of rows requested

Poniżej trigger :

create or replace trigger akt_polowania
after insert or update on polowania
Declare
v_limit number(3);
v_ile number(3);
v_gromadka varchar2(20);
v_date varchar2(20);

cursor c_gromadka is
select krasnal from polowania A, krasnale B where B.gromadka = v_gromadka and B.imie = A.krasnal;

Begin
select gromadka into v_gromadka from krasnale where imie in (select krasnal from pomocnicza);

select sum(months_between(sysdate,data_urodzenia)) into v_limit from krasnale where gromadka = v_gromadka;

select to_char(data_polowania) into v_date from pomocnicza;

select sum(liczba_much) into v_ile from polowania where data_polowania = v_date and krasnal in (select imie from krasnale where gromadka = v_gromadka);

if v_ile >= v_limit then
for i in c_gromadka loop
--insert into liczkrasnal values(i.krasnal);
update polowania
set jest_limit = 'T'
where data_polowania = v_date and krasnal = i.krasnal;
end loop;
end if;

delete from pomocnicza;

End;
/
show errors

Może jakieś uwagi ? Sugestie ?

Pozdrawiam.
Pewex

0

Po pierwsze stosuj formatowanie po drugie przecież to oczywiste komunikat mówi dokładnie co zmaściłeś. Robiąc select ... into zmienna musisz zapewnić, że select zwróci tylko jeden rekord. Na moje oko sypie się na tym pierwszym zapytaniu:

select gromadka into v_gromadka from krasnale where imie in (select krasnal from pomocnicza);
0

woolfik, sorki za brak formatowania.
Na tym pierwszym zapytaniu się nie wywala. Jak robię Insert lub Update do tabeli gdzie warunek na UPDATE kolumny nie jest spełniony, wtedy trigger przechodzi. Dopiero jak ma zabrać się za UPDATE wyrzuca błąd.

1

O masakra ...
Robisz coś co odpala triggera, który jest: after insert or update on polowania
Następnie wewnątrz triggera ponownie robisz update na tabeli polowania więc tym samym odpalasz triggera ponownie ...
W takim wypadku prawdopodobnie któryś z selectów ma już dwa lub więcej rekordów i wykonanie INTO jest niemożliwe generując wyjątek.

Jak mi nie wierzysz to zrób sobie for zamiast into (zliczaj ilość wywołań i zapisz sobie gdzieś do tabeli tymczasowej/logów) i zobaczysz, że mam rację.
PS jak chcesz kogoś "zawołać" to przed jego nickiego wstaw @ dzięki temu dostanie on powiadomienie czyli wołam @Pewex
PS2. Nie przepraszaj tylko wejdź w edycję i dodaj formatowanie ;)
PS3. Robiąc takie machlojki, że z poziomu triggera aktualizujesz coś na tabeli której dotyczy trigger może dochodzić (np przy zapytaniu) do mutowania wyzwalacza. Staraj się unikać tego typu konstrukcji bo przy bardzo rozbudowanych systemach ciężko jest to potem odkręcić.

0

Dzięki ! masz rację skoro wewnątrz triggera odpalam UPDATE na tabeli na której działa trigger to nie może to zadziałać :)
Zamotałem się!

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