Предложение OracleEE 11g WITH, вызывающее ошибку, не компилируется - PullRequest
0 голосов
/ 22 февраля 2012

Это мой первый пробежка по 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 ]

4 голосов
/ 22 февраля 2012

Ошибка в строке 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 входа и 4 выхода. Поэтому для его вызова вам нужно будет использовать 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 голосов
/ 22 февраля 2012

Я думаю, это должно быть end find_high_avg; вместо end; после оператора select.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...