Update Trigger Affecting Too Many Rows - sql

I wrote the following trigger:
begin
update NFL.TeamStatistics
set Passing_Yards = (select sum(Quarterbacks.Yards)
from NFL.Quarterbacks
where Quarterbacks.Team = inserted.Team)
from NFL.Quarterbacks
inner join inserted on Quarterbacks.Team = inserted.Team;
Whenever someone updates the passing yards in the table about quarterbacks, it should automatically set NFL.TeamStatistics.Passing_Yards to the sum of each team's passing yards.
I used the following update statement to test it:
update NFL.Quarterbacks
set Quarterbacks.Yards = 4000
where Team = 'PIT';
However, in the table NFL.TeamStatistics it set the passingyards for all teams to 4000 instead of just for PIT. What is the matter?

You need to add a where clause and column in NFL.TeamStatistics that you want to compare to
e.g:
begin
update NFL.TeamStatistics
set Passing_Yards = (select sum(Quarterbacks.Yards)
from NFL.Quarterbacks
where Quarterbacks.Team = inserted.Team)
from NFL.Quarterbacks
inner join inserted on Quarterbacks.Team = inserted.Team
where Team = Quarterbacks.Team;
Assuming you were comparing to Quaterbacks.Team

You should use where clause in your update statement in order to filter data you are going to update.

Related

Run multiple update statements on same table in stored procedure using values from table vlued parameter

I want to update a column in a table uing values from a table valued parameter, then I want to update another column (same rows) depending on the value of the column that was updated on first statement. Here is the code:
#reports as WhatsTableType ReadOnly
BEGIN
update dbo.tblappointments Set dbo.tblappointments.D_report = r.D_report
from dbo.tblappointments as A inner join #reports as r on A.appointmentID = r.appointmentID;
update dbo.tblappointments Set dbo.tblappointments.WantSMS = 0
from dbo.tblappointments as A inner join #reports as r on A.appointmentID = r.appointmentID
where A.D_report = 'Read' or A.D_report = 'DEVICE';
END
The table parameter contain two columns (appointmentID, D_report). I guess I can use single update statement using IIF, I'm not sure about the best way to do this.
Thank you.
Depending on what you want WantSMS to become if D_Report is something else, or NULL, or if it should depend on the existing value in the table, you can do this in one statement as follows:
UPDATE A Set
A.D_report = r.D_report,
A.WantSMS = CASE
-- need to check R for the _new_ value:
WHEN r.D_Report IN ('Read', 'DEVICE') THEN 0
ELSE A.WantSMS END
FROM dbo.tblappointments as A
INNER JOIN #reports as r
ON A.appointmentID = r.appointmentID;
IIF is just fancy CASE but I find CASE a lot more flexible. YMMV.

SQL Server After Update Trigger - Single Table - 2 Columns

I have a table (dbo.membersdatatable) that has multiple columns. I would like this trigger to update a column called "memberstatus" when "memberdesignation" is updated to a value of "10" from a value of "9".
-------SQL STATEMENT BELOW---------------
IF UPDATE([MemberDesignation])
--need to make it so it will recognize when memberdesignation = 10
UPDATE dbo.MembersDataTable
SET MemStatus = '0'
FROM dbo.MembersDataTable AS mdtbl
INNER JOIN inserted AS i ON i.StudentID = mdtbl.StudentID
Use triggers SPARINGLY. For example, my system has 138 tables, 550 stored procedures and only 28 triggers. I wish I had less.
But if you decide a trigger is required, it will look something like this:
CREATE TRIGGER [t_MemberDesignationSideEffect] ON [dbo].MembersDataTable
FOR UPDATE
AS
SET NOCOUNT ON
IF NOT ( UPDATE([MemberDesignation]) ) RETURN
-- REMINDER: All triggers can and will fire for a set of rows...not just one
UPDATE mdtbl
SET MemStatus = '0'
FROM inserted i
JOIN dbo.MembersDataTable mdtbl on i.StudentID = mdtbl.StudentID
JOIN deleted d on d.StudentID = mdtbl.StudentID
WHERE i.memberdesignation = '10'
and d.memberdesignation = '9'
GO
You are writing an update trigger on table. Here you can use deleted and inserted magic tables. In case of update trigger:
Deleted table contains the row as it was before the UPDATE statement.
Inserted table contains the row as it is after the UPDATE statement.
create trigger update_member_status
on membersdatatable
for update
as
begin
declare #old_designation int
declare #new_designation int
set #old_designation = (select memberdesignation from deleted)
set #new_designation = (select memberdesignation from inserted)
if (#old_designation = 9 and #new_designation = 10)
begin
update membersdatatable
set memstatus = '0'
from membersdatatable as mdtbl
inner join inserted as i on i.StudentID = mdtbl.StudentID
end
end
You are going to update member status of all rows with a
memberdesignation = 10
you can probably add conditions to this query in order to update only the ones you want by using a date field or another
Simply call this procedure after updating your table
CREATE PROCEDURE USP_MemberStatusRules()
AS
UPDATE dbo.MembersDataTable
SET MemStatus = '0'
WHERE memberdesignation = 10
AND .....
AND .....
GO

SQL Trigger Using Variables

I need help creating this trigger, any help will be appreciate it, I can't save this script, it's saying 'Invalid column name OfferId'. But I checked all the columns names and they are correct
CREATE TRIGGER dbo.OrderOffer_UpdatedUnits
ON dbo.OrderOffer
FOR UPDATE
AS
BEGIN
DECLARE #OfferId char(5) SET #OfferId = (Select OfferId From INSERTED i, OrderOffer a Where i.OrderOfferid = a.OrderOfferid);
DECLARE #UnitsAvailable int SET #UnitsAvailable = (Select SUM(UnitsAvailable) From dbo.Offer Where OfferId=#OfferId);
UPDATE dbo.OrderOffer SET dbo.UnitsAvailable = #UnitsAvailable
FROM INSERTED i, OrderOffer a
WHERE i.OrderOfferid = a.OrderOfferid
END
Try this:
CREATE TRIGGER dbo.OrderOffer_UpdatedUnits
ON dbo.OrderOffer
FOR UPDATE
AS
BEGIN
UPDATE a
SET dbo.UnitsAvailable =
(
Select SUM(b.UnitsAvailable)
From dbo.Offer b
Where b.OfferId = a.OfferId
)
FROM OrderOffer a
INNER JOIN INSERTED i
ON i.OrderOfferid = a.OrderOfferid
END
NB: I removed the variables since that would assume you only updated one row at a time. Even if the update runs over multiple rows, the above should still work.

Creating an Update Trigger with Where Filter

i'm new at creating triggers. I'm attempting to create a trigger which updates a the tblServiceOrders.GeneralSymptoms with tblAccounts.HotNote where tblAccounts.Number = tblServiceOrders.AccountNumber and where whenever a new line is added to tblServiceOrders. Here is what I've got so far.
ALTER TRIGGER [dbo].[HOTNOTE_update] ON [dbo].[tblServiceOrders]
AFTER INSERT
AS
BEGIN
UPDATE tblServiceOrders tblAccounts.AccountNumber = tblServiceOrders.AccountNumber
SET GeneralSymptoms =
(
SELECT HotNote FROM tblAccounts, tblServiceOrders
WHERE tblAccounts.AccountNumber = tblServiceOrders.AccountNumber
)
FROM tblServiceOrders
WHERE tblServiceOrders.SOType = 'BE Maintenance' OR tblServiceOrders.SOType = 'DD Maintenance'
END
Reading your code, every time you insert a record, you will update the whole table, that is really high cost. I guess you don't really want to do that. If you want to just update the record you just insert, then why not before insert make the data ready and insert directly.
Assuming you're using SQL Server, it looks like your UPDATE statement is trying to perform the following:
UPDATE so
SET so.GeneralSymptoms = a.hotnote
FROM tblServiceOrders so
JOIN tblAccounts a ON so.AccountNumber = a.AccountNumber
WHERE so.SOType = 'BE Maintenance'
OR so.SOType = 'DD Maintenance'
This will update all records in the table with these matching criteria. You might need to consider using just the Inserted record -- depends on your DB Structure.

Executing a trigger; updating another field

I have been reading up on triggers, and I don't seem to be finding an example, that handles my situation. My situation is unfortunate. The previous DBA scattered redundant data throughout our database.
I'd like to update the company name in multiple other tables once the company name has been changed in my organiz table. I have this, but it doesn't seem to work:
CREATE TRIGGER updOrgNameTrigger
ON organiz
AFTER UPDATE
AS
IF UPDATE(Org_Name_1)
BEGIN
DECLARE #org_name varchar(256)
SET #org_name = (select Org_Name_1 from organiz)
UPDATE other_table set Org_Name_1 = #org_name
UPDATE the_other_table set Org_name_1 = #org_name
END
Is what I am trying to do possible?
Your current trigger assumes that an update can only ever affect a single row; it also intends to update every single row in the other two tables with an arbitrary value from the source table (not necessarily the row that was updated!). You need to use the inserted pseudo-table to identify the row(s) that fired the trigger and to pull the new value(s) for the Org_Name_1 column. How about this version:
CREATE TRIGGER dbo.updOrgNameTrigger
ON dbo.organiz
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
UPDATE o SET Org_Name_1 = i.Org_Name_1
FROM dbo.other_table AS o
INNER JOIN inserted AS i
ON o.org_id = i.org_id;
UPDATE o2 SET Org_Name_1 = i.Org_Name_1
FROM dbo.the_other_table AS o2
INNER JOIN inserted AS i
ON o2.org_id = i.org_id;
END
GO