语句触发器是Oracle吗?

时间:2017-05-24 16:03:16

标签: sql oracle triggers

假设我有这三个表,Player,Thing和playerThing。 Player有一个名字和一个playerLevel,Thing有一个thingName,playerThing有一个playerName,它是Player的外键和一个thingName,它是Thing的外键。

我想要一个触发器,在插入到playerThing之后,检查是否有一个playerName出现的次数比它所引用的玩家更多次具有playerLevel。

就像我说有一个名字叫' John'和playerLevel = 3并且在我的playerThing表中有三行,其中有playerName' John'。因此,如果我尝试插入另一个带有playerName' John'我不希望触发器允许这样做。我一直在尝试,但我不太了解触发因素,而且我不确定如何解决这个问题。

CREATE OR REPLACE TRIGGER thingLevel
AFTER INSERT ON playerThing
BEGIN
    SELECT playerName, count(*) AS num
    FROM playerThing PT
    GROUP BY playerName

    SELECT level as lvl
    FROM Player P
    WHERE P.name = PT.playerName

    IF num > lvl
     //remove entry
END

我知道这是错的,但我不知道如何修复它。我把它放在这里,这样你就可以更好地了解我想做什么。我不明白我将如何删除刚刚插入的条目,或者我是否可以删除。所以,是的,我很失落,我相信你能说出来......

编辑: 嘿,只是发布一个解决方案,如果有人好奇的话我最终会做什么

create or replace trigger numThings
before insert
on playerThing
for each row
declare
 nums number;
 lvl number;
BEGIN
 SELECT count(M.playerName) into nums
 FROM playerThing M
 WHERE M.playerName = :new.playerName;

 SELECT P.playerLevel into lvl
 FROM Player P
 WHERE P.name = :new.playerName;

 If nums+1 > lvl then 
 Raise_Application_Error (-20100,'Level too low');
 End if;
END;
/

1 个答案:

答案 0 :(得分:0)

Player  --<   PlayerThing  >--  Thing

当我想要检查时,m:n表中的数量与行数完全相同,也就是表Player中列级别的值。

所以你必须从播放器中选择列级别,你必须从PlayerThing中选择count(1),其中Playerid =:newPlayerID你可以检查count + 1 =在插入触发器之前的级别或者count = level插入触发器后。

CREATE [ OR REPLACE ] TRIGGER trigger_name
BEFORE/AFTER INSERT
   ON table_name
   [ FOR EACH ROW ]
DECLARE
   -- variable declarations
BEGIN
EXCEPTION
WHEN
-- exception handling