- Il n'est pas nécessaire de déclarer un
c1
type pour un curseur de référence faiblement typé. Vous pouvez simplement utiliser leSYS_REFCURSOR
taper. - Vous ne pouvez pas mélanger des appels de curseur implicites et explicites comme celui-ci. Si vous allez
OPEN
un curseur, il fautFETCH
en boucle et vous devezCLOSE
ce. Vous ne pouvez pasOPEN
etCLOSE
puis récupérez-le dans une boucle de curseur implicite. - Vous devrez déclarer une variable (ou des variables) dans laquelle récupérer les données. J'ai déclaré un type d'enregistrement et une instance de cet enregistrement, mais vous pouvez tout aussi bien déclarer deux variables locales et
FETCH
dans ces variables. ROWID
est un mot réservé donc j'ai utiliséROWPOS
à la place.
En mettant cela ensemble, vous pouvez écrire quelque chose comme
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.
Je crois que cela renvoie le résultat que vous attendez
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
Notez que du point de vue de l'efficacité, vous feriez bien mieux d'écrire ceci comme une seule instruction SQL plutôt que d'ouvrir un curseur et de récupérer chaque ligne de la table à chaque fois. Si vous êtes déterminé à utiliser un curseur, vous devriez quitter le curseur lorsque vous avez trouvé la ligne qui vous intéresse plutôt que de continuer à extraire chaque ligne de la table.
Du point de vue de la clarté du code, bon nombre de vos noms de variables et types de données semblent plutôt étranges. Vos noms de paramètres semblent mal choisis - je ne m'attendrais pas à model_in
être le nom de la table d'entrée, par exemple. Déclarer un curseur nommé c2
est également problématique car il est très peu descriptif.