我目前正在学习SQL,而我的程序遇到了麻烦。该过程应计算名为' INDICE_METABO_PAT'的列的平均值。我需要的信息是3-4个不同的表。然后,当我确实计算了平均值时,我会更新一个表格,将此平均值设置为相应的条目。这是程序。请注意,我的.sql文件中的其他所有内容都可以工作:插入,更新,选择,查看等。
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 :(得分: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行。但是这条消息指的是PL / SQL代码块的第20行,它是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连接语法,而不是现在使用旧的from / where语法。遗憾的是,这仍然是一种耻辱。所以你的游标查询应该是这样的:
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和ETUDE之间的连接条件 - 您不太可能想要笛卡尔积,并且使用此语法比使用您的语法更容易发现缺少连接。
您还需要仔细查看更新语句,尤其是exists
子句。如果光标找到任何东西,那基本上总是会返回true,所以它会用你计算的平均值更新DROGUE_VARIANT中的每一行,这可能不是你想要的。
您正在更新的表中的行与该子句中的子查询之间没有相关性 - 子查询中的DROGUE_VARIANT独立于您正在更新的DROGUE_VARIANT。我的意思是,它显然是同一张桌子;但更新和子查询分别查看表,因此查看不同的行。它还具有与游标查询相同的缺少连接条件。