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

Executar seleção imediata não retorna valores


Você deve selecionar em algo. Caso contrário, a consulta nem é executado (embora seja analisado).
create or replace procedure select_procedure
as
  l_name student.name%TYPE;
  l_surname student.name%TYPE;
begin
  execute immediate
  'select name, surname
  from student
  where id_student = 1'
  into l_name, l_surname;
end;
/

Mas, em nenhuma ordem específica:(a) você deve usar variáveis ​​de ligação em vez de ter o valor literal 1 embutido na instrução dinâmica; (b) isso não precisa ser dinâmico; e (c) o chamador não poderá ver os valores retornados pela consulta de qualquer maneira - a menos que você selecione OUT argumentos ou exiba-os com dbms_output() (embora isso deva realmente ser usado apenas para depuração, pois você não pode controlar se o cliente o mostrará).

Então você poderia fazer:
create or replace procedure select_procedure
as
  l_name student.name%TYPE;
  l_surname student.name%TYPE;
begin
  select name, surname
  into l_name, l_surname
  from student
  where id_student = 1;

  dbms_output.put_line('name=' || l_name ||', surname=' || l_surname);
end;
/

ou
create or replace procedure select_procedure (
  p_name OUT student.name%TYPE,
  p_surname OUT student.name%TYPE
)
as
begin
  select name, surname
  into p_name, p_surname
  from student
  where id_student = 1;
end;
/

e faça com que seu chamador passe seus próprios nomes de variáveis ​​para preencher e, em seguida, faça o que for necessário com eles. O chamador normalmente também passaria o ID que você está procurando, então você não tem o 1 codificado.

Não parece que um procedimento seja realmente o melhor mecanismo para isso.

Além disso, usando um select ... into (estático ou dinâmico) ocorrerá um erro se a consulta retornar zero linhas ou mais de uma linha. Só funcionará se houver exatamente uma linha retornada. Um cursor lidaria com qualquer número de linhas - mas a menos que você esteja apenas imprimindo os resultados (como @Jayanth mostra), você precisa passar o cursor de volta para o chamador. Você pode fazer uma bulk collect into uma coleção em vez disso, mas você ainda tem que fazer algo com isso.