Procedure que retorna mais de uma linha (SELECT)

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
leprado
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 5
Registrado em: Sex, 24 Out 2008 3:44 pm
Localização: Curitiba - PR

Pessoal

Preciso faser uma procedure que retorne mais de uma linha no result set

estou fazendo da seguinte maneira

Selecionar tudo

create or replace procedure TesteSelect(
  cod_regional IN number DEFAULT 0, 
  p_cod_regional OUT NUMBER, 
  p_dsc_regional OUT varchar2,
  p_dsc_erro OUT varchar2) IS 
begin  
  p_dsc_erro := null;
  
  if(cod_regional = 0) then
    begin
      select reg_cod, reg_des into p_cod_regional, p_dsc_regional
      from fas_corporativo.corp_regional;
    end;
  else 
    begin
      select reg_cod, reg_des into p_cod_regional, p_dsc_regional
      from fas_corporativo.corp_regional
      where reg_cod = cod_regional;
    end;
  end if;
  
  exception    
       when others then  
           p_dsc_erro:= sqlerrm;  
end;
porem quando eu mando executar essa proc me retorna o seguinte erro:

Selecionar tudo

P_DSC_ERRO = ORA-01422: a extração exata retorna mais do que o número solicitado de linhas
minha duvida é: como fazer uma proc que possa retornar mais de uma linha no result set??

aguardo!!!
Trevisolli
Moderador
Moderador
Mensagens: 2016
Registrado em: Qua, 12 Jan 2005 3:25 pm
Localização: Araraquara - SP
Abraço,

Trevisolli
OCA Oracle PL/SQL Developer Certified Associate
OCP Oracle Forms Developer Certified Professional
Araraquara-SP

Brother,

Tem como fazer o retorno de um objeto.
Você pode retornar um Type pl/sql table.
Dê uma pesquisada aqui no fórum mesmo por Type ou PL/SQL Table que irá encontrar exemplos interessantes.

qualquer coisa, manda pra gente.
leprado
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 5
Registrado em: Sex, 24 Out 2008 3:44 pm
Localização: Curitiba - PR

Fala Trevisolli.. beleza..

fiz algumas pesquisas na NET e encontrei alguns artigos sobre tabelas temporarias, porém não consegui nada prático..

você tem algum exemplo ai de uma procedure que faça um select simples e retorne os campos

obrigado!
leprado
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 5
Registrado em: Sex, 24 Out 2008 3:44 pm
Localização: Curitiba - PR

estou fazendo da seguinte maneira

procedure:

Selecionar tudo

create or replace PROCEDURE TESTESELECT3 AS
  CURSOR c_carac IS select nu_caracteristica, de_caracteristica from caracteristica;

  TYPE type_numero IS TABLE OF caracteristica.nu_caracteristica%TYPE INDEX BY BINARY_INTEGER; 
  tab_numero type_numero; 
  
  TYPE type_desc IS TABLE OF caracteristica.de_caracteristica%TYPE INDEX BY BINARY_INTEGER; 
  tab_desc type_desc; 

  v_counter NUMBER := 0;

BEGIN
  FOR r_cname IN c_carac
  LOOP
    v_counter := v_counter + 1;
    tab_numero(v_counter):= r_cname.nu_caracteristica;
    tab_desc(v_counter):= r_cname.de_caracteristica;
  END LOOP;

  FOR i_cname IN 1 .. v_counter
  LOOP
    DBMS_OUTPUT.put_line('Codigo: '|| tab_numero(i_cname));
    DBMS_OUTPUT.put_line('Descri: '|| tab_desc(i_cname));
  END LOOP;

END TESTESELECT3;

retorno:

Selecionar tudo

Codigo: 1
Descri: Tipo de Logradouro
Codigo: 2
Descri: Tipo de localidade
Codigo: 3
Descri: Domicilio coberto por
Codigo: 4
Descri: Situação do Domicílio
Codigo: 5
Descri: Tipo do Domicílio
Codigo: 6
Descri: Número de Cômodos
Codigo: 7
Descri: Tipo de Construção
Codigo: 8
Descri: Tipo de abastecimento de água
Codigo: 9
Descri: Tratamento de água
Codigo: 10
Descri: Tipo de Iluminação
Codigo: 11
Descri: Escoamento Sanitário
Codigo: 12
Descri: Destino do Lixo no Domicílio
Codigo: 13
Descri: Sexo
Codigo: 14
Descri: Nacionalidade
Codigo: 15
Descri: País de Origem
Codigo: 16
Descri: Estado civil
Codigo: 17
Descri: Tipo de deficiência
agora como posso retornar os dados para um resultset, para que no .NET possa consumir essa procedure???

aguardo
Trevisolli
Moderador
Moderador
Mensagens: 2016
Registrado em: Qua, 12 Jan 2005 3:25 pm
Localização: Araraquara - SP
Abraço,

Trevisolli
OCA Oracle PL/SQL Developer Certified Associate
OCP Oracle Forms Developer Certified Professional
Araraquara-SP

Brother, vai utilizar este retorno em .Net?

Veja se este link lhe ajuda (ref cursor):

http://www.glufke.net/oracle/viewtopic. ... 25&start=0

Qualquer coisa, manda pra gente.
leprado
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 5
Registrado em: Sex, 24 Out 2008 3:44 pm
Localização: Curitiba - PR

obrigado pela resposta porém fiquei com a mesma duvida que nesse topico que você me passou..

vou ter que criar uma packag???

para cada consulta mimha vou ter um package??

aguardo
Trevisolli
Moderador
Moderador
Mensagens: 2016
Registrado em: Qua, 12 Jan 2005 3:25 pm
Localização: Araraquara - SP
Abraço,

Trevisolli
OCA Oracle PL/SQL Developer Certified Associate
OCP Oracle Forms Developer Certified Professional
Araraquara-SP

Brother,

Aí vai da tua regra de negócio.
Package não precisa não, apenas precisa declarar uma única vez, no SPEC dela o teu type (ref cursor) de retorno.

Depois, pode reaproveitar para todos os teus retornos.

Se as tuas queries forem diferentes, ai você organiza da melhor forma e/ou no padrão de onde trabalhas.

Qualquer coisa, manda pra gente.
leprado
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 5
Registrado em: Sex, 24 Out 2008 3:44 pm
Localização: Curitiba - PR

entendi...

agora se fosse usar um cursor ref nessa procedure como ficaria

Selecionar tudo

create or replace PROCEDURE TESTESELECT3 AS
  CURSOR c_carac IS select nu_caracteristica, de_caracteristica from caracteristica;

  TYPE type_numero IS TABLE OF caracteristica.nu_caracteristica%TYPE INDEX BY BINARY_INTEGER;
  tab_numero type_numero;
 
  TYPE type_desc IS TABLE OF caracteristica.de_caracteristica%TYPE INDEX BY BINARY_INTEGER;
  tab_desc type_desc;

  v_counter NUMBER := 0;

BEGIN
  FOR r_cname IN c_carac
  LOOP
    v_counter := v_counter + 1;
    tab_numero(v_counter):= r_cname.nu_caracteristica;
    tab_desc(v_counter):= r_cname.de_caracteristica;
  END LOOP;

  FOR i_cname IN 1 .. v_counter
  LOOP
    DBMS_OUTPUT.put_line('Codigo: '|| tab_numero(i_cname));
    DBMS_OUTPUT.put_line('Descri: '|| tab_desc(i_cname));
  END LOOP;

END TESTESELECT3; 
rcoelho_6
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 18
Registrado em: Ter, 04 Nov 2008 1:56 pm
Localização: SP - são Paulo

Grande, acho que o codigo que você precisa seja algo mais ou menos assim.

Eu mudei a procedure para uma function que retorna o tipo da sua tabela.

Selecionar tudo

create or replace FUNCTION TESTESELECT3 return caracteristica%rowtype
IS

  CURSOR c_carac IS select nu_caracteristica, de_caracteristica from caracteristica;
  
  v_caract caracteristica%rowtype;

BEGIN 
   
    open c_carac;
    fetch c_carac into v_caract;
    close c_carac;

   return v_caract;

END TESTESELECT3;
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 6 visitantes