我有选择语句
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过程已成功完成。我如何得到结果? (将服务器输出设置为开)
答案 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;