SQL Oracle - 过程语法(学校分配)

时间:2016-03-18 18:17:03

标签: sql oracle

我目前正在学习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;
/

我收到错误:编译过程,错误检查编译器日志。

但是我无法打开编译器日志,当我的朋友打开它时,它指向奇怪的地方,比如我的创建表等。

顺便说一下,这是学校的东西,所以如果你能提供洞察力而不是直接的解决方案,那就太好了。非常感谢。

非常感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

要查看您在创建过程声明后可以show errors执行的错误,或者您可以查询user_errorsall_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。我的意思是,它显然是同一张桌子;但更新和子查询分别查看表,因此查看不同的行。它还具有与游标查询相同的缺少连接条件。