Oracle
 sql >> Database >  >> RDS >> Oracle

funzione Oracle e cursore utilizzando il nome della tabella dinamica

  • Non è necessario dichiarare un c1 digitare per un cursore di riferimento debolmente digitato. Puoi semplicemente usare il SYS_REFCURSOR digitare.
  • Non puoi mischiare chiamate al cursore implicite ed esplicite in questo modo. Se stai andando su OPEN un cursore, devi FETCH da esso in un ciclo e devi CLOSE esso. Non puoi OPEN e CLOSE ma poi recupera da esso in un ciclo del cursore implicito.
  • Dovrai dichiarare una variabile (o variabili) in cui recuperare i dati. Ho dichiarato un tipo di record e un'istanza di quel record, ma potresti altrettanto facilmente dichiarare due variabili locali e FETCH in quelle variabili.
  • ROWID è una parola riservata, quindi ho usato ROWPOS invece.

Mettendolo insieme, puoi scrivere qualcosa come

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.

Credo che questo restituisca il risultato che ti aspetti

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

Nota che dal punto di vista dell'efficienza, faresti molto meglio a scriverlo come una singola istruzione SQL piuttosto che aprire un cursore e recuperare ogni riga dalla tabella ogni volta. Se sei determinato a utilizzare un cursore, vorrai uscire dal cursore quando hai trovato la riga che ti interessa invece di continuare a recuperare ogni riga dalla tabella.

Dal punto di vista della chiarezza del codice, molti dei nomi delle variabili e dei tipi di dati sembrano piuttosto strani. I nomi dei tuoi parametri sembrano scelti male:non mi aspetterei model_in essere il nome della tabella di input, ad esempio. Dichiarando un cursore chiamato c2 è anche problematico poiché è molto non descrittivo.