Como e quando usar sys_refcursor no oracle


Respostas:


10

Um cursor é um ponteiro para um conjunto de resultados para uma consulta. Ao retornar um, sys_refcursorvocê permite que o cliente busque quantas ou poucas linhas da consulta forem necessárias. Em aplicativos com estado, isso pode ser usado para paginar os resultados.

Um cursor pode permitir mais flexibilidade do que escrever uma função PL / SQL que retorna uma matriz, pois depende completamente do cliente quantas linhas buscar e quando parar. Dito isto, não encontrei muitos casos em que essa flexibilidade adicional seja útil.

Vale ressaltar que o tipo sys_refcursoré fracamente digitado, para que você possa retornar ponteiros para consultas que não apenas possuem cláusulas diferentes ou onde, mas também números e tipos diferentes de colunas. Como alternativa, você pode usar um cursor fortemente digitado onde as colunas no conjunto de resultados são fixas.

Isso permite que você escreva funções que retornam consultas diferentes, como:

create function get_data ( type varchar2 ) return sys_refcursor as
  ret_cur sys_refcursor;
begin

  if type = 'EMP' then
    open ret_cur for select * from emp;
  elsif type = 'DEPT' then
    open ret_cur for select * from dept;
  end if;

  return ret_cur;
end;

No entanto, se você estiver usando sys_refcursorpara criar uma função genérica de "abrir uma consulta" como a acima, provavelmente está fazendo algo errado!


@ Chris ... por que sua função de exemplo está "errada?"
Johnny Wu

2
@JohnnyWu será uma tarefa mais difícil de gerenciar. Como você testa para garantir que obtenha os resultados certos em todos os casos? E a segurança? Isso pode ser necessário se você estiver construindo uma estrutura. Mas para a lógica de negócios em geral, é melhor ter separadas get_empse get_deptsfunções
Chris Saxon

1

Como um exemplo das possibilidades: como o pl / sql está de volta, é possível definir um objeto para representar uma linha, definir uma tabela pl / sql desses objetos,

create type T_MY_TABLE as table of t_my_object;

e termine com

OPEN p_recordset FOR select * from table( v_my_table );

Portanto, em vez de construir consultas diretas mongo, muitas vezes densas e / ou enigmáticas em uma tabela de banco de dados, é possível criar uma tabela interna e ter todo o poder do pl / sql para preenchê-la. E o cliente que coleta o conjunto de resultados não é o mais sábio. E mudar a definição da tabela interna é mais fácil do ponto de vista de gerenciamento do que alterar uma tabela do banco de dados.

Além disso, ao usar geradores de relatórios como o Jasper, você pode enviar o SQL para fora do relatório e entrar no banco de dados e apenas chamar o procedimento para obter o conjunto de registros, deixando o lado do relatório focado na formatação.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.