Oracle
 sql >> Database >  >> RDS >> Oracle

Esegui selezione immediata non restituisce alcun valore

Devi selezionare in qualche cosa. In caso contrario, la query non viene nemmeno eseguito (sebbene sia analizzato).

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

Ma, in nessun ordine particolare:(a) dovresti usare le variabili bind invece di avere il valore letterale 1 incorporato nell'istruzione dinamica; (b) questo non deve essere affatto dinamico; e (c) il chiamante non sarà comunque in grado di vedere i valori restituiti dalla query, a meno che non selezioni in OUT argomenti invece, o visualizzarli con dbms_output() (anche se in realtà dovrebbe essere utilizzato solo per il debug poiché non puoi controllare se il client lo mostrerà).

Quindi potresti fare:

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

e fai in modo che il tuo chiamante passi i suoi nomi di variabili da popolare, quindi fai tutto ciò di cui ha bisogno con quelli. Il chiamante di solito trasmette anche l'ID che stai cercando, quindi non hai l'1 hardcoded.

Tuttavia, non sembra che una procedura sia davvero il miglior meccanismo per questo.

Inoltre, utilizzando un select ... into (statico o dinamico) visualizzerà un errore se la query restituisce zero righe o più di una riga. Funzionerà solo se viene restituita esattamente una riga. Un cursore gestirebbe un numero qualsiasi di righe, ma a meno che tu non stia semplicemente stampando i risultati (come mostra @Jayanth), devi invece riportare il cursore al chiamante. Potresti effettuare una bulk collect into una collezione invece, ma devi comunque farci qualcosa.