sql-更新表之前统计表中的行数

yqlxgs2m  于 2021-07-26  发布在  Java
关注(0)|答案(2)|浏览(293)

我正在做一个关于oraclesql的大学项目,当我尝试更新一个表时,我不断地得到错误“表(…)正在变化,触发器/函数可能看不到它”。我的participateteams表有3列(eventname varchar(),teamid number,teamplace number)。
这里的目标是,当我在一个事件中更新给定团队的teamplace时,该位置必须小于或等于同一事件中参与者团队的数量。
我的触发器如下:

Before update on participateTeams
for each row
Declare participants number;
Begin
     select count(*) into participants from participateteams where :New.eventName = participateteams.eventName;

        if(:NEW.teamplace>participants) then
            RAISE_APPLICATION_ERROR(-20250,'O lugar da equipa é inválido');
        end if;
End;
/

根据我的研究,这是因为我试图读取调用触发器的同一个表。我也尝试过将代码的select部分导出到函数中,但问题仍然存在。
活动的参与者是团队本身,而不是组成这些团队的个人。示例:如果a队、b队和c队参加了一个事件e,则同一事件e的计数应为3。
有什么建议吗?谢谢您。

umuewwlo

umuewwlo1#

变异表错误只是一种痛苦。你要做的是相当棘手的。这里有一种方法:
将列添加到 teams 参加人数。
维护此列 insert / update ,和 delete 触发器打开 participateteams .
编写一个用户定义的函数来获取给定团队的计数。
添加 check 约束 participateteams 使用用户定义的函数。

b4qexyjb

b4qexyjb2#

逻辑上正确的触发条件是:-

CREATE OR REPLACE TRIGGER TRIG_CHK
AFTER INSERT OR UPDATE OF teamPlace ON participateteams
FOR EACH ROW
DECLARE
participants NUMBER;
BEGIN
 select count(*) into participants from participateteams where :New.eventName = 
 participateteams.eventName;
    if(:NEW.teamplace>participants) then
        RAISE_APPLICATION_ERROR(-20250,'O lugar da equipa é inválido');
    end if;
End;    
update participateteams set teamPlace = 2 where eventName = 'B';

但是,当它在尝试更新表participateteams时出现变异表错误时,为了解决这个棘手的问题,我所做的是:-
步骤1:声明包头中所需的表列

CREATE OR REPLACE PACKAGE PKG_TEAMS AS
v_eventName participateteams.eventName%type;
v_teamPlace participateteams.teamPlace%type;
end;

步骤2:初始化行级触发器中的变量

CREATE OR REPLACE TRIGGER TRG_row
AFTER INSERT OR UPDATE OF teamPlace
ON participateteams
FOR EACH ROW
BEGIN
PKG_TEAMS.v_eventName := :NEW.eventName;
PKG_TEAMS.v_teamPlace := :NEW.teamPlace;
END;

步骤3:现在,使用全局初始化变量,而不是使用:新的伪列

CREATE OR REPLACE TRIGGER TRG_stmt
AFTER INSERT OR UPDATE OF teamPlace ON participateteams
DECLARE 
v_participants NUMBER;
BEGIN
SELECT COUNT(*) INTO v_participants FROM participateteams
WHERE eventName = PKG_TEAMS.v_eventName;
 if(PKG_TEAMS.v_teamPlace>v_participants) then
            RAISE_APPLICATION_ERROR(-20250,'CANNOT UPDATE,AGAINST RULES');
        end if;
End;

相关问题