简体   繁体   中英

Oracle PL/SQL Constraint Trigger

I have tables: Teams and Matches.

'Teams' stores the information on football teams and the one I'm particularly interested in is the Country field.

'Matches' stores the information on football matches that happen between the teams listed in 'Teams'. The field I'm interested in from this table is the Competition field. Depending on the type of competition: "All-England" or "All-Spain", etc. the teams involved should be from the appropriate countries.

I'm currently trying to write a Constraint Trigger to handle this but am being thrown a really cryptic error by SQL Developer "invalid and failed re-validation" upon running even if it compiles alright. Anyone care to help? Suggestions on doing things a better way would be great too. PL/SQL block below and I apologise if the following code makes any of you cry. I know I'm terrible at this

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;

In case the problem lies with the tables, I've also included their Create statements. Again, any suggestions or criticisms on these are very welcome.

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

You had 3 mistakes:

  1. && instead of AND .
  2. Accessing matches table instead of :new.competition .
  3. Double EXCEPTION keyword.

Try below code:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM