Oracle PL / SQL约束触发器

时间:2013-10-18 08:34:16

标签: sql oracle plsql constraints

我有桌子:团队和比赛。

'Teams'存储有关足球队的信息,而我特别感兴趣的是国家队。

'匹配'存储“团队”中列出的球队之间发生的足球比赛信息。我从这张桌子感兴趣的领域是竞赛领域。根据比赛的类型:“全英格兰”或“全西班牙”等,所涉及的球队应来自相应的国家。

我目前正在尝试编写一个Constraint Trigger来处理这个问题但是,即使编译好了,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')
);

1 个答案:

答案 0 :(得分:1)

你有3个错误:

  1. &&代替AND
  2. 访问matches表而不是:new.competition
  3. 加倍EXCEPTION关键字。
  4. 尝试以下代码:

    -- 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;