Oracle Procedura

0

Witam, mam następujący problem. Staram się stworzyć procedurę, która wypisuje preferencje danego klienta. Stworzyłem selecta, który działa bezbłędnie, następnie umieściłem go w procedurze do której mam tylko wprowadzić ID klienta. Przy wywoływaniu procedury dostaję taki błąd:
"wrong number or types of arguments in call to 'PR_PREFERENCJE'"

Tutaj wywołanie procedury:
CALL PR_PREFERENCJE(1);

Oraz kod procedury

 CREATE OR REPLACE PROCEDURE PR_PREFERENCJE 
(
    IDK IN NUMBER,
    F_ID OUT NUMBER,
    F_NAZWA OUT VARCHAR2
) AS 
BEGIN

SELECT F.ID_F, F.NAZWA
INTO F_ID, F_NAZWA
FROM FILM F, KLIENT K, PREFERENCJE PRE, GATUNEK G
WHERE F.ID_F NOT IN    
(
  SELECT DISTINCT F.ID_F    
  FROM KLIENT K, ZAMOWIENIE Z, POZYCJA P, EGZEMPLARZ_FILMU EF, FILM F, GATUNEK G, PREFERENCJE PRE    
  WHERE K.ID_K = IDK AND Z.ID_K = K.ID_K AND P.ID_Z = Z.ID_Z AND P.ID_EF = EF.ID_EF AND EF.ID_F = F.ID_F AND F.ID_G = G.ID_G
)
AND K.ID_P = PRE.ID_P AND PRE.ID_G = G.ID_G AND F.ID_G = G.ID_G AND K.ID_K = IDK
ORDER BY F.ID_F ASC; 

END PR_PREFERENCJE;
0

Masz procedure PR_PREFERENCJE(IN, OUT, OUT) a wywołujesz ją PR_PREFERENCJE(IN).

0

Co muszę dodatkowo wprowadzić jako (OUT,OUT)?

0

Jakieś out-y. Nie wiem gdzie wywołujesz procedure (trochę mi to wygląda na JAVE) ale np z poziomu PL/SQL:

DECLARE
l_f_id_num NUMBER;
l_f_nazwa_var VARCHAR2(100);
BEGIN
PR_PREFERENCJE(1,l_f_id_num,l_f_nazwa_var);
dbms_output.putline("Id: " || l_f_id_num || " Nazwa: " || l_f_nazwa_var);
END;
0

Ta procedura zwraca więcej niż jeden wiersz, przy takim wywołaniu też nie może działać.

0

Znaczy się, że select który wstawiłeś w pierwszym poście zwraca więcej niż jeden rekord? Jeśli tak to bez obsłużenia wyjątku otrzymasz ORA-01422 bo masz INTO.

0

Zgadza się, ta procedura zwraca prawie za każdym razem kilka rekordów, zapomniałem o tym wspomnieć.

0

To zamiast procedury możesz użyć samego zapytania w pętli:

for rec in (SELECT F.ID_F, F.NAZWA
FROM FILM F, KLIENT K, PREFERENCJE PRE, GATUNEK G
WHERE F.ID_F NOT IN    
(
  SELECT DISTINCT F.ID_F    
  FROM KLIENT K, ZAMOWIENIE Z, POZYCJA P, EGZEMPLARZ_FILMU EF, FILM F, GATUNEK G, PREFERENCJE PRE    
  WHERE K.ID_K = IDK AND Z.ID_K = K.ID_K AND P.ID_Z = Z.ID_Z AND P.ID_EF = EF.ID_EF AND EF.ID_F = F.ID_F AND F.ID_G = G.ID_G
)
AND K.ID_P = PRE.ID_P AND PRE.ID_G = G.ID_G AND F.ID_G = G.ID_G AND K.ID_K = IDK
ORDER BY F.ID_F ASC) loop
...
end loop

lub zamiast zmiennych stworzyć typ tablicowy i jego zwracac

0

Nie robię tego dla siebie, dlatego tak nalegam na procedurę. Nie ma innej opcji zrobienia tego?
Ewentualnie, zrobienie tego przy użyciu tablicy, ale nie mam pojęcia jak to zacząć.

0

Po godzinach poszukiwań udało mi się :)
Gdyby kogoś ciekawiło rozwiązanie

 create or replace FUNCTION F_PREFERENCJE(X INTEGER)  
RETURN OPAKOWANIE.TABLICA PIPELINED IS CURSOR kk IS  

SELECT F.ID_F, F.NAZWA
FROM FILM F, KLIENT K, PREFERENCJE PRE, GATUNEK G 
WHERE F.ID_F NOT IN     
(   
SELECT DISTINCT F.ID_F       
FROM KLIENT K, ZAMOWIENIE Z, POZYCJA P, EGZEMPLARZ_FILMU EF, FILM F, GATUNEK G, PREFERENCJE PRE       
WHERE K.ID_K = X AND Z.ID_K = K.ID_K AND P.ID_Z = Z.ID_Z AND P.ID_EF = EF.ID_EF AND EF.ID_F = F.ID_F AND F.ID_G = G.ID_G 
)
AND K.ID_P = PRE.ID_P AND PRE.ID_G = G.ID_G AND F.ID_G = G.ID_G AND K.ID_K = X 
ORDER BY F.ID_F ASC; 

w OPAKOWANIE.WIERSZ;
BEGIN 
OPEN kk; 
LOOP 
FETCH kk into w; 
EXIT WHEN kk%notfound;
PIPE ROW(w); 
END LOOP; 
CLOSE kk; 
RETURN; 
END;
create or replace PACKAGE OPAKOWANIE IS
TYPE WIERSZ IS RECORD(
ID_FILMU NUMBER,
NAZWA VARCHAR2(100)
);
TYPE TABLICA IS TABLE OF WIERSZ;
end;

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