2012-02-21 54 views
0

這是我第一次運行PL SQL,因此我可能會犯一些愚蠢的錯誤。 我正在嘗試在Oracle Express Edition 11g中編寫一個過程。我遇到了與過程體中的WITH子句有關的錯誤。OracleEE 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; 

回答

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; 
+0

我做了這個改變,但是我遇到了編譯器仍然會遇到的問題。更新了主要問題以反映這一點。 – tyh 2012-02-21 22:50:08

+0

@timyh - 更新了我的答案,還有一些問題。 – 2012-02-22 02:14:56

+0

非常感謝您提供了非常好的詳細解答,並且我對這一切如何運作有了更好的理解。 – tyh 2012-02-23 03:19:24

0

東西,我覺得應該是end find_high_avg;而不是end; select語句之後。

+0

試過,但仍然像以前一樣的問題。 – tyh 2012-02-21 23:25:24

相關問題