2016-03-18 2 views
0

В настоящее время я изучаю SQL, и у меня возникают проблемы с моей процедурой. Процедура должна вычислять среднее значение столбца под названием «INDICE_METABO_PAT». Мне нужна информация в 3-4 разных таблицах. Затем, когда у меня есть среднее значение, я обновляю таблицу, чтобы установить это среднее значение в соответствующие записи. Вот процедура. Обратите внимание, что все остальное в моем файле .sql работы: вставки, обновления, выбирает, мнения и т.д.SQL Oracle - Синтаксис процедуры (назначение школы)

create or replace Procedure SP_UPDATE_INDICE_METABO_DV (P_NO_ETUDE in number) 

is 
    V_SOMME number := 0; 
    V_NBPATIENT number := 0; 
    V_NO_ETUDE number := P_NO_ETUDE; 

    cursor curseur is 
    select PATIENT.INDICE_EFFICACITE_METABO_PAT 
    from ETUDE, DROGUE_VARIANT, ETUDE_PATIENT, PATIENT 
    where ETUDE.NO_DROGUE = DROGUE_VARIANT.NO_DROGUE 
    and ETUDE.NO_VAR_GEN = DROGUE_VARIANT.NO_VAR_GEN 
    and V_NO_ETUDE = ETUDE_PATIENT.NO_ETUDE 
    and ETUDE_PATIENT.NO_PATIENT = PATIENT.NO_PATIENT; 

begin 
    open curseur; 
    fetch curseur into V_SOMME; 
    V_NBPATIENT := V_NBPATIENT + 1; 
    exit when curseur%NOTFOUND; 

    update DROGUE_VARIANT 
    set INDICE_EFFICACITE_METABO_DV = V_SOMME/V_NBPATIENT 
    where exists(select * from ETUDE, DROGUE_VARIANT, ETUDE_PATIENT, PATIENT 
    where ETUDE.NO_DROGUE = DROGUE_VARIANT.NO_DROGUE 
    and ETUDE.NO_VAR_GEN = DROGUE_VARIANT.NO_VAR_GEN 
    and V_NO_ETUDE = ETUDE_PATIENT.NO_ETUDE 
    and ETUDE_PATIENT.NO_PATIENT = PATIENT.NO_PATIENT); 

end SP_UPDATE_INDICE_METABO_DV; 
/

Я получаю сообщение об ошибке: Процедура компиляции ошибка журнала проверки компилятора.

Но я не могу открыть журнал компилятора, и когда мой друг открывает его, он указывает на странные места, такие как мои таблицы создания и т. Д.

Это, кстати, школьный материал, так что будет хорошо, если вы сможете дать представление, а не прямое решение. Большое спасибо.

Спасибо за помощь за помощь!

+0

Не должно быть петли где-то обрабатывать строки, извлеченные из курсора? –

+0

Вы не сказали, в чем проблема. Вы получаете ошибку компиляции, ошибку времени выполнения, неправильные результаты? Почему вы делаете это в процедуре; почему бы просто не использовать агрегированную функцию 'avg()' в вашем запросе или непосредственно в инструкции обновления? –

+0

Сообщите нам, что * не * работа поможет гораздо больше. Вы получаете ошибку компиляции? Неверные результаты? –

ответ

2

Чтобы увидеть ошибку, вы можете сделать show errors после создания вашей инструкции по созданию процедуры, или вы можете запросить user_errors или all_errors views.

Это покажет что-то вроде:

LINE/COL ERROR 
-------- ------------------------------------------------------------------------ 
20/4  PLS-00376: illegal EXIT/CONTINUE statement; it must appear inside a loop 
20/4  PL/SQL: Statement ignored 

Вы упомянули, что, когда вы проверили журнал компилятором, который показывает ту же самую информацию, «он указывает на странные места». Предположительно, вы смотрите строку 20 в своем скрипте. Но это сообщение относится к строке 20 кодового блока PL/SQL, которая является exit when curseur%NOTFOUND;, что имеет смысл для сообщения об ошибке.

И как говорится в сообщении, и как @ammoQ сказал в комментарии, это должно быть в цикле. Если вы пытаетесь вручную вычислить среднее значение в процедуре в качестве упражнения, вместо того, чтобы использовать встроенные функции агрегации, то вам необходимо перебираем все строки из курсора:

open curseur; 
loop 
    fetch curseur into V_SOMME; 
    exit when curseur%NOTFOUND; 
    V_NBPATIENT := V_NBPATIENT + 1; 
end loop; 
close curseur; 

Но, как вы быстро поймете, что в итоге вы получите переменную v_somme, имеющую последнее полученное значение, а не сумму всех значений. Вам нужна отдельная переменная, чтобы отслеживать сумму - выборка каждого значения в переменную и добавить ее к вашей общей сумме, все в пределах цикла. Но по просьбе, не давая полного решения.


Как вы начинаете вы должны действительно использовать ANSI синтаксис объединения, а не старый из /, где синтаксис у вас есть сейчас. Это позор, который все еще преподается. Таким образом, ваш курсор запрос должен быть что-то вроде:

select PATIENT.INDICE_EFFICACITE_METABO_PAT 
from ETUDE_PATIENT 
join ETUDE 
-- missing on clause ! 
join DROGUE_VARIANT 
on DROGUE_VARIANT.NO_DROGUE = ETUDE.NO_DROGUE 
and DROGUE_VARIANT.NO_VAR_GEN = ETUDE.NO_VAR_GEN 
join PATIENT 
on PATIENT.NO_PATIENT = ETUDE_PATIENT.NO_PATIENT 
where ETUDE_PATIENT.NO_ETUDE = P_NO_ETUDE; 

... который показывает вам, что вам не хватает условия соединения между ETUDE_PATIENT и этюдом - это маловероятно, что вы хотите, декартово произведение, и это гораздо легче обнаружить, что не хватает присоединитесь к этому синтаксису, чем к тому, что у вас было.


Вы должны смотреть на ваше заявление обновлений тщательно тоже, в частности, положение о exists. Это будет в основном всегда возвращать true, если курсор нашел что-либо, поэтому он обновит каждую строку в DROGUE_VARIANT с вашим рассчитанным средним значением, которое, по-видимому, не является тем, что вы хотите.

Нет корреляции между строками в обновляемой таблице и подзапросом в этом разделе - DROGUE_VARIANT в подзапросе не зависит от обновляемого DROGUE_VARIANT. Под этим я подразумеваю, что это та же таблица, очевидно; но обновление и подзапрос смотрят на таблицу отдельно и поэтому смотрят на разные строки. Он также имеет те же условия отсутствия соединения, что и запрос курсора.

+0

Хорошо, спасибо всем, я сейчас на работу, я посмотрю это позже сегодня вечером. Также @Alex Poole, нас учат нескольким методам присоединиться, но мне удалось получить результаты только с помощью метода from/where. Мне нравится пример, который вы мне дали, я попытаюсь сделать мои суставы такими, как сейчас! (Извините за ангрича) – CBinet

Смежные вопросы