游标可以在执行时传递参数吗

can cursors be passed with parameters at execution time

游标可以动态传参吗?

例如:

create or replace procedure getRec
as
cursor get(nameToGet varchar2) is select * from test where name = nameToGet;
rec test%rowtype;
begin
for rec in get('sam') loop
if get%notfound then
dbms_output.put_line('No record found');
else
dbms_output.put_line('Name : ' || ' ' || rec.name ||' ::: ' || 'Address : ' 
|| rec.address);
end if;
end loop;
end;

但这是硬编码的('nameToGet' 的值)。如何动态地将值传递给游标(如果可能)? 当然我们可以使用像

这样的参数化过程来做到这一点
create or replace procedure getRec(nameToGet IN varchar2)

光标会像

cursor get is select * from test where name = nameToGet;

但我想创建一个参数化游标并将值动态传递给游标。

另一方面,当找不到记录时,dbms_output('record not found') 不会执行。任何人都可以纠正代码吗?

如果需要,您可以将过程参数传递给游标:

create or replace procedure getRec(nameToGet IN varchar2)
as
cursor get(nameToGet varchar2) is select * from test where name = nameToGet;
begin
for rec in get(nameToGet) loop
...

如果您给参数起不同的名字,您可能会发现它不会那么混乱,例如有以 'p' 前缀开头的过程参数名称的约定,以 'c' 前缀开头的游标参数名称,或其他任何名称。

我删除了 rec 变量定义,因为它从未被使用过; for rec in ... 中的 rec 是一个完全不相关的变量。

您的所有 dbms_output 逻辑都在游标 for 循环内,因此只会在循环内评估 - 即当有数据时。如果你想使用这个循环结构,你可以使用一个标志来说明你是否已经进入循环,比如:

create or replace procedure getRec(pNameToGet IN varchar2)
as
  cursor get(cNameToGet varchar2) is
  select * from test where name = cNameToGet;
  lDataSeen boolean := false;
begin
  for rec in get(pNameToGet) loop
    lDataSeen := true;
    dbms_output.put_line('Name : ' || ' ' || rec.name ||' ::: ' || 'Address : ' 
      || rec.address);
  end loop;

  if !lDataSeen then
    dbms_output.put_line('No record found');
  end if;
end;