September 20, 2005 at 11:01 pm
I have written a trigger to update a field when data is inserted into a table (see code below)
DECLARE @IRN char(12)
SET @IRN = (SELECT IRN FROM inserted)
IF(SELECT COUNT(IRN) FROM ProductionControl WHERE IRN = @IRN) > 0
UPDATE ImagingEmu SET DA = 1
WHERE IRN = @IRN.
It works ok except that it updates all of the rows where the condition applies. I'd prefer it to just update the row which is being inserted. How can I accomplish this?
Thanks
RB
September 21, 2005 at 1:41 am
What's the primary key of the table?
As an aside, the way your trigger is written only caters for single row inserts. Try this
IF EXISTS (SELECT 1 FROM ProductionControl WHERE IRN IN (SELECT IRN FROM INSERTED))
UPDATE ImagingEmu SET DA = 1 WHERE [primary key] IN (SELECT [primary key] FROM INSERTED
Replace [primary key] with whatever the unique field is in your table. Not sure about the if statement. Some DDL would make things clearer.
hth
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability
September 21, 2005 at 4:29 pm
Thanks for the reply,
Unfortunately there is no primary key in 'inserted'. This is for a request system. A primary key only gets generated when the request is inserted into the ProductionControle table.
Is there another way or referencing the row being inserted?
RB
September 22, 2005 at 12:07 am
The only way is to match what's in inserted with the real table is on a unique field or a unique combination of fields. SQL has no concept of row position.
Note that inserted has all the columns of the table that the trigger is on, and that triggers happen after the insert/update/delete has happened.
You could always add an identity field to get you something unique. The identity is auto populated when the record is inserted and it's always increasing.
Would you mind posting the definitions of the tables involved, some sample data and what it is that you're trying to do. It may be that someone here could see an alternative.
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability
September 22, 2005 at 1:00 am
Thanks
I've come up with this which seems to work ok.
CREATE TRIGGER [UpdateDA] ON [dbo].[ImagingEmu]
FOR INSERT
AS
DECLARE @IRN char(12)
SET @IRN = (SELECT IRN FROM inserted)
IF(SELECT COUNT(IRN) FROM ProductionControl WHERE IRN = @IRN) > 0
DECLARE @RequestNo int
DECLARE rn_cursor CURSOR
LOCAL SCROLL STATIC
FOR
SELECT RequestNo FROM ImagingEmu
OPEN rn_cursor
FETCH LAST FROM rn_cursor
INTO @RequestNo
UPDATE ImagingEmu SET DA = 1
WHERE IRN = @IRN
AND RequestNo = @RequestNo
CLOSE rn_cursor
DEALLOCATE rn_cursor
I think I need to stick with one row at time because each row has a different value for IRN which is what needs to be checked in the ProductionControl table.
RB
September 22, 2005 at 2:38 am
I hate cursors. There's usually a better way....
The way you've written it, if there are multiple rows inserted at once, only one of them will be processed for updating ImagingEmu. (Whichever one SQL picks from inserted for the variable assignment) Bear in mind that a trigger will execute only once for an insert, whether you insert 1 record or 1 million records.
Also the entire thing of get RequestID from ImagingEmu then use it to match records from ImagingEmu doesn't make any sense. You might as well match only on IRN like earlier. I think that should have been DECLARE CURSOR ... FOR SELECT ResourceID FROM inserted
Try this instead of the whole cursor. If I've understood what you're doing (and there's a definate posibility that I haven't) this should do what you want.
Update ImagingEmu SET DA = 1
WHERE EXISTS (SELECT 1 FROM inserted WHERE inserted.IRN=ImagingEmu.IRN AND inserted.RequestNo = ImagingEmu.RequestNo) AND IRN IN (SELECT IRN FROM ProductionControl GROUP BY IRN HAVING Count(*)>1)
Find the records in ImagingEmu that match the just inserted rows (matching on IRN and ResourceID and have more than one matching record in ProductionControl (matching on IRN) and set the value of DA to one.
As I said before, table definitions would make it a lot easier to give useful advice.
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability
September 22, 2005 at 5:11 am
Roger
You wouldn't be a developer rather than a DBA would you
If you tried to put a trigger with a cursor into production at our site you'd be lucky to keep your ears. Cursors are bad enough for performance, but to include one in a trigger should be classed as the eighth deadly sin
As mentioned in a prior post, how about posting the DDL for the tables in question and explaining what has to happen. Then as a whole the community will help redeem your soul
--------------------
Colt 45 - the original point and click interface
September 22, 2005 at 5:31 am
You wouldn't be a developer rather than a DBA would you
Be nice. I'm a developer.
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability
September 22, 2005 at 5:34 am
"Be nice. I'm a developer..."
That's ok, I forgive you because "I hate cursors..."
--------------------
Colt 45 - the original point and click interface
September 22, 2005 at 5:14 pm
Apologies if this message is posted twice but the first time I posted it nothing seemed to happen.
Thanks for the above comments. It will take me a little while to process them and provide the information required.
I am a developer (sort of) but this is my first foray into SQL triggers and T-SQL. I probably should have posted my original message to the T-SQL forum but then my soul may have been lost forever.
In the meantime, I take the point that using cursors may have a high overhead but I couldn't think of another way of accessing the last inserted record. I need to do this because the field I want to update isn't in 'inserted' ('inserted' is only a stub of the new record).
Also, I'll have to think further about updating more than one record. Each record is inserted separately into ImagingEmu by the client application and each contains a different value for IRN which needs to be checked for in the ProductionControl table.
RB
September 23, 2005 at 12:11 am
'inserted' is only a stub of the new record
Not sure what you mean by that. inserted contains all the fields that are in the table the trigger is on. If you mean that only a couple of fields are populated when the insert occurres and the rest updated later?
Did you try my single update statement?
Awaiting the table definition and example data.
There's no shame in been new. We all had to start somewhere.
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability
September 23, 2005 at 12:14 am
Seriously, if any of my collegues submitted a trigger with cursors, it would be back on their desk so fast they'd have whiplash.
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability
Viewing 12 posts - 1 through 12 (of 12 total)
You must be logged in to reply to this topic. Login to reply