- Nie ma potrzeby deklarowania
c1
type dla słabo wpisanego kursora ref. Możesz po prostu użyćSYS_REFCURSOR
typ. - Nie można mieszać niejawnych i jawnych wywołań kursora w ten sposób. Jeśli zamierzasz
OPEN
kursor, musiszFETCH
z niego w pętli i musiszCLOSE
to. Nie możeszOPEN
iCLOSE
go, ale potem pobiera z niego w niejawnej pętli kursora. - Będziesz musiał zadeklarować zmienną (lub zmienne), do której będą pobierane dane. Zadeklarowałem typ rekordu i instancję tego rekordu, ale równie łatwo możesz zadeklarować dwie zmienne lokalne i
FETCH
do tych zmiennych. ROWID
jest słowem zastrzeżonym, więc użyłemROWPOS
zamiast tego.
Łącząc to, możesz napisać coś takiego
SQL> ed
Wrote file afiedt.buf
1 CREATE OR REPLACE Function Findposition (
2 model_in IN varchar2,
3 model_id IN number)
4 RETURN number
5 IS
6 cnumber number;
7 c2 sys_refcursor;
8 type result_rec is record (
9 id number,
10 rowpos number
11 );
12 l_result_rec result_rec;
13 BEGIN
14 open c2 FOR 'SELECT id,ROW_NUMBER() OVER ( ORDER BY id) AS rowpos FROM '||model_in;
15 loop
16 fetch c2 into l_result_rec;
17 exit when c2%notfound;
18 IF l_result_rec.id=model_id
19 then
20 cnumber :=l_result_rec.rowpos;
21 end if;
22 END LOOP;
23 close c2;
24 RETURN cnumber;
25* END;
SQL> /
Function created.
Uważam, że to zwraca oczekiwany wynik
SQL> create table foo( id number );
Table created.
SQL> insert into foo
2 select level * 2
3 from dual
4 connect by level <= 10;
10 rows created.
SQL> select findposition( 'FOO', 8 )
2 from dual;
FINDPOSITION('FOO',8)
---------------------
4
Zauważ, że z punktu widzenia wydajności znacznie lepiej byłoby napisać to jako pojedyncze polecenie SQL, niż otwierać kursor i za każdym razem pobierać każdy wiersz z tabeli. Jeśli jesteś zdecydowany użyć kursora, wolałbyś wyjść z niego po znalezieniu wiersza, który Cię interesuje, zamiast kontynuować pobieranie każdego wiersza z tabeli.
Z punktu widzenia przejrzystości kodu wiele nazw zmiennych i typów danych wydaje się dość dziwnych. Twoje nazwy parametrów wydają się źle dobrane — nie spodziewałbym się, że model_in
być nazwą tabeli wejściowej, na przykład. Deklarowanie kursora o nazwie c2
jest również problematyczny, ponieważ jest bardzo nieopisowy.