在Oracle Sql数据库上触发

时间:2018-12-18 20:24:14

标签: sql oracle oracle11g

我的sql数据库有一些问题要解决:

  • 确保玩家只能有2张黄牌或1张红牌
  • 一队最多不能有5名外国球员(国籍与法国国籍不同的球员)

我的模型是这样的:

Team
-------
team_id (PK)
name

Player
-------
player_id (PK)
team_id (FK)
name
number_yellow_cards
number_red_cards
nationality

我认为触发器可以解决我的问题。这是我的触发器,但是在任何情况下(插入/更新)都无效

create or replace TRIGGER foreign_players
Before Insert OR UPDATE on Player
FOR EACH ROW 
DECLARE nr_foreign_players INTEGER;
Begin

  IF INSERTING THEN
    SELECT Count(*) INTO nr_foreign_players
    FROM
        Team T
        INNER JOIN Player P ON P.team_id = T.team_id
    WHERE 
        P.team_id =  :new.team_id 
        AND P.nationality <> 'French';

    if(nr_foreign_players > 5) then
        Raise_Application_Error(-20000,'Error insert' ); 
    End If;
  END IF; --INSERTING

  IF UPDATING THEN
    SELECT Count(*) INTO nr_foreign_players
    FROM
        Team T
        INNER JOIN Player P ON P.team_id = T.team_id
    WHERE 
        P.team_id =  :new.team_id 
        AND P.nationality <> 'French';

    if(nr_foreign_players > 5) then
    Raise_Application_Error(-20000,'Error update' ); 
    End If;
  END IF; --UPDATING


End;

有人可以帮助我吗?

1 个答案:

答案 0 :(得分:0)

这不是100%肯定的答案,因为您没有完全告诉我们在任何情况下都不起作用

我发现您的触发器有几个问题:

  1. 确保一支球队最多只能有5名非法国球员的逻辑似乎是正确的,但是为什么要为INSERTUPDATE复制呢?这可以简化。

  2. 您根本无法验证玩家只能拥有2张黄牌或1张红牌

这是更新的SQL代码,应该可以完成工作。它会逐个执行每个检查,一旦一项检查失败,就会引发应用程序异常。 INSERTUPDATE操作之间没有区别,因为两种操作的逻辑完全相同。

CREATE OR REPLACE TRIGGER foreign_players
BEFORE INSERT OR UPDATE ON Player
FOR EACH ROW 
DECLARE 
    nr_foreign_players INTEGER;
BEGIN

    IF NVL(:new.number_yellow_cards, 0) > 2 THEN
        Raise_Application_Error(-20000, 'Too many yellow cards' ); 
    END IF;

    IF NVL(:new.number_red_cards, 0) > 1 THEN
        Raise_Application_Error(-20000, 'Too many red cards' ); 
    END IF;

    SELECT Count(*) INTO nr_foreign_players
    FROM
        Team T
        INNER JOIN Player P ON P.team_id = T.team_id
    WHERE 
        P.team_id =  :new.team_id 
        AND P.nationality <> 'French';
    IF nr_foreign_players > 5 THEN
        Raise_Application_Error(-20000, 'Too many foreign players' ); 
    END IF;

END;