2013-10-18 48 views
1

我有表:团队和匹配。Oracle PL/SQL约束触发器

'团队'存储足球队的信息,我特别感兴趣的是国家/地区领域。

'Matches'存储关于'Team'中列出的球队之间发生的足球比赛的信息。我从这张表中感兴趣的领域是比赛场地。根据比赛类型:“全英格兰”或“全西班牙”等,所涉及的团队应来自适当的国家。

我目前正在尝试编写一个约束触发器来处理这个问题,但是在运行时即使编译好的时候,SQL Developer也会抛出一个非常神秘的错误“无效且失败的重新验证”。任何人都在意帮忙吗?建议以更好的方式做事情也会很棒。下面的PL/SQL块,我很抱歉,如果下面的代码让你们任何一个哭了。我知道我很可怕

CREATE OR REPLACE TRIGGER matchcountry_BIR 
BEFORE INSERT ON matches 
FOR EACH ROW 

DECLARE 
invalidEng EXCEPTION; 
invalidSpa EXCEPTION; 
team1 teams.Country%type; 
team2 teams.Country%type; 
comp matches.Competition%type; 

BEGIN 
SELECT Country INTO team1 FROM teams WHERE TeamID = :new.TeamID_A; 
SELECT Country INTO team2 FROM teams WHERE TeamID = :new.TeamID_B; 
comp:=:new.Competition; 

IF (comp='All England') AND (team1!='England' AND team2!='England') THEN 
RAISE invalidEng; 
END IF; 

IF (comp='All Spain') AND (team1!='Spain' AND team2!='Spain') THEN 
RAISE invalidSpa; 
END IF; 

EXCEPTION 
WHEN invalidEng THEN 
RAISE_APPLICATION_ERROR(-20005, 'Countries are invalid for a English competition.'); 
END; 

EXCEPTION 
WHEN invalidSpa THEN 
RAISE_APPLICATION_ERROR(-20006, 'Countries are invalid for a Spanish competition.'); 
END; 

如果问题出在表格上,我还包括了他们的Create语句。再次,对这些建议或批评是非常受欢迎的。

CREATE TABLE teams 
(
    TeamID number(2) PRIMARY KEY, 
    TeamName varchar2(50), 
    Country varchar2(30), 
    CHECK (Country='Spain' OR Country='England') 
); 

CREATE TABLE matches 
(
    MatchID number(2) PRIMARY KEY, 
    TeamID_A number(2), 
    TeamID_B number(2), 
    Goal_A number(2), 
    Goal_B number(2), 
    Competition varchar2(50), 
    CONSTRAINT fk_TeamA FOREIGN KEY(TeamID_A) REFERENCES teams, 
    CONSTRAINT fk_TeamB FOREIGN KEY(TeamID_B) REFERENCES teams, 
    CHECK (Goal_A >= 0), 
    CHECK (Goal_B >= 0), 
    CHECK (Competition='Champions League' OR Competition='Europa League' OR Competition='All England' OR Competition='All Spain') 
); 
+0

在Oracle中,你使用'和'运营商,而不是''&&,所以你应该在你的代码进行更改。另外,为什么你从'matches'表中选择了'MatchID'等于新记录ID的比赛?您应该使用':new.competition'来检查新记录的值。 –

+0

复合键外键可以让你用声明方式解决你的问题。 –

+0

嗯谢谢你的评论。我已经提出了你建议的修正,Przemyslaw。 但是,我仍然收到相同的错误。 – ScoopsaHaagenDazs

回答

1

你有3个错误:

  1. &&代替AND
  2. 访问matches表而不是:new.competition
  3. Double EXCEPTION关键字。

试试下面的代码:

-- Trigger will not let an insert on the Match table with invalid countries for the competition 
CREATE OR REPLACE TRIGGER matchcountry_BIR 
BEFORE INSERT ON matches 
FOR EACH ROW 

DECLARE 
    invalidEng EXCEPTION; 
    invalidSpa EXCEPTION; 
    team1 teams.Country%type; 
    team2 teams.Country%type; 
    comp matches.Competition%type; 

BEGIN 
    SELECT Country INTO team1 FROM teams WHERE TeamID = :new.TeamID_A; 
    SELECT Country INTO team2 FROM teams WHERE TeamID = :new.TeamID_B; 
    --SELECT Competition INTO comp FROM matches WHERE MatchID = :new.MatchID; 
    comp := :new.competition; 

    IF (comp='All England') AND (team1!='England' AND team2!='England') THEN 
    RAISE invalidEng; 
    END IF; 

    IF (comp='All Spain') AND (team1!='Spain' AND team2!='Spain') THEN 
    RAISE invalidSpa; 
    END IF; 

EXCEPTION 
    WHEN invalidEng THEN 
    RAISE_APPLICATION_ERROR(-20005, 'Countries are invalid for a English competition.'); 

    WHEN invalidSpa THEN 
    RAISE_APPLICATION_ERROR(-20006, 'Countries are invalid for a Spanish competition.'); 
END; 
+1

我有很多东西需要学习。约束现在按预期工作。我需要重新组织我的牌桌,但这有助于给我一个模板来解决问题。再次感谢。 – ScoopsaHaagenDazs