Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Updating multiple rows with my trigger gives me a subquery error

Posted on 2010-11-25
12
Medium Priority
?
321 Views
Last Modified: 2012-05-10
I have created the following SQL trigger which always returns an error when I run it on multiple rows, so if have more than 1 row and I execute "UPDATE TSDETAIL SET TSD_SUN=120" I get the error below.  When I execute with the KEY such as "UPDATE TSDETAIL SET TSD_SUN=120 WHERE TSD_KEY=1" , I do not get any errors.

My question is how do I write the trigger to work in both cases.

Msg 512, Level 16, State 1, Procedure UPDATE_TSD_RATES, Line 11
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
The statement has been terminated.

ALTER TRIGGER [dbo].[UPDATE_TSD_RATES] ON [dbo].[TSDETAIL]
AFTER UPDATE
AS
DECLARE @v_rate1 NUMERIC(15,4)
DECLARE @v_rate2 NUMERIC(15,4)
DECLARE @v_min   NUMERIC(11)
DECLARE @tsd_key NUMERIC(11)
DECLARE @tsd_rat NUMERIC(11)

BEGIN
    SET @tsd_key=(SELECT TSD_KEY FROM inserted)
    SET @tsd_rat=(SELECT TSD_RAT FROM inserted)
    SET @v_rate1=(SELECT RAT_RATE1 FROM RATE WHERE RAT_KEY=@tsd_rat)
    SET @v_rate2=(SELECT RAT_RATE2 FROM RATE WHERE RAT_KEY=@tsd_rat)
    SET @v_min = (SELECT TSD_MON+TSD_TUE+TSD_WED+TSD_THU+TSD_FRI+TSD_SAT+TSD_SUN FROM inserted)

    UPDATE [dbo].[TSDETAIL] SET TSD_RATE1=@v_rate1, TSD_RATE2=@v_rate2, TSD_MIN=@v_min
      WHERE [dbo].[TSDETAIL].TSD_KEY = @TSD_KEY
END
0
Comment
Question by:hmstechsupport
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 5
  • 2
12 Comments
 
LVL 19

Expert Comment

by:Bhavesh Shah
ID: 34213208
Hi,

As you also know that

when you run below query

UPDATE TSDETAIL SET TSD_SUN=120

This will update multiple rows.

so  SET @tsd_key=(SELECT TSD_KEY FROM inserted) will failed.

You can put (SELECT TOP 1 TSD_KEY FROM inserted) but this is not right way.

Best thing is update query with parameter.

or why you wanted to update multiple at a time????
0
 

Author Comment

by:hmstechsupport
ID: 34213225
The trigger works fine 1 row at a time, but I need to retroactively update the rows that are already in the table and the easiest way is an update statment.  I could write some PLSQL in a stored procedure to update 1 line at a time, but that seems like a long workaround.
Is there no way to write the TRIGGER in SQL to accomplish this?
0
 
LVL 19

Expert Comment

by:Bhavesh Shah
ID: 34213227
or what you can do is....

You can remove trigger and update directly..

UPDATE TSDETAIL
SET TSD_SUN=120,
 TSD_RATE1=RAT_RATE1,
         TSD_RATE2=RAT_RATE2,
 TSD_MIN = TSD_MON+TSD_TUE+TSD_WED+TSD_THU+TSD_FRI+TSD_SAT+TSD_SUN
from TSDETAIL A INNER JOIN RATE B
ON A.TSD_RAT = B.RAT_KEY
WHERE TSD_KEY=1
0
Moving data to the cloud? Find out if you’re ready

Before moving to the cloud, it is important to carefully define your db needs, plan for the migration & understand prod. environment. This wp explains how to define what you need from a cloud provider, plan for the migration & what putting a cloud solution into practice entails.

 
LVL 19

Expert Comment

by:Bhavesh Shah
ID: 34213244
Hi,

It might not be accomplish with trigger, if you can update in single query then that will more beneficial, in terms of performance and debugging view.

As you said I  could write some PLSQL in a stored procedure to update 1 line at a time, but that seems like a long workaround.

- It wont be....i dont think so

0
 

Author Comment

by:hmstechsupport
ID: 34213345
Ok.  I have written the stored procedure to accomplish the update and it works fine and accomplished the immediate solution to the problem, but my question about how to do this in a trigger remains unanswered.  Is there no answer to this?
0
 
LVL 19

Expert Comment

by:Bhavesh Shah
ID: 34213493
0
 

Author Comment

by:hmstechsupport
ID: 34213599
Ok.  Thanks Brichsoft.  Unfortunate, but I guess that is the way it works.
0
 
LVL 71

Accepted Solution

by:
Qlemo earned 2000 total points
ID: 34213764
Of course that is possible. You do not want to insert records, just update, and that is absolutely feasible. And here we go: The "secret" is to consider INSERTED and DELETED as temporary tables you need to join to. DELETED contains the old record, INSERTED the new one. As you do not need the old values here, we can ignore that one.
ALTER TRIGGER [dbo].[UPDATE_TSD_RATES] ON [dbo].[TSDETAIL] 
AFTER UPDATE 
AS
BEGIN
  UPDATE tbl
     SET TSD_RATE1 = RAT_RATE1 
         TSD_RATE2 = RAT_RATE2
         TSD_MIN   = TSD_MON+TSD_TUE+TSD_WED+TSD_THU+TSD_FRI+TSD_SAT+TSD_SUN
    FROM dbo.TSDETAIL tbl
    JOIN inserted i ON tbl.TSD_KEY = i.TSD_KEY
    JOIN RATE     r ON   i.TSD_RAT = r.RAT_KEY
END

Open in new window

0
 
LVL 19

Expert Comment

by:Bhavesh Shah
ID: 34213834
I didnt said,its not possible.but does it require?

Wen u can do it without trigger then why trigger require?



0
 
LVL 71

Expert Comment

by:Qlemo
ID: 34213854
There are many reasons you want to have a trigger acting on the records you have updated:
* updating a secondary table
* no influence to the programming
* expansions which would else require to have the change done on many code lines
* supporting accumulated columns (like the TSD_MIN here).

The danger with such attempt is that is not directly derivable when seeing the query which tables are involved in a transaction. The RATE table would be part of the transaction, hence locked, though the query does not refer to it.
0
 

Author Comment

by:hmstechsupport
ID: 34213927
Ok.  I had to modify this a little as I do want it to work for Insert and Update so I added the INSERT clause and I had to make a few other minor changes adding commas and adding aliases to avoid ambiguity but this is EXACTLY what I hoped for.  Works like a charm in both inserting new rows and also running a big update statement.
Thank you Qlemo.
I also agree that the reason I do this is to avoid adding code to the application that ther clients do not require.  This trigger suits this client perfectly.

ALTER TRIGGER [dbo].[UPDATE_TSD_RATES] ON [dbo].[TSDETAIL]
AFTER INSERT,UPDATE
AS
BEGIN
  UPDATE tbl
     SET TSD_RATE1 = r.RAT_RATE1,
         TSD_RATE2 = r.RAT_RATE2,
         TSD_MIN   = tbl.TSD_MON+tbl.TSD_TUE+tbl.TSD_WED+tbl.TSD_THU+tbl.TSD_FRI+tbl.TSD_SAT+tbl.TSD_SUN
    FROM dbo.TSDETAIL tbl
    JOIN inserted i ON tbl.TSD_KEY = i.TSD_KEY
    JOIN RATE     r ON   i.TSD_RAT = r.RAT_KEY
END
0
 

Author Closing Comment

by:hmstechsupport
ID: 34213931
Fabulous and exactly what I was looking for.
0

Featured Post

Three Reasons Why Backup is Strategic

Backup is strategic to your business because your data is strategic to your business. Without backup, your business will fail. This white paper explains why it is vital for you to design and immediately execute a backup strategy to protect 100 percent of your data.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you have heard of RFC822 date formats, they can be quite a challenge in SQL Server. RFC822 is an Internet standard format for email message headers, including all dates within those headers. The RFC822 protocols are available in detail at:   ht…
How to leverage one TLS certificate to encrypt Microsoft SQL traffic and Remote Desktop Services, versus creating multiple tickets for the same server.
In this video, Percona Director of Solution Engineering Jon Tobin discusses the function and features of Percona Server for MongoDB. How Percona can help Percona can help you determine if Percona Server for MongoDB is the right solution for …
Want to learn how to record your desktop screen without having to use an outside camera. Click on this video and learn how to use the cool google extension called "Screencastify"! Step 1: Open a new google tab Step 2: Go to the left hand upper corn…

661 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question