简体   繁体   中英

sql Trigger: select the FK from another table before insert

I have two database tables.

  1. tblTeams : PK TeamID , TeamName
  2. tblMatches : PK match id , FK HomeTeam , FK AwayTeam,Score .

I am using SQL Server 2008 and I am importing rows through the Wizard from a .csv file. The columns in the csv are hometeam , awayteam , score . Thus, before inserting in the tblMatches , I want a trigger that finds the FK of the team and inserts in the tblMatches the foreign key and not the name.

Any help with that please.

CREATE TRIGGER tblmatches_BeforeInsert
ON tblmatches
BEFORE INSERT
AS 
BEGIN
    INSERT  tblmatches
    SELECT  teamName
    FROM    tblmatches
    WHERE   tblTeams.id = ?i dont know here what to insert? 
END

AFAIK, for a trigger to be called on tblMatches, you need to supply values for all the columns in that table and only for the columns in that table which means, you cannot pass a team name to a trigger so that it can be used to resolve the team ID.

If I were to do it, I would just create a table to insert the raw data as is, let the import wizard write records into this table, define a trigger on this table to insert records into the two derived tables viz. tblTeams, tblMatches. ( SQL Server Triggers )

My attempt at writing one (didn't get a chance to verify as I don't have SQL server)

CREATE TRIGGER teams.process ON teams
AFTER INSERT
AS
BEGIN
    DECLARE @homeTeamId INT
    DECLARE @awayTeamId INT
    DECLARE @maxTeamId INT
    DECLARE @matchId INT

    SELECT @maxTeamId = 0
    SELECT @maxTeamId = ISNULL(MAX(teamId), 0) from tblTeams

    --- Check if home team has already been inserted into the table.
    SELECT @homeTeamId = -1
    SELECT 
        @homeTeamId = teamId 
    FROM 
        tblTeams t
        JOIN inserted i
        ON t.teamName = i.hometeam
    IF (@homeTeamId = -1) 
    BEGIN
        SELECT @homeTeamId = @maxTeamId + 1
        SELECT @maxTeamId = @maxTeamId + 1
        INSERT INTO tblTeams SELECT @homeTeamId, i.hometeam FROM inserted i
    END

    --- Check if away team has already been inserted into the table.
    SELECT @awayTeamId = -1
    SELECT 
        @awayTeamId = teamId 
    FROM 
        tblTeams t
        JOIN inserted i
        ON t.teamName = i.awayteam
    IF (@awayTeamId = -1) 
    BEGIN
        SELECT @awayTeamId = @maxTeamId + 1
        SELECT @maxTeamId = @maxTeamId + 1
        INSERT INTO tblTeams SELECT @awayTeamId, i.awayteam FROM inserted i
    END

    -- insert a record into the matches table with the home team ID and away team ID.
    SELECT @matchId = 0
    SELECT @matchId = ISNULL(MAX(MatchId), 0) FROM tblMatches
    INSERT INTO tblMatches 
    SELECT @matchId + 1, @homeTeamId, @awayTeamId, i.score 
    FROM inserted i
END 

If you want a different representation in the table then you'll probably have to implement a view, and perform the inserts via it, rather than the base table.

Something like:

CREATE TABLE realMatches (
    MatchID int IDENTITY(1,1) not null, /* Identity? */
    HomeTeamID int not null,
    AwayTeamID int not null,
    Score int not null, /* int? */
    constraint PK_realMatches PRIMARY KEY (MatchID),
    constraint FK_Matches_HomeTeams (HomeTeamID) references tblTeams (TeamID),
    constraint FK_Matches_AwayTeams (AwayTeamID) references tblTeams (TeamID)
)
GO
CREATE VIEW tblMatches
AS
    SELECT
        MatchID,
        ht.TeamName as HomeTeam,
        at.TeamName as AwayTeam,
        Score
    FROM
        realMatches m
           inner join
        tblTeams ht
           on
               m.HomeTeamID = ht.TeamID
           inner join
        tblTeams at
           on
               m.AwayTeamID = at.TeamID
GO
CREATE TRIGGER T_Matches ON tblMatches
INSTEAD OF INSERT
AS
     SET NOCOUNT ON

     INSERT INTO realMatches (HomeTeamID,AwayTeamID,Score)
     SELECT ht.TeamID,at.TeamID,i.Score
     FROM
        inserted i
           inner join
        tblTeam ht
           on
              i.HomeTeam = ht.TeamName
           inner join
        tblTeam at
           on
              i.AwayTeam = at.TeamName

You can now (assuming that "A Team" and "Team America" exist in tblTeams ):

INSERT INTO tblMatches (HomeTeam,AwayTeam,Score)
VALUES ('A Team','Team America',19)

Of course, this doesn't (yet) deal with any updates which attempt to change a team in the matches table, nor what to do if a team doesn't yet exist in tblTeam , but you've not asked about those yet.

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