- Il n'est pas nécessaire de déclarer un
c1type pour un curseur de référence faiblement typé. Vous pouvez simplement utiliser leSYS_REFCURSORtaper. - Vous ne pouvez pas mélanger des appels de curseur implicites et explicites comme celui-ci. Si vous allez
OPENun curseur, il fautFETCHen boucle et vous devezCLOSEce. Vous ne pouvez pasOPENetCLOSEpuis 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
FETCHdans ces variables. ROWIDest 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.