有没有办法检查游标是不是返回没有记录?
Posted
技术标签:
【中文标题】有没有办法检查游标是不是返回没有记录?【英文标题】:Is there any way to check if cursor return no record?有没有办法检查游标是否返回没有记录? 【发布时间】:2021-05-03 20:59:32 【问题描述】:我在 PL/SQL 中编写了简单的程序来降低价格。当我调用过程时,我故意传递不在数据库中的参数,因此游标不返回任何数据。
这是问题:我的异常不起作用。 kursor%notfound
之类的表达式检查 kursor 是否不返回任何数据或未声明?
我很困惑,因为在我进行研究时,有人说kursor%notfound
在没有找到数据时返回 true,但在我的程序中它不起作用。说到这里:
if (kursor%notfound) then
raise no_data_found;
end if;
它不会引发异常。我究竟做错了什么? PS 抱歉,语言不一致(混合波兰语和英语),但我有波兰语数据库。
我的整个程序:
set serveroutput on
create or replace procedure reduce_price(surname_p varchar2,
name_p varchar2, percents number default 5)is
cursor kursor is
select n.id_mech,cena from naprawa n
join mechanik m on m.id_mech = n.id_mech
where m.imie = name_p and m.nazwisko = surname_p
for update;
nc number;
begin
for k in kursor
loop
if (kursor%notfound) then
raise NO_DATA_FOUND;
end if;
begin
nc := k.cena *(1-percents/100);
dbms_output.put_line(k.cena ||' ' ||nc);
update naprawa set cena =nc
where id_mech = k.id_mech;
exception
when NO_DATA_FOUND then
dbms_output.put_line('no rows found');
end;
end loop;
end;
/
begin
reduce_price('aaa', 'XYZ',1);
end;
感谢您的宝贵时间。
【问题讨论】:
@OldProgrammer 的回答解释了为什么它永远不会引发 NO_DATA_FOUND,但原始代码中的另一个问题是在 RAISE 语句的范围内没有异常处理程序。 【参考方案1】:那是行不通的。在您的 cursor for 循环中,如果您的代码进入循环,那么这意味着找到一个或多个记录,并且 %notfound 游标属性永远不会为真。你有几个选择。
在循环中保留一个计数器并在退出后检查
创建或替换过程 reduce_price(surname_p varchar2, name_p varchar2,百分比数字默认5)是
nc number;
cnt number := 0;
begin
for k in kursor
loop
nc := k.cena *(1-percents/100);
dbms_output.put_line(k.cena ||' ' ||nc);
update naprawa set cena =nc
where id_mech = k.id_mech;
cnt := cnt + 1;
end loop;
if cnt = 0 then
raise NO_DATA_FOUND;
end if;
.. etc..
在进入循环之前检查现有数据
select count(*)
into cnt
from naprawa n
join mechanik m on m.id_mech = n.id_mech
where m.imie = name_p and m.nazwisko = surname_p;
if cnt = 0 then
raise NO_DATA_FOUND;
end if;
...
for k in kursor
loop
【讨论】:
(很抱歉由于某种原因在答案中格式化代码时出现问题) 这些都不起作用。在这两种情况下,结果都是:过程 REDUCE_PRICE 编译的 PL/SQL 过程成功完成。 即使我的数据库中没有传递给过程的数据,我也没有引发任何异常:( 我虽然这可能是使用 sql developer 的问题,但我不这么认为,在更简单的程序中异常有效。 但是在我编译过程后我运行 reduce_price('param1','param2',3)。现在我看到,由于某种原因,即使我评论了几乎所有的行,即使我有“创建和替换”,程序也能正常工作。我会按照你说的检查调试器。以上是关于有没有办法检查游标是不是返回没有记录?的主要内容,如果未能解决你的问题,请参考以下文章