执行立即选择不返回任何值

时间:2019-02-20 18:00:44

标签: sql oracle

我有选择语句

select name, surname
from student
where id_student = 1;

返回

name surname
Bob Smith

我想使用立即执行创建具有相同选择语句的过程:

create or replace procedure select_procedure
as
begin
execute immediate
'select name, surname
from student
where id_student = 1';
end;
/
exec select_procedure;

执行此过程时,它显示PL / SQL过程已成功完成。我如何得到结果? (将服务器输出设置为开)

2 个答案:

答案 0 :(得分:5)

您必须选择 to 。如果您不这样做,则查询isn't even executed(尽管已解析)。

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

但是,没有特别的顺序:(a)您应该使用绑定变量,而不要在动态语句中嵌入文字值1; (b)这根本不需要是动态的; (c)调用者无论如何都无法查看查询返回的值-除非您改为选择OUT个参数,或使用dbms_output()显示它们(尽管实际上应该只使用用于调试,因为您无法控制客户端是否显示它。

所以您可以这样做:

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

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

,并让您的调用者传入其自己的变量名以进行填充,然后使用这些变量名进行所需的操作。呼叫者通常还会传递您要查找的ID,因此您没有1个硬编码。

尽管看来,过程实际上并不是最好的机制。

此外,如果查询返回零行或多于一行,则使用select ... into(静态或动态)也会出错。仅当返回准确的一行时,它才起作用。游标可以处理任意数量的行-但除非您只是打印结果(如@Jayanth所示),否则您需要将游标传递回调用方。您可以改而bulk collect into进行收集,但是您仍然必须对此进行处理。

答案 1 :(得分:0)

您必须为此编写一个游标。请在下面找到相同的语法。

语法:

create or replace procedure select_procedure
as
CURSOR <cursor_name> IS <SELECT statement without semicolon>;
BEGIN
  FOR record IN <cursor_name>
  LOOP
  Dbms_output.put_line(‘Record Fetched:‘||record.name);
  Dbms_output.put_line(‘Record Fetched:‘||record.surname);
  END LOOP;
END;