Procedimento com Select

Dúvidas, dicas e truques de SQL, Select, Update, Delete, cláusulas, operações com joins, Funções em SQLs, etc
Avatar do usuário
fernandolacerda
Rank: Estagiário Sênior
Rank: Estagiário Sênior
Mensagens: 10
Registrado em: Dom, 04 Jul 2010 9:57 am
Localização: ITUIUTABA-MG

bom dia pessoal,
sou iniciante em PL/SQL.
estou com uma duvida, pois fiz um comando SQL dentro da procedure e da o seguinte erro :

Selecionar tudo

é esperado uma cláusula INTO nesta instrução SQL.

Selecionar tudo

create or replace procedure selecionarNome(p_cod IN NUMBER) 
is
begin
       select codigo, nome as resultado
       from agenda
       where codigo = p_cod;    
end nome;

se alguém puder ajudar.
rogenaro
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Sex, 30 Mar 2007 7:26 pm
Localização: Londrina - PR
Rafael O. Genaro

Em P/SQL, você precisa definir em quais variáveis os resultados da query serão retornados:

Selecionar tudo

create or replace procedure selecionarNome(p_cod IN NUMBER) 
is 
  v_codigo agenda.codigo%type;
  v_nome agenda.nome%type;
begin 
  select codigo, nome as resultado 
  into   v_codigo, v_nome
  from agenda 
  where codigo = p_cod; 
exception
  when no_data_found then
    -- tratar quando não houver nenhum registro retornado
  when too_many_rows then
    -- tratar quando houver mais de um registro com o mesmo código
end selecionarNome; 

Lembrando que, select ... into ... espera um e apenas um registro retornado. Logo, se você consultar determinad código que possua dois ou mais registros, será lançada uma exceção (too_many_rows).
Caso não tenha nenhum registro para o código informado, será lançada uma exceção (no_data_found). No caso, seria apenas tratar cada uma no bloco exception.

Se você precisar tratar mais de uma linha retornada, utilize o for:

Selecionar tudo

for x in
(
  select codigo, nome as resultado 
  from agenda 
  where codigo = p_cod
) loop
  dbms_output.put_line( x.codigo||' - '||x.resultado );
end loop;
Observando apenas que, com o for, não é lançada a exceção no_data_found, logo dependendo da situação, a verificação da existência ou não de dados fica por conta do desenvolvedor.
Avatar do usuário
fernandolacerda
Rank: Estagiário Sênior
Rank: Estagiário Sênior
Mensagens: 10
Registrado em: Dom, 04 Jul 2010 9:57 am
Localização: ITUIUTABA-MG

ai se no caso nessa função eu queira retornar todos os codigo, onde nome = 'fernando' por exemplo, ficaria assim:

Selecionar tudo

create or replace function retornaCodigo(p_nome IN VARCHAR2) return number 
is
  Result number;
  v_codigo agenda.codigo%type; 
  v_nome agenda.nome%type; 
begin
  for x in ( 
  select codigo, nome 
  from agenda 
  where codigo = p_nome 
  ) loop 
  dbms_output.put_line( x.codigo||' - '||x.nome ); 
  end loop; 

end maisResult;  
Obrigado pela ajuda..
tiago.steil
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 17
Registrado em: Qui, 01 Jul 2010 3:22 pm
Localização: RS
Oracle Developer

Boa tarde,

A lógica séria essa que o amigo rogenaro passou mas você está comparando código com o nome?? provavelmente está trocado e no final depois do end vai o nome da procedure que no seu caso está trocado também ou pode deixar sem nome depois do end.
rogenaro
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Sex, 30 Mar 2007 7:26 pm
Localização: Londrina - PR
Rafael O. Genaro

É só atribuir o valor de x.codigo à variável Result, e no final colocar um

Selecionar tudo

return Result
, ou já retornar o valor do primeiro registro encontrado:

Selecionar tudo

create or replace function retornaCodigo(p_nome IN VARCHAR2) return number 
is 
  Result number; 
  v_codigo agenda.codigo%type; 
  v_nome agenda.nome%type; 
begin 
  for x in ( 
  select codigo, nome 
  from agenda 
  where codigo = p_nome  -- como o Tiago disse, acredito que seria where nome = p_nome aqui
  ) loop 
    return (x.codigo);
  end loop; 

  return null; -- Não achou nenhum registro.. a função deverá retornar null? ou com erro?

end maisResult; -- Aqui você tem que colocar o mesmo nome de sua função.. no caso, retornaCodigo
Avatar do usuário
fernandolacerda
Rank: Estagiário Sênior
Rank: Estagiário Sênior
Mensagens: 10
Registrado em: Dom, 04 Jul 2010 9:57 am
Localização: ITUIUTABA-MG
Fernando Lacerda

valeu pela ajuda ai pessoal, muito obrigado mesmo. Funcionou beleza.
Responder
  • Informação