Reputation: 43
I've been researching but I just can't seem to get it right. I have the following tables:
create table school_tb
(idSchool int identity primary key,
nameSchool varchar(100),
schoolPopulation int
)
create table career_tb
(idCareer int identity primary key,
nameCareer varchar(100),
carrerPopulation int,
numberClasses int,
idSchool int foreign key references school_tb(idSchool)
)
to find out the populatuon in the first table I have to SUM() population from the careers in the same school. I need to create a trigger that will update the column population in table school_tb when I update population in career_tb. please help me. I had something like this, but I can't get it to work.
--create trigger updatePopulation
--on career_tb
--for update as
--if UPDATE(carrerPopulation)
--update school_tb set schoolPopulation =(SELECT add(carrerPopulation)
-- from career_tb
-- where idSchool=(SELECT idSchool
-- from career_tb
-- where idCareer=@idCareer)
-- )
--go
I appreciate any help given. thanks
Upvotes: 2
Views: 784
Reputation: 21776
CREATE TRIGGER name ON career_tb
AFTER INSERT, UPDATE, DELETE
AS
BEGIN
SET NOCOUNT ON;
MERGE school_tb T
USING
(
SELECT idSchool, SUM(carrerPopulation) res
FROM
(
SELECT idSchool, carrerPopulation
FROM INSERTED
UNION ALL
SELECT idSchool, -carrerPopulation
FROM DELETED
) t
GROUP BY idSchool
) S
ON T.idSchool = S.idSchool
WHEN MATCHED THEN UPDATE SET
schoolPopulation = T.schoolPopulation +S.res
;
END
Upvotes: 2
Reputation: 19356
This should help you out. Please see the comments inside the body of a trigger.
create trigger updatePopulation
on career_tb
-- to update sum even if carreer gets deleted or inserted
after insert, update, delete
as
-- to avoid trigger messing up rows affected
set nocount on
if UPDATE(carrerPopulation)
begin
-- update sum by difference between previous and current state of one record in career
update school_tb
set schoolPopulation = schoolPopulation + difference
from school_tb
-- derived table sums all the careers changed in one go
inner join
(
-- sum all values from careers by school
select idSchool, sum (carrerPopulation) difference
from
(
-- change sign of previous values
select deleted.idSchool, -deleted.carrerPopulation carrerPopulation
from deleted
union all
-- + current values
select inserted.idSchool, inserted.carrerPopulation
from inserted
) a
group by idSchool
-- Skip update in case of no change
having sum (carrerPopulation) <> 0
) a
on school_tb.idSchool = a.idSchool
end
Upvotes: 3