Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

função oracle e cursor usando o nome da tabela dinâmica

  • Não há necessidade de declarar um c1 type para um cursor de referência fracamente tipado. Você pode simplesmente usar o SYS_REFCURSOR tipo.
  • Você não pode misturar chamadas de cursor implícitas e explícitas como esta. Se você for OPEN um cursor, você deve FETCH dele em um loop e você tem que CLOSE isto. Você não pode OPEN e CLOSE mas, em seguida, busque-o em um loop de cursor implícito.
  • Você terá que declarar uma variável (ou variáveis) para buscar os dados. Eu declarei um tipo de registro e uma instância desse registro, mas você poderia facilmente declarar duas variáveis ​​locais e FETCH nessas variáveis.
  • ROWID é uma palavra reservada, então usei ROWPOS em vez disso.

Juntando isso, você pode escrever 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.

Acredito que isso retorne o resultado que você espera
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

Observe que, do ponto de vista da eficiência, seria muito melhor escrever isso como uma única instrução SQL em vez de abrir um cursor e buscar todas as linhas da tabela todas as vezes. Se você estiver determinado a usar um cursor, deverá sair do cursor quando encontrar a linha em que está interessado, em vez de continuar buscando cada linha da tabela.

Do ponto de vista da clareza do código, muitos de seus nomes de variáveis ​​e tipos de dados parecem bastante estranhos. Seus nomes de parâmetros parecem mal escolhidos - eu não esperaria model_in para ser o nome da tabela de entrada, por exemplo. Declarando um cursor chamado c2 também é problemático, pois é muito não descritivo.