问题
Right now trigger looks like this and it works partly
My trigger looks like this
ALTER trigger [dbo].[tr_EligebilityCheck]
on [dbo].[Clients]
for INSERT,update
as
BEGIN
UPDATE Clients
SET
StatusID = 5
WHERE
ClientID IN (Select ClientID
from Clients c
join inserted --ADD THIS JOIN
on inserted.ClientID = c.ClientID
join IncomeEligibility i
on c.HshldSize = i.HshldSize
where StatusID in (1,2)
and WIC = 0
and (c.CategCode = 'SR'
and ((MonthlyYearly = 'month' and c.AnnualHshldIncome >= i.SeniorMo)
or (c.AnnualHshldIncome >= i.SeniorYr and MonthlyYearly ='year'))
and DATEDIFF(YEAR,DOB,GETDATE()) < 60)
or
(c.CategCode = 'CH'
and ((MonthlyYearly = 'month' and c.AnnualHshldIncome >= i.WomanChildMo)
or (c.AnnualHshldIncome >= i.WomanChildYr and MonthlyYearly ='year'))
and DATEDIFF(YEAR,DOB,GETDATE()) > 6))
update Clients
set StatusID = 4
where WIC =1
from Clients --ADD THIS FROM STATEMENT
join inserted --ADD THIS JOIN
on inserted.ClientID = Clients.ClientID
END
when I inset client with CategCode = 'SR' it check only DOB and fire if client is younger than 60 but if clients is older it did not check this
and ((MonthlyYearly = 'month' and c.AnnualHshldIncome >= i.SeniorMo)
or (c.AnnualHshldIncome >= i.SeniorYr and MonthlyYearly ='year'))
If I insert client with CategCode = 'CH' it check Income but did not check DOB.
回答1:
As long as you have a proper reference to a primary key, I don't see why you would need an INSTEAD OF trigger. It doesn't seem like there is any situation in which you'd prevent an insert or update, correct? You just want to make sure of the value of StatusID. There's no reason that has to be done before the update.
I believe the reason you're getting too many rows updated is that you're not limiting the trigger to only those rows in the inserted table. Try adding a join to your trigger, like so:
ALTER trigger [dbo].[tr_EligebilityCheck]
on [dbo].[Clients]
for INSERT,update
as
BEGIN
UPDATE Clients
SET
StatusID = 5
WHERE
ClientID IN (Select ClientID
from Clients c
join inserted --ADD THIS JOIN
on inserted.ClientID = c.ClientID
join IncomeEligibility i
on c.HshldSize = i.HshldSize
where StatusID in (1,2)
and WIC = 0
and (c.CategCode = 'SR'
and ((MonthlyYearly = 'month' and c.AnnualHshldIncome >= i.SeniorMo)
or (c.AnnualHshldIncome >= i.SeniorYr and MonthlyYearly ='year'))
and DATEDIFF(YEAR,DOB,GETDATE()) < 60)
or
(c.CategCode = 'CH'
and ((MonthlyYearly = 'month' and c.AnnualHshldIncome >= i.WomanChildMo)
or (c.AnnualHshldIncome >= i.WomanChildYr and MonthlyYearly ='year'))
and DATEDIFF(YEAR,DOB,GETDATE()) > 6))
update Clients
set StatusID = 4
where WIC =1
from Clients --ADD THIS FROM STATEMENT
join inserted --ADD THIS JOIN
on inserted.ClientID = Clients.ClientID
END
If you do want to use an INSTEAD OF trigger, a few pointers on that: INSTEAD OF is not the same thing as BEFORE UPDATE. BEFORE UPDATE alters the inserted table and then proceeds with the update. INSTEAD OF cancels the insert or update entirely, which means you need to explicitly re-write it. I have an example below.
Also, if you want to use an INSTEAD OF trigger, you'll either need separate INSERT and UPDATE triggers, or you'll need to write your query as a MERGE statement. I'll use INSERT in my example below:
ALTER trigger [dbo].[tr_EligebilityCheck]
on [dbo].[Clients]
INSTEAD OF INSERT
as
BEGIN
--First, set StatusID in the inserted table
UPDATE inserted
SET
StatusID = 5
WHERE
ClientID IN (Select ClientID
from Clients c
join IncomeEligibility i
on c.HshldSize = i.HshldSize
where StatusID in (1,2)
and WIC = 0
and (c.CategCode = 'SR'
and ((MonthlyYearly = 'month' and c.AnnualHshldIncome >= i.SeniorMo)
or (c.AnnualHshldIncome >= i.SeniorYr and MonthlyYearly ='year'))
and DATEDIFF(YEAR,DOB,GETDATE()) < 60)
or
(c.CategCode = 'CH'
and ((MonthlyYearly = 'month' and c.AnnualHshldIncome >= i.WomanChildMo)
or (c.AnnualHshldIncome >= i.WomanChildYr and MonthlyYearly ='year'))
and DATEDIFF(YEAR,DOB,GETDATE()) > 6));
update inserted
set StatusID = 4
where WIC =1;
--Once the inserted table looks right, proceed with the insert
--You need to explicitly write an insert statement, or nothing will happen
INSERT INTO [dbo].[Clients]
<column_list>
SELECT <column_list>
FROM inserted;
来源:https://stackoverflow.com/questions/15237583/sql-server-trigger-update-data-in-to-table-but-should-update-data-only-when-cust