sql >> Base de Datos >  >> RDS >> Oracle

Ejecutar selección inmediata no devuelve valores

Tienes que seleccionar en alguna cosa. Si no lo hace, la consulta ni siquiera se ejecuta (aunque se analiza).

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;
/

Pero, sin ningún orden en particular:(a) debe usar variables de vinculación en lugar de tener el valor literal 1 incrustado en la declaración dinámica; (b) esto no necesita ser dinámico en absoluto; y (c) la persona que llama no podrá ver los valores devueltos por la consulta de todos modos, a menos que seleccione OUT argumentos en su lugar, o mostrarlos con dbms_output() (aunque eso solo debería usarse para la depuración, ya que no puede controlar si el cliente lo mostrará).

Así que podrías hacer:

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;
/

o

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;
/

y haga que la persona que llama pase sus propios nombres de variables para completar, y luego haga lo que sea necesario con ellos. Por lo general, la persona que llama también pasaría la ID que está buscando, por lo que no tiene el 1 codificado.

Sin embargo, no parece que un procedimiento sea realmente el mejor mecanismo para esto.

Además, usando select ... into (estático o dinámico) generará un error si la consulta devuelve cero filas o más de una fila. Solo funcionará si se devuelve exactamente una fila. Un cursor manejaría cualquier cantidad de filas, pero a menos que solo esté imprimiendo los resultados (como muestra @Jayanth), debe devolver el cursor a la persona que llama. Podrías hacer una bulk collect into una colección en su lugar, pero todavía tienes que hacer algo con eso.