Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 Transact-SQL (2000)
 UPDATE Multiple Rows-one at a time

Author  Topic 

MorrisK
Yak Posting Veteran

83 Posts

Posted - 2005-11-02 : 16:44:50
I want to update values in one table with values from another table. I have an update trigger on the table I'm updating and when I run my update I get the "Subquery returned more than 1 value." message referencing the trigger.

I thought I would try modifying my update rather than my trigger because it seems that this situation should normally not occur. In other words only one record should normally be updated at a time.

I need to update BuyerCodes in a ItemMaster table to match the BuyerCode in the ItemClass table where ItemMaster.BuyerCode <> ItemClass.BuyerCode

ItemMaster table

Item ItemClass ItemCategory BuyerCode
123 C1 B B1
456 C1 B B1
789 C1 B B2
abc C2 B B3
def C1 M B1


ItemClass table

ItemClass BuyerCode
C1 B2
C2 B3

In this example, I need to update Items 123 and 456. Here is what I'm using but I get the error because of the multiple rows to update.

UPDATE ItemMaster
SET Buyer = ItemClass.Buyer
FROM ItemMaster, ItemClass
WHERE ItemMaster.ProductClass = ItemClass.ProductClass
AND ItemMaster.ItemCategory = 'B' AND LEN(ItemClass.Buyer)<>0
AND (LEN(ItemMaster.Buyer)=0 OR ItemMaster.Buyer<>ItemClass.Buyer)

If I wanted to change the sql for the UPDATE above so that it updates the rows one at a time, how would I do it?

Or would it be easier to change my trigger to handle multiple row updates? If this is the case, would I use a cursor to loop through the updated records?

Thanks in advance,

Kevin

nathans
Aged Yak Warrior

938 Posts

Posted - 2005-11-02 : 19:02:18
Can you post the trigger code?


Thanks

Nathan Skerl
Go to Top of Page

afrika
Master Smack Fu Yak Hacker

2706 Posts

Posted - 2005-11-03 : 04:18:27
It would be better to use a stored proceedure. Like nathans said, paste your code here
Go to Top of Page

blindman
Master Smack Fu Yak Hacker

2365 Posts

Posted - 2005-11-03 : 09:40:06
quote:
...Or would it be easier to change my trigger to handle multiple row updates? If this is the case, would I use a cursor to loop through the updated records?


ALWAYS write triggers to handle multi-record transactions.
AVOID putting cursors in triggers.
To handle multi-record transactions, your trigger should make use of the virtual "inserted" and "deleted" tables.
Writing triggers that can only handle single-record transaction is, in my opinion, one of the worst coding transgressions anyone can make.
Go to Top of Page

MorrisK
Yak Posting Veteran

83 Posts

Posted - 2005-11-03 : 10:03:48
Here is the trigger that is giving the error. In our company, bought-out items are supposed to have TraceableType = 'T', except if they have ItemClass = 'C2'. This trigger checks new items for this as they are added and lets us know if they are not.

IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'BoughtOutNotTraceableINSERT' AND type = 'TR')
DROP TRIGGER BoughtOutNotTraceableINSERT
GO
Create Trigger BoughtOutNotTraceableINSERT
On dbo.ItemMaster
For INSERT
As
IF ((SELECT ins.ItemCategory FROM inserted ins) = 'B'
AND (SELECT ins.ItemClass FROM inserted ins) <>'C2'
AND (SELECT ins.TraceableType FROM inserted ins) <>'T')
BEGIN
declare @From varchar(90),
@To varchar(90),
@Subject varchar(100),
@Body varchar(4000),
@Item varchar(30),
@Descr varchar(30),
@DBNumber varchar(128),
@Oper varchar(6)

select @Item = (SELECT RTRIM(ins.Item) FROM inserted ins),
@Descr = (SELECT RTRIM(ins.Description) FROM inserted ins),
@DBNumber = (SELECT RIGHT(DB_NAME(),1)),
@Oper = (SELECT TOP 1 ItemMastAmendJnl.OperatorCode
FROM ItemMastAmendJnl, inserted ins
WHERE ItemMastAmendJnl.Item= ins.Item
ORDER BY ItemMastAmendJnl.JnlDate DESC , ItemMastAmendJnl.JnlTime DESC),
@From = 'my-email@my-company.com',
@To = 'their-email@my-company.com',
@Subject = 'Bought-out item, '+@Item+', added and not set as lot traceable',
@Body = @Item+', '+@Descr+', ',
@Body = @Body+'was inserted into the ItemMaster table in the company ',
@Body = @Body+@DBNumber+' database as a bought-out item but was not set as lot traceable. ',
@Body = @Body+'This item was added by operator '+@Oper+'.'

exec sp_send_cdosysmail @From,@To,@Subject,@Body

END
GO

How can I modify it to handle multiple row updates without using a cursor?

Kevin
Go to Top of Page

MorrisK
Yak Posting Veteran

83 Posts

Posted - 2005-11-07 : 18:23:13
Suggestions anyone? I'm not sure what to do.

blindman says

quote:
To handle multi-record transactions, your trigger should make use of the virtual "inserted" and "deleted" tables.



I'm using inserted and deleted but how do you handle multiple records?

Thanks,

Kevin
Go to Top of Page

tkizer
Almighty SQL Goddess

38200 Posts

Posted - 2005-11-07 : 18:28:30
You will need to loop through every row in the inserted table using a WHILE loop or a cursor. You have to loop due to needing to call sp_send_cdosysmail for each row. You can not do this set-based.

Tara Kizer
Go to Top of Page

X-Factor
Constraint Violating Yak Guru

392 Posts

Posted - 2005-11-07 : 19:16:32
I'm having a similar issue. I need a trigger that will recurse up a tree stored in a table looking for circular references. I think this requires a WHILE loop in order to check every row inserted or updated.

I figure I can put the WHILE loop in a UDF and call the UDF in the SELECT clause. My plan was to raise an error when a circular reference was found but its saying 'Invalid use of 'RAISEERROR' within a function.'.

Any ideas?

Also how does one WHILE loop over all the rows in the inserted table? Something like this....

SELECT TOP 1 * FROM inserted WHERE PK > @lastPK
Go to Top of Page

alexsts2010
Starting Member

3 Posts

Posted - 2011-12-09 : 14:25:33
correction to update statement to narrow it down to those 2 rows:

update ItemMaster t
set t.buyerCode= IC.buyerCode
from ItemClass IC where
t.itemClass=IC.ItemClass and t.item in (select item from ItemClass where BuyerCode='B1') and t.ItemCategory='B'

AB
Go to Top of Page

tkizer
Almighty SQL Goddess

38200 Posts

Posted - 2011-12-09 : 14:34:53
Why are you adding posts to a thread that is 6 years old? I've deleted your other two replies as a result.

Tara Kizer
Microsoft MVP for Windows Server System - SQL Server
http://weblogs.sqlteam.com/tarad/

Subscribe to my blog
Go to Top of Page
   

- Advertisement -