January 26, 2005 at 12:21 pm
Hi experts,
I created 2 update triggers in 2 tables few weeks ago as following, the reason I created the triggers is that I want to know which record was updated in 2 tables (UPR00100 and UPR00102) when user used Great Plains (Microsoft financial system) to modify any employee's information. Then one of my weekly reports will look for this update_ind=1 (in UPR00100) to export the file to bank to notify any changes for our employee information.
However, when I checked the table, there's more than 500 employee's update_ind set to 1, and user said she only modified less than 30 employees. I am wondering if it's possible that even when user just view the records from the finanical system, it will fire this update trigger????
Is there anyway around it? I only want to set update_ind=1 when there's really a record updated! Thanks.
-------------------------------------------------------
Create Trigger Tg_UpdateIndication On UPR00100
For Update
AS
IF UPDATE (LASTNAME) or update (FRSTNAME) or update (MIDLNAME) or update (BRTHDATE) or update (DEPRTMNT)
BEGIN
update UPR00100
set Update_Ind=1
from inserted
where (inserted.EmployID = UPR00100.EmployID)
END
-------------------------------------------------
CREATE Trigger Tg_UpdateInd On UPR00102
For Update
AS
IF UPDATE (Address1) or update (Address2) or update (CITY) or Update (State) or update (ZIPCODE) or update (Phone1)
BEGIN
update UPR00100
set Update_Ind=1
from inserted
where (inserted.EmployID = UPR00100.EmployID ) and (inserted.ADRSCODE=UPR00100.ADRSCODE)
END
January 26, 2005 at 12:39 pm
Try this :
If Update(?)....
begin
Update UPR set UPR.Update_Ind = 1 from Inserted Ins inner join dbo.UPR00100 UPR on Ins.EmployID = UPR.EmployID and Ins.ADRSCODE = UPR.ADRSCODE
WHERE (Ins.Adress1 UPR.Adress1 or Ins.Address2 UPR.Adress2 or...)
end
the where condition will ignore updates that don't make any changes in the data. Also keep in mind that sql server uses short circuiting so I'd put the fields that are most likely to be updated in the front of the list (might not make a huge difference here since there's only a few updates/day but if you have huge loads of transaction it can be a great boost.).
January 26, 2005 at 1:08 pm
Some rules for you:
1. At the begining of the trigger check for @@rowcount
2. Use the if UPDATE(col) on separated columns. Don't mix them up
3. in the where clause compare old and new vaules and if they permit nulls then account for that also
as an example:
Create Trigger Tg_UpdateIndication On UPR00100
For Update
AS
IF @@ROWCOUNT = 0
RETURN
-- assuming EmployID is primary Key
IF UPDATE (LASTNAME)
begin
update UPR set Update_Ind=1
from
UPR00100 UPR
join
inserted new on new.EmployID = UPR.EmployID
join
deleted old on old.EmployID = UPR.EmployID
where
new.LASTNAME <> old.LASTNAME
or (new.LASTNAME IS NULL and old.LASTNAME IS NOT NULL )
or (new.LASTNAME IS NOT NULL and old.LASTNAME IS NULL )
end
HTH
* Noel
January 26, 2005 at 2:11 pm
Thanks for your help. But I still have problem with my 2nd trigger.
The 2nd trigger will update the 1st table (set Update_Ind=1) when there's a update on 2nd table (UPR00200). So I guess the join is not correct,
join
dbo.UPR00100 UPR1 on UPR1.EmployID = UPR2.EmployID and UPR1.ADRSCODE = UPR2.ADRSCODE
but when I apply the changes in the 2nd trigger, it didn't throw me any errors.
The 1st table is the master, 1 employee can have multiple address, so I have to look up both employid and adrscode.
Here is the 2nd trigger: Can you please point me out where it goes wrong? Thanks.
CREATE Trigger Tg_UpdateInd On UPR00102
For Update
AS
IF @@ROWCOUNT = 0
RETURN
IF UPDATE (Address1) or update (Address2) or update (CITY) or Update (State) or update (ZIPCODE) or update (Phone1)
BEGIN
update UPR00100
set Update_Ind=1
from
UPR00200 UPR2
join
inserted new on new.EmployID = UPR1.EmployID
join
deleted old on old.EmployID = UPR1.EmployID
join
dbo.UPR00100 UPR1 on UPR1.EmployID = UPR2.EmployID and UPR1.ADRSCODE = UPR2.ADRSCODE
where
new.Address1 <> old.Address1
or (new.Address2 <> old.Address2 )
or (new.CITY <> old.CITY )
or (new.State <> old.State )
or (new.ZIPCODE <> old.ZIPCODE )
or (new.Phone1 <> old.Phone1 )
END
January 26, 2005 at 2:21 pm
Do you want to update UPR00200 or UPR00100 cause this
BEGIN
update UPR00100
will update table one instead of 2.
January 26, 2005 at 2:22 pm
>> The 2nd trigger will update the 1st table (set Update_Ind=1) when there's a update on 2nd table (UPR00200). So I guess the join is not correct,
It's updating the 1st table because that's what you're explicitly telling it to do:
>>update UPR00100
Your code is explcitly updating UPR00100 (the 1st table) and not UPR0020.
January 26, 2005 at 2:29 pm
To answer the second trigger I need:
How 101 relates to 102
One record on 101 to many on 102 ?
or
One record on 102 to many on 101?
and through what keys?
can you put some example data?
* Noel
January 26, 2005 at 2:57 pm
Yes, the Update_Ind is only at the 1st table (UPR00100). If there's any updates in 2nd table (UPR00200), the trigger should set Update_Ind=1, and nothing to do with 2nd table but only checking the updates.
1st table(UPR00100) is the master employee table, not duplicate records, employid is the primary key.
example:
employID Lname FName MidName ADRSCODE
999999999 Doe John Premary
2nd table(UPR00200) is the employee information table. 1 employee can have more than 1 rows because the they can have up to 3 addresses. The employid and ADRSCODE are keys.
employid ADRSCODE ADDRESS1 Phone
999999999 Primary 123 Elm St. 6309093489
999999999 Secondary 333 Main St. 3128887909
January 26, 2005 at 3:18 pm
Update UPR00100
set Update_Ind=1
from UPR00100 As u1
Where Exists (
Select *
From inserted As new
Inner Join deleted As old
On ( new.EmployID = old.EmployID and
new.AdrsCode = old.AdrsCode )
Where new.EmployID = u1.EmployID
And ( new.Address1 <> old.Address1
or (new.Address2 <> old.Address2 )
or (new.CITY <> old.CITY )
or (new.State <> old.State )
or (new.ZIPCODE <> old.ZIPCODE )
or (new.Phone1 <> old.Phone1 ) )
)
January 26, 2005 at 3:19 pm
here you go!
update UPR1
set Update_Ind=1
from
UPR00100 UPR1
join
inserted new on new.EmployID = UPR1.EmployID and new.ADRSCODE = UPR1.ADRSCODE
join
deleted old on old.EmployID = UPR1.EmployID and old.ADRSCODE = UPR1.ADRSCODE
where
new.Address1 <> old.Address1
or (new.Address2 <> old.Address2 )
or (new.CITY <> old.CITY )
or (new.State <> old.State )
or (new.ZIPCODE <> old.ZIPCODE )
or (new.Phone1 <> old.Phone1 )
Again make sure you check for NULLs
HTH
* Noel
January 26, 2005 at 3:37 pm
There are 2 design issues here, and something we haven't been told about.
1st off, there are cardinality issues, if 2 or more addresses get updated in a batch, you only want to update the parent record *once*. Hence the Exists () in my code.
Secondly, AdrsCode is supposed to be the column which distinguishes the multiple addresses in the child table so what is it also doing in the parent table ?
Including it in the join gurantees that the trigger won't work as designed, because if you update the Secondary address, the join won't locate the parent.
January 27, 2005 at 9:13 am
1st off, there are cardinality issues, if 2 or more addresses get updated in a batch, you only want to update the parent record *once*. Hence the Exists () in my code
True , just it does not makes sense to update 2 addresses of the same person at once (i took a shortcut based on that )
Secondly, AdrsCode is supposed to be the column which distinguishes the multiple addresses in the child table so what is it also doing in the parent table ?
Including it in the join gurantees that the trigger won't work as designed, because if you update the Secondary address, the join won't locate the parent.
AGREED
I do concur with you also that there are either design flaws or missing information in the post. We just try to help with the minimum available but in this case more is probably needed.
* Noel
Viewing 12 posts - 1 through 11 (of 11 total)
You must be logged in to reply to this topic. Login to reply