SQL Server 2008 R2: trigger after update - sql

This is my first post so please bear with me. Here are the tables I'm working with and I'm only showing the relevant columns:
Movement:
id
cnt_tare_weight
chassis_tare_weight
Stop:
movement_id
order_id
For each movement record, there are 2 or more stop records. The way this works, is that we create an order and create the stops. The stops are grouped into movements.
Here's some example data:
Movement:
id cnt_tare_weight chassis_tare_weight
-------------------------------------------------
1545257 4525.2 3652.2
1545258 null null
Stop:
order_id movement_id
------------------------
0933774 1545257
0933774 1545257
0933774 1545258
0933774 1545258
Here's what I am trying to accomplish:
When the cnt_tare_weight and/or chassis_tare_weight are updated in the movement record, I need to copy this data to all other movement records for that order. I want to use a trigger after update to do this.
Here is what I've come up with but and I'm not sure it will work. I would like to see if what I'm wanting do is correct or if I'm missing something.
Here's my SQL:
CREATE TRIGGER set_tare_weights
ON movement
AFTER UPDATE AS
BEGIN
SET NOCOUNT ON;
DECLARE #movement_id AS INT;
DECLARE #cnt_tare_weight AS DECIMAL(8,1);
DECLARE #chz_tare_weight AS DECIMAL(8,1);
DECLARE #order_id AS int;
SELECT #movement_id = inserted.id
FROM INSERTED
IF update(cnt_tare_weight)
BEGIN
SET #cnt_tare_weight = 'Updated cnt_tare_weight'
END
IF update(chz_tare_weight)
BEGIN
SET #chz_tare_weight = 'Updated chz_tare_weight'
END
SELECT #order_id = order_id
FROM stop
WHERE movement_id = #movement_id
UPDATE movement
SET cnt_tare_weight = #cnt_tare_weight,
chz_tare_weight = #chz_tare_weight
WHERE #movement_id IN (SELECT DISTINCT movement_id
FROM stop
WHERE order_id = #order_id)
AND id <> #movement_id
END
I have never created a SQL Server trigger before. I'm not sure if this will work or if I need to do something more. Do I need to create a trigger that calls a stored procedure? Or will the above work?
Thanks for any help!

Related

Update trigger for update new table from another

I have 2 tables mpayment and account. When someone updates data in mpayment, then the trigger should automatically update the account table with the newly updated data. I wrote this trigger on my mpayment table, but when I try to update some data, I get an error:
The row value update or deleted either do make the row unique or they alter multiplerows [2 rows]
This is my trigger that I am trying to use
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[mpacupdate]
ON [dbo].[mpayment]
AFTER UPDATE
AS
BEGIN
DECLARE #pid AS NCHAR(10)
DECLARE #memid AS NCHAR(10)
DECLARE #pdate AS DATE
DECLARE #pamount AS MONEY
DECLARE #flag AS INT
SELECT #pid = list.pid FROM inserted list;
SELECT #memid = list.memid FROM inserted list;
SELECT #pdate = list.pdate FROM inserted list;
SELECT #pamount = list.pamount FROM inserted list;
SELECT #flag = list.flag FROM inserted list;
BEGIN
UPDATE [dbo].[account]
SET memid = #memid, pdate = #pdate,
pamount = #pamount, flag = #flag
WHERE pid = #pid
END
END
Your trigger is assuming that only 1 row will be updating at a time; it shouldn't. Treat the data as what it is, a dataset (not a set a scalar values).
This maynot fix the problem, as there's no sample data here to test against. I'm also not really sure that what you're after here is the right design choice, however, there's no information on what that is. Generally, you shouldn't be repeating data across tables; if you need data from another table then use a JOIN, don't INSERT or UPDATE both. If they become out of sync you'll start to get some really odd results I imagine.
Anyway, on track, this is probably what you're looking for, however, please consider the comments I've made above:
ALTER TRIGGER [dbo].[mpacupdate] ON [dbo].[mpayment]
AFTER UPDATE
AS BEGIN
UPDATE A
SET memid = i.memid,
pdate = i.pdate,
pamount = i.pamount,
flag = i.flag
FROM dbo.Account A
JOIN inserted i ON A.pid = i.pid;
END

sql table trigger

I need to write a table trigger and I've never done this before. Here's what I'm trying to accomplish. Every time an order is placed with $0, I need the payment type to be set to 100. I run the below query manually, however it would be great if this was processed automatically.
UPDATE tblPay
SET lngPayTypeID = '100'
WHERE (lngFloatID IN (14171)) AND (dateWebDate > '5/25/18 6:00PM')
AND (curTender = '0')
Any help is greatly appreciated.
Generate the trigger SetPayment on table tblPlay:
CREATE TRIGGER [dbo].[SetPayment]
ON [dbo].[tblPlay]
AFTER INSERT
AS
DECLARE
#lngFloatID float,
#curTender decimal
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT
#lngFloatID = lngFloatID,
#curTender = curTender
FROM
inserted
IF (#curTender = 0)
BEGIN
UPDATE
tblPay
SET
lngPayTypeID = '100'
WHERE
lngFloatID = #lngFloatID
END
END
When a record with curTender = 0 is inserted, it will get its lngFloatID and set its lngPayTypeID to 100.

Need to wait on specific column state change in SQL

I need to check for the status change of a certain column in the table
I can do it using while loop, where i can get the column value and check the value and break from the loop if value is changed.
i am using SQL server 2008.
is there a better way?
Here is the sample sql query
declare #status int = 1
select #status = status from MyTable with (nolock) where Id = 100034
while #status <> 3
begin
WAITFOR DELAY '00:01'
select #status = status from MyTable with (nolock) where Id = 100034
end
Have you considered to use a trigger instead of an stored procedure? This is exactly, what are triggers for.
CREATE TRIGGER reactOnStatus3
ON MyTable
AFTER INSERT, UPDATE, DELETE
AS
BEGIN
IF Status = 3
EXEC DoTheMagicStoredProcedure;
END;

Sometimes SQL Server trigger is not firing

I created a trigger on my recharge table. It updates the balance of onaccountregistry table.
But sometimes when inserting rows into my recharge table it is not firing the trigger. Then values are mismatch. This recharge table insert rows every time.
I created the trigger as follows. This is not a replicated table. I'm using SQL Server 2008 Enterprise edition.
Please help me solve this matter
CREATE TRIGGER [dbo].[RechargeRefund]
ON [dbo].[ISRecharge]
FOR INSERT
AS
declare #tin char(9)
declare #depocd char(1)
declare #oldvalue money
declare #newvalue money
begin
select #tin = inserted.tin_subtin from inserted
select #depocd = inserted.updatetype from inserted
select #newvalue = inserted.DepositAmt from inserted
select #oldvalue = Totdeposit from ISOnAcctRegistry where tin_subtin = #tin
end
if #depocd ='1'
begin
update ISOnAcctRegistry
set Totdeposit = #oldvalue + #newvalue
where tin_subtin = #tin
end
if #depocd ='2'
begin
update ISOnAcctRegistry
set Totdeposit = #oldvalue - #newvalue
where tin_subtin = #tin
end
GO
As #marc points out, writing assuming a single row in inserted is bad - it can even be possible for your 3 selects from inserted to assign values to your 3 variables from 3 different (arbitrary) rows from inserted.
What you probably want is:
update i1
set Totdeposit = Totdesposit + t2.Total
from ISOnAcctRegistry i1
inner join
(select
tin_subtin,
SUM(CASE updatetype
WHEN 1 THEN DepositAmt
WHEN 2 THEN -DepositAmt
ELSE 0 END) as Total
from inserted
group by tin_subtin) t2
on
i1.tin_subtin = t2.tin_subtin
But you might be able to replace this work (and this column in ISOnAcctRegistry) with an indexed view built on ISRecharge - with some limitations, you can build a view that automatically performs a SUM across the rows in ISRecharge, and SQL Server would take responsibility for maintaining the value in the background for you.
Obviously, at present, your trigger doesn't account for any UPDATE or DELETE activity on ISRecharge. An indexed view would.
Well, of course it won't work - you're assuming that the trigger fires once per row inserted.
But that's NOT the case.
The trigger fires once per INSERT batch, and the pseudo-table Inserted might contain multiple rows!
If you did get an INSERT with more than one row - which row did your statements here select ?
select #tin = inserted.tin_subtin from inserted
select #depocd = inserted.updatetype from inserted
select #newvalue = inserted.DepositAmt from inserted
select #oldvalue = Totdeposit from ISOnAcctRegistry where tin_subtin = #tin
You need to rewrite your trigger so that it will handle multiple rows in Inserted - then it'll work every time.

How to use trigger for update in SQL Server 2005

I have a table called tbl_gallery which has a column of datatype bit called isActive.
When the user updates the IsActive value, other rows with IsActive = true will be automatically turned to false.
How can do it with updated trigger?
Please help
I think you want something like:
CREATE TRIGGER trgGalleryActive
ON dbo.tbl_gallery
FOR UPDATE
AS
BEGIN
UPDATE g
-- Update all other gallery rows for this same user to false
SET g.IsActive = 0
FROM tbl_gallery g
INNER JOIN inserted i
on g.UserPK = i.UserPK
WHERE
-- However, we don't want current inserted records to be updated
g.TablePK <> i.TablePK
-- As per Marc's comment - don't update existing inactive rows unnecessarily
AND g.IsActive = 1
-- Only if this record is active should any of this happen
AND i.IsActive = 1
END
Trigger for update second table after updated first table :
CREATE TRIGGER update_table_cityUpdated_afterTable_cityUpdate
ON Table_city
AFTER UPDATE AS
BEGIN
DECLARE #cityId AS BIGINT
DECLARE #stateId AS BIGINT
DECLARE #CityName AS NVARCHAR(200)
SELECT #cityId=cityId FROM INSERTED
SELECT #stateId= stateId FROM INSERTED
SELECT #CityName= CityName FROM INSERTED
UPDATE table_cityUpdated
SET
[dbo].[table_cityUpdated].stateId=#stateId,
[dbo].[table_cityUpdated].CityName=#CityName
WHERE [dbo].[table_cityUpdated].cityId=#cityId
END
;