我将游标定义为
CURSOR all_movie_nominations IS SELECT a.title, a.award_year,n.people_id FROM award a JOIN
nominee n ON
a.award_id = n.award_id
WHERE n.movie_id = (SELECT movie_id FROM movie WHERE movie_name = movieName);
正在打开和关闭光标。
将以下代码中的光标用作
FETCH all_movie_nominations INTO award_title, award_year,nominee_people_id;
WHILE all_movie_nominations%FOUND LOOP
SELECT given_name, family_name INTO first_name, last_name FROM people WHERE people_id=nominee_people_id;
IF first_name = '' THEN
DBMS_OUTPUT.PUT_LINE('The Movie was nominated for '||award_title||' for the year '||award_year);
ELSE
DBMS_OUTPUT.PUT_LINE(first_name||' '||last_name||' was nominated for '||award_title||' for the year '||award_year);
END IF;
FETCH all_movie_nominations INTO award_title, award_year, nominee_people_id;
END LOOP;
现在游标定义中的属性n.people_id
。此列包含某些行的空值。
在执行上面的代码时,我得到了正确的输出,但在输出的末尾有一个'NO_DATA_FOUND`异常。
如果我从光标中排除n.people_id
,我就不会有任何异常。
有关可能出错的建议吗?
答案 0 :(得分:3)
除非这是关于学习使用游标的学生代码,否则在现实生活中永远不会以这种方式编码。循环结构中的SQL语句是一个红色标志。因为你用这种方式锤击数据库,有很多(奖励数量)微小的选择语句检索一个人。这意味着PL / SQL引擎必须多次切换到SQL引擎,导致相对昂贵的上下文切换。如果使用连接,或者在外壳连接中使用,则可以将上下文切换次数最小化为一个。
替代方案的一个例子(当然未经测试):
for r in
( select a.title
, a.award_year
, p.given_name
, p.family_name
from award
inner join nominee n on a.award_id = n.award_id
left outer join people p on n.people_id = p.people_id
where n.movie_id = (select movie_id from movie where movie_name = movieName)
)
loop
dbms_output.put_line
( case
when r.given_name is null then
'The Movie'
else
r.given_name || ' ' || r.family_name
end ||
' was nominated for ' || r.title || ' for the year ' || r.award_year
);
end loop;
答案 1 :(得分:1)
我不确定会发生什么,我认为内部选择句引发了not_found异常:
IF nominee_people_id is not null THEN
SELECT given_name, family_name INTO first_name, last_name FROM people WHERE
people_id=nominee_people_id;
END IF;
我会尝试设置一个条件,检查nominee_people_id是否为空,以便执行这种情况。
我希望它对你有用 Redgards
答案 2 :(得分:0)
Hi you can opt for exception block for that if you want to ignore IF--END IF BLOCK;
BEGIN
SELECT given_name, family_name INTO first_name, last_name FROM people WHERE people_id=nominee_people_id;
EXCEPTION WHEN NO_DATA_FOUND THEN
dbms_output.put_line('no data found for '||nominee_people_id);
END;