sql >> Base de Datos >  >> RDS >> Oracle

función de oráculo y cursor usando el nombre de la tabla dinámica

  • No hay necesidad de declarar un c1 escriba para un cursor de referencia débilmente escrito. Puedes simplemente usar el SYS_REFCURSOR escriba.
  • No puede mezclar llamadas de cursor implícitas y explícitas como esta. Si vas a OPEN un cursor, tienes que FETCH de él en un bucle y tienes que CLOSE eso. No puedes OPEN y CLOSE pero luego obtenerlo en un bucle de cursor implícito.
  • Tendrá que declarar una variable (o variables) para obtener los datos. Declaré un tipo de registro y una instancia de ese registro, pero podría declarar fácilmente dos variables locales y FETCH en esas variables.
  • ROWID es una palabra reservada, así que usé ROWPOS en su lugar.

Poniendo eso junto, puedes escribir algo como

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.

Creo que esto devuelve el resultado que esperas

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

Tenga en cuenta que, desde el punto de vista de la eficiencia, sería mucho mejor escribir esto como una sola instrucción SQL en lugar de abrir un cursor y obtener cada fila de la tabla cada vez. Si está decidido a usar un cursor, querrá salir del cursor cuando haya encontrado la fila que le interesa en lugar de continuar buscando cada fila de la tabla.

Desde el punto de vista de la claridad del código, muchos de sus nombres de variables y tipos de datos parecen bastante extraños. Los nombres de sus parámetros parecen mal elegidos:no esperaría model_in ser el nombre de la tabla de entrada, por ejemplo. Declarar un cursor llamado c2 también es problemático ya que es muy poco descriptivo.