简体   繁体   中英

Trigger involving two tables SQL

I have two tables:

CONTRACTS (player, team)

MATCHES (player, team, match)

team is a NUMBER(1) from 0 to 9.

Attribute team in MATCHES have to be the same of this player in contracts or 1 less or 1 more. (In matches, the same player could appear more than one time).

I have to check with a trigger if all the players in MATCHES fulfill the condition that I stated previously

I have tried that, but not found:

  CREATE TRIGGER trigA
  BEFORE INSERT OR UPDATE OF team on matches
  FOR EACH ROW
  DECLARE error EXCEPTION;
  BEGIN
  IF (:NEW.team!=contracts.team OR :NEW.team!=contracts.team +1 OR :NEW.team!=contracts.team -1) AND (:NEW.player) = contracts.player
  THEN error;
  END IF;
  EXCEPTION
  WHEN error THEN DBMS_OUTPUT.PUT_LINE('Invalid Team');
  END;
/

In your trigger you need to query the CONTRACTS table within your trigger, looking for CONTRACTS rows which satisfy the condition you've got. If you find at least one everything is fine. If you don't you need to raise an error.

Something like this:

CREATE TRIGGER MATCHES_BIU_TEAM
  BEFORE INSERT OR UPDATE OF team on matches
  FOR EACH ROW
DECLARE
  nContract_count  NUMBER;
BEGIN
  SELECT COUNT(*)
    INTO nContract_count
    FROM CONTRACTS c
    WHERE c.PLAYER = :NEW.PLAYER AND
          c.TEAM BETWEEN :NEW.TEAM - 1
                     AND :NEW.TEAM + 1;

  IF nContract_count = 0 THEN
    RAISE_APPLICATION_ERROR(...);
  END IF;
END MATCHES_BIU_TEAM;

Go look up how to use RAISE_APPLICATION_ERROR to raise an exception which the calling program can capture. This is important because if an exception does occur you don't want to just have it disappear in an EXCEPTION handler in a trigger - it needs to be raised so that the calling application code can handle it.

Best of luck.

Another approach would be this:

CREATE TRIGGER MATCHES_BIU_TEAM
  BEFORE INSERT OR UPDATE OF team on matches
  FOR EACH ROW
DECLARE
  matchTeam  NUMBER;
BEGIN
  SELECT c.team
    INTO matchTeam
    FROM CONTRACTS c
    WHERE c.player = :NEW.player;

  IF matchTeam < :NEW.team - 1 OR matchTeam > :NEW.team + 1 THEN
    RAISE_APPLICATION_ERROR(...);
  END IF;
END MATCHES_BIU_TEAM;

This assumes a) that you want to compare the value of contracts.team with the value of matches.team (Bob Jarvis' answer compares the number of records in contracts to the value of matches.team ), and b) that there is exactly one record in contracts for each player.

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