PLS-00302:必须声明组件-无法解析
Posted
技术标签:
【中文标题】PLS-00302:必须声明组件-无法解析【英文标题】:PLS-00302: component must be declared- Unable to resolve 【发布时间】:2014-03-10 16:53:00 【问题描述】:我在 SQL developer 中尝试了以下程序并遇到了一些问题:
declare
cursor emp_complex_cur is
select e.fname,d.dlocation
from employee e, dept_location d
where e.dno=d.dnumber;
emp_max_id integer;
type emp_complex_rec is record(rname employee.fname%type,rlocation dept_location.dlocation%type);
begin
open emp_complex_cur;
for emp_complex_rec in emp_complex_cur loop
fetch emp_complex_cur into emp_complex_rec;
dbms_output.put_line('The employee id is: '||emp_complex_rec.rname||' and the employee''s location is '||emp_complex_rec.rlocation);
close emp_complex_cur;
end;
我在声明变量 rname
时遇到错误,尽管它已在记录中正确声明。
【问题讨论】:
你应该考虑用这个创建一个sqlfiddle。 我相信 sqlfiddle 中没有可用的 Oracle 引擎。 @Rahul:SQLFiddle 肯定支持 Oracle。转到 sqlfiddle.com,单击数据库选择(默认为 mysql 5.5.32,但可以更改),然后在结果下拉列表中选择 Oracle 11g R2。分享和享受。 【参考方案1】:试试:
begin
for emp_complex_rec in (select e.fname,
d.dlocation
from employee e
INNER JOIN dept_location d
ON (e.dno = d.dnumber))
loop
dbms_output.put_line('The employee id is: ' ||
emp_complex_rec.rname ||
' and the employee''s location is ' ||
emp_complex_rec.rlocation);
end loop;
end;
原始代码的问题在于 emp_complex_rec
作为类型的定义与 emp_complex_rec
作为游标循环变量的定义发生冲突。也不需要显式游标定义 - IMO 将 SELECT
放入 FOR
循环更容易和更清晰。
分享和享受。
【讨论】:
【参考方案2】:光标中的列名称与您在输出行中调用的名称不同,我猜您使用的 for 循环会弄乱您的代码。实际上,它可能更简单:
declare
cursor emp_complex_cur is
select e.fname,d.dlocation
from employee e, dept_location d
where e.dno=d.dnumber;
emp_max_id integer;
begin
for emp_complex_rec in emp_complex_cur loop
dbms_output.put_line('The employee id is: '||emp_complex_rec.fname||' and the employee''s location is '||emp_complex_rec.dlocation);
end loop;
end;
【讨论】:
【参考方案3】:您似乎混淆了几种不同的技术。
选项 #1 - 手动获取显式光标
declare
cursor emp_complex_cur is
select e.fname,d.dlocation
from employee e, dept_location d
where e.dno=d.dnumber;
emp_max_id integer;
type emp_complex_typ is record(rname employee.fname%type,rlocation dept_location.dlocation%type);
--A variable must be declared of the type you've created
emp_complex_rec emp_complex_typ;
begin
open emp_complex_cur;
--Initial fetch is needed
fetch emp_complex_cur into r_complex_rec;
while emp_complex_cur%found loop
fetch emp_complex_cur into r_complex_rec;
end loop;
close emp_complex_cur;
dbms_output.put_line('The employee id is: '||emp_complex_rec.rname||' and the employee''s location is '||emp_complex_rec.rlocation);
end;
选项 #2 - 使用 for
循环获取显式游标
declare
cursor emp_complex_cur is
select e.fname,d.dlocation
from employee e, dept_location d
where e.dno=d.dnumber;
begin
--no "open" required
for emp_complex_rec in emp_complex_cur loop
--no "fetch" required
null;
end loop;
--no "close" required
dbms_output.put_line('The employee id is: '||emp_complex_rec.rname||' and the employee''s location is '||emp_complex_rec.rlocation);
end;
选项 #3 - 使用 for
循环获取隐式游标
查看@BobJarvis 提供的答案
选项 #4 - 仅获取一次显式游标
对于这种只检索单个记录的场景,我更喜欢使用显式游标和单个提取。如果您的查询返回 1 行或 100 行,这并不重要,因为您只对其中一个进行操作。为什么要遍历您要忽略的所有行?
declare
cursor emp_complex_cur is
select e.fname,d.dlocation
from employee e, dept_location d
where e.dno=d.dnumber;
emp_complex_rec emp_complex_cur%rowtype;
begin
open emp_complex_cur;
fetch emp_complex_cur into r_complex_rec;
close emp_complex_cur;
dbms_output.put_line('The employee id is: '||emp_complex_rec.fname||' and the employee''s location is '||emp_complex_rec.dlocation);
end;
【讨论】:
感谢艾伦的详细解答!即使使用了选项 #1 中提到的记录类型,我仍然面临问题。我需要显示满足条件的所有行(员工表中的员工 ID=部门表中的员工 ID)。我试图通过选项#2 中提到的方式来实现这一点。但是当我运行选项 #2 中给出的代码时,我仍然遇到同样的错误。请问有什么想法吗?以上是关于PLS-00302:必须声明组件-无法解析的主要内容,如果未能解决你的问题,请参考以下文章
PLS 00302:组件 DATA_TYPE 必须在函数中声明