我创建了一个函数,该函数将影片ID作为输入,并根据ID返回股票信息。该功能大部分都有效,但是如果我想从不在数据库中的电影中检索信息(不返回任何行),则不会返回任何内容。不知道为什么吗?
当我调用不返回任何行的ID时不会给我错误,因此异常处理将不起作用。
create or replace function stock_info
(p_id IN NUMBER
)
return VARCHAR2
IS
cursor c1 is
select movie_id, movie_title, movie_qty
from mm_movie
where p_id = movie_id;
lv_movie_info VARCHAR2(100);
BEGIN
for i in c1 loop
if p_id = i.movie_id then
lv_movie_info := i.movie_title || ' is available: ' || i.movie_qty || ' on the shelf';
else
lv_movie_info := 'no data found';
end if;
end loop;
return lv_movie_info;
END STOCK_INFO;
/
答案 0 :(得分:1)
没有数据时您什么也没得到的原因是循环没有执行。逻辑上,For表达式说“为游标中返回的每一行执行以下循环”,但是游标中没有行,因此它永远不会执行该循环。此外,该结构实际上表明您期望给定p_id多个。如果不是这种情况,则可以一起消除光标。假设p_id是主键,那么您有0行或1行,因此:
create or replace function stock_info (p_id in number)
return text
is
lv_movie_info varchar2(100);
begin
select i.movie_title || ' is available: ' || i.movie_qty || ' on the shelf'
into lv_movie_info
from mm_movie i
where p_id = movie_id;
return lv_movie_info;
exceptions
when no_data_found
then return 'no data found';
end stock_info;
当然,如果确实希望多于1行,则需要游标,但是IF不是因为are子句保证它是正确的。仍为0行时,将不会执行循环,因此需要在“结束循环”之后加上“找不到数据”消息。
Belayer
答案 1 :(得分:0)
您使用的游标语句从in参数中获取数据。即在光标中,根据传递的电影ID选择限制。
传递不在数据库中的影片ID时,游标select语句将不会获取任何记录,因此流程甚至都不会进入for循环。
如果您希望不返回任何数据-传递数据库中没有的电影ID时,有两种解决方法 1.在循环之前,使用select语句将标志设置为Y或N(如果存在)并满足您的要求。 2.在不用于光标的情况下,有一个选项可以检查未找到... 样本:
declare
cursor c1 is select * from table_sample; -- empty table
c_rec c1%rowtype;
begin
open c1;
fetch c1 into c_rec;
if c1%notfound then
dbms_output.put_line('not found');
end if;
close c1;
end;
-- output
not found