导致错误过程的OracleEE 11g WITH子句将无法编译

时间:2012-02-21 22:20:53

标签: sql plsql oracle11g

这是我第一次使用PL SQL,所以我可能会犯一些愚蠢的错误。 我正在尝试在Oracle Express Edition 11g中编写一个过程。我遇到了一个与过程体中的WITH子句有关的错误。

每当我尝试运行它时,我都会看到两个错误。

Error report:
ORA-06550: line 14, column 50:
PL/SQL: ORA-00918: column ambiguously defined
ORA-06550: line 12, column 7:
PL/SQL: SQL Statement ignored
ORA-06550: line 29, column 3:
PLS-00306: wrong number or types of arguments in call to 'FIND_HIGH_AVG'
ORA-06550: line 29, column 3:
PL/SQL: Statement ignored
06550. 00000 -  "line %s, column %s:\n%s"
*Cause:    Usually a PL/SQL compilation error.
*Action:

程序代码见下文。

DECLARE 
  myTerm courses.term%type;
  myLine courses.lineno%type;

procedure find_high_avg (term IN courses.term%type, 
                        line IN courses.lineno%type,
                        s_fname OUT students.fname%type,
                        s_lname OUT students.lname%type,
                        s_sid OUT students.side%type,
                        s_avg OUT number) is 
  begin 
      WITH grades as (select * from components co --line 12 here
            join scores sc on co.term = sc.term and co.lineno = sc.lineno and CO.COMPNAME = SC.COMPNAME
            where sc.lineno = line and sc.term = term) --line 14 here
      select * 
      into s_fname, s_lname, s_sid, s_avg 
      from (
          select s.fname, s.lname, s.sid, round(sum(points/maxpoints * weight),0) as AV
          from grades, students
          join students s on grades.sid = s.sid
          group by s.sid, s.fname, s.lname
          order by AV)
      where rownum = 1;   
  end; 

BEGIN
  myTerm:='F12';
  myLine:='1031';
  find_high_avg(myTerm, myLine); --line 29 here
END;

2 个答案:

答案 0 :(得分:4)

第10行出现错误是因为存储过程的参数不需要很长时间。程序声明应该类似于

procedure find_high_avg (term IN courses.term%type, 
                        line IN courses.lineno%type,
                        s_fname OUT students.fname%type,
                        s_lname OUT students.lname%type,
                        s_sid OUT students.side%type,
                        average OUT number) 
is

第14行的错误可能是因为您的过程的参数与表中的列具有相同的名称。在SQL语句的范围解析规则中,列名优先于本地PL / SQL变量。所以当你编写像

这样的代码时
sc.term = term

Oracle尝试使用其中一个表中的列来解析不合格的TERM。如果两个表都有一个名为TERM的列,那么会生成一个不明确的列引用 - Oracle不知道要使用哪两个表。当然,实际上,您不希望它使用任何一个表中的列,您希望它使用该参数。解决此问题的最常见方法是在参数名称中添加前缀,以确保它们不会与列名冲突。像

这样的东西
procedure find_high_avg (p_term IN courses.term%type, 
                        p_line IN courses.lineno%type,
                        s_fname OUT students.fname%type,
                        s_lname OUT students.lname%type,
                        s_sid OUT students.side%type,
                        p_average OUT number) 
is

第29行出现错误是因为该过程需要6个参数 - 2 IN和4 OUT。因此,为了调用它,您需要使用6个参数。像

这样的东西
DECLARE 
  myTerm courses.term%type;
  myLine courses.lineno%type;

  l_fname students.fname%type;
  l_lname students.lname%type;
  l_sid   students.side%type;
  l_avg   number;
BEGIN
  myTerm:='F12';
  myLine:='1031';
  find_high_avg(myTerm, myLine,l_fname,l_lname, l_sid, l_avg); 
END;

答案 1 :(得分:0)

我认为在select语句之后它应该是end find_high_avg;而不是end;