Oracle
 sql >> Base de données >  >> RDS >> Oracle

fonction oracle et curseur utilisant le nom de table dynamique

  • 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 le SYS_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 faut FETCH en boucle et vous devez CLOSE ce. Vous ne pouvez pas OPEN et CLOSE 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.