ORA-00933触发器异常 - SQL命令未正确结束

时间:2013-12-17 10:22:17

标签: sql oracle sqlplus

我有以下代码编译错误 - SQL命令未正确结束     创建或替换触发器trg_bc       插入Marks后       对于每一行       宣布         sumMarks int;         noCMarks int;

    begin
      select nbrMarks into noCMarks from Course where idC = :new.idC;

      select count(idC) from Marks where idStd = :new.idStd and idC = :new.idC;

      if (noCMarks = Marks) then
        select sum(Mark) into sumMarks from Marks where idC = :new.idC
        and idStd = :new.idStd;
        select nbrMarks into noCMarks from Course where idC = :new.idC;
      insert into meanbyCourse (idStd, IdC, Mean) values(:new.idStd, :new.idC, sumMarks/ noCMarks);
      end if;
  end;
/
show errors

我不知道它有什么问题。

2 个答案:

答案 0 :(得分:1)

“没有足够的值”表示您正在尝试执行insert语句,并且列列表比值列表长。检查插入语句。可能需要将其更改为:

insert into meanbycourse
   (idstd
   ,idc
   ,mean)
values
   (marks_change_tab(i).idstd
   ,marks_change_tab(i).idc
   ,marks_change_tab(i).stdmean);

答案 1 :(得分:1)

这部分有点错误 - 第26行,因为错误信息指向:

select count (*) into rowcnt from Course where idc =    marks_change_tab(marks_change_tab.last).IdC := :new.IdC and nbrMarks in
(select count(idC) from Marks where idStd = marks_change_tab(marks_change_tab.last).IdStd and idC = marks_change_tab(marks_change_tab.last).IdC := :new.IdC);

你已经完成了两次任务,:=。我不确定这应该是做什么的:

where idc =    marks_change_tab(marks_change_tab.last).IdC := :new.IdC

同样的事情在子查询中。我猜你从上面的几行剪切并粘贴它并得到了太多的东西?如果是这样的话:

select count (*) into rowcnt
from Course
where idc = marks_change_tab(marks_change_tab.last).IdC 
and nbrMarks in (
  select count(idC)
  from Marks
  where idStd = marks_change_tab(marks_change_tab.last).IdStd
  and idC = marks_change_tab(marks_change_tab.last).IdC
);

即。只需从这些行中删除:= :new.IdC即可。我并没有真正关注你在这里所做的事情,但是因为它在一个循环中,看起来你的意思是指整个marks_change_tab(i),而不是{{1}值?虽然除非我遗漏了某些内容,否则它只会有一行,这有点毫无意义。您无法在SQL语句中引用.last(您将收到PLS-00425错误),因此您需要在那里使用.last并在其中的其他select语句中使用i循环。

select count (*) into rowcnt
from Course
where idc = marks_change_tab(i).IdC
and nbrMarks in (
  select count(idC)
  from Marks
  where idStd = marks_change_tab(i).IdStd
  and idC = marks_change_tab(i).IdC
);

if (rowcnt >0) then
  select sum(Mark) into sumOfStdMarks
  from Marks
  where idC =  marks_change_tab(i).idC
  and idStd = marks_change_tab(i).idStd;

  select nbrMarks into nbrOfCourseMarks
  from Marks
  where idC = marks_change_tab(i).idC;

  marks_change_tab(i).mean := sumOfStdMarks/ nbrOfCourseMarks;
else
  marks_change_tab.delete(i);
end if;

(已在评论中更新为包含delete)。但是,如果只有一行,您可以跳过循环并直接使用:new值。并且没有marks.nbrMarks列;不确定你的意思是从course获得吗?

第二个错误就像雷恩已经指出的那样;您尝试将单个值(即记录)插入三列。 Rene显示,您需要明确指定记录中的每个值。 insert和记录类型都有三列,它们不是直接兼容的并不重要。您可以改为以不同方式声明记录类型:

subtype mbcourse_rec is meanbycourse%rowtype;
type m_change_tab is table of mbcourse_rec;

...然后你可以这样做:

insert into meanbyCourse values marks_change_tab(i);

This compiles now, anyway

触发器似乎不是这里的方式。似乎更容易使meanByCourse视图计算动态值,或者可能是物化视图,或者有一个程序来执行计算并执行插入到marks和{ {1}}同时,虽然这会产生相同的并发问题。类似地,看起来您可能从触发器或此触发器触发的插入之前计算meanByCourse,这也可能容易出现并发问题。真的很难说,但这一切看起来都非常复杂和混乱。