SQL TRIGGER ON UPDATE - sql

Hey guys i am trying to make a trigger to update the feild Bill.BillAmmount everytime a new row is added to Reading
The feild should = (Reading.MeterReading - Reading.LastMeterReading)*Resedent.Rate )
REDEDENT
BILL
READING
are the 3 tables
also thankyou sooo much
AFTER INSERT ON Reading
Begin
UPDATE bill
SET bill.BillAmount = (SELECT (Reading.MeterReading - Reading.LastMeterReading)*Resedent.Rate
FROM Reading, Resedent
WHERE Reading.ReadingID = ReadingID AND Resedent.AccountID = AccountID)
End;
DROP TRIGGER BILLAMOUNT_ON_INSERT; ```

In Oracle, a trigger should be referring to :NEW (or perhaps :OLD). In addition, Oracle doesn't support FROM in UPDATE statements.
I suspect you want something like this:
Begin
UPDATE bill b
SET BillAmount = (SELECT (:new.MeterReading - :new.LastMeterReading) * rs.Rate
FROM Resedent rs
WHERE rs.ReadingID = :new.AccountID
)
WHERE b.AccountId = :new.AccountId
End;
However, without more information about your data model, it is hard to be specific about what you really want to do.

Related

Trigger in SQL causing error "Product_Reorder is not a recognized SET option"

CREATE OR ALTER TRIGGER CheckQuantity
ON dbo.Products
AFTER UPDATE
AS
BEGIN
UPDATE dbo.Products
SET Product_ReOrder = 1
FROM Inserted i
WHERE i.Product_ID = dbo.Products.Product_ID
AND i.Product_QOH < 5;
I am not getting a syntax error
syntax error near ;
This is referring to the ; at the end of the code.
Not 100% sure what you're trying to do - you're not giving us much to go on, either!
I'm assuming you mean you want to set a column called Product_ReOrder in your table to 1 if another column Product_QOH is less than 5 - correct?
In that case - use a trigger something like this:
CREATE OR ALTER TRIGGER CheckQuantity
ON dbo.Products
AFTER UPDATE
AS
BEGIN
UPDATE dbo.Products
SET Product_ReOrder = 1
FROM Inserted i
WHERE i.PrimaryKeyColumn = dbo.Products.PrimaryKeyColumn
AND i.Product_QOH < 5;
END
The trigger will fire after an UPDATE, and Inserted will contain all rows (can and will be multiple rows!) that have been updated - so I'm assuming you want to check the quantity on those rows.
I'm joining the base table (dbo.Products) to the Inserted pseudo table on the primary key column of your table (which we don't know what it is - so you need to adapt this as needed), and I'm setting the Product_ReOrder column to 1, if the Products_QOH value is less than 5.
Your line of code
Select #QOH = (select Product_QOH from inserted)
has a fatal flaw of assuming that only one row was updated - this might be the case sometimes - but you cannot rely on that! Your trigger must be capable of handling multiple rows being updated - because the trigger is called only once, even if 10 rows are updated with a command - and then Inserted will contain all those 10 updated rows. Doing such a select is dangerous - you'll get one arbitrary row, and you'll ignore all the rest of them ....
Is that what you're looking for?
I'm unclear what you were thinking when you wrote this code, or what template you were basing off, but there are many syntax errors.
It seems you probably want something like this:
The update() function only tells us if that column was present in the update statement, not if anything was actually changed.
We need to check if we are being called recursively, in order to bail out.
We also check if no rows have been changed at all, and bail out early
Note how inserted and deleted are compared to see if any rows actually changed. This also deals correctly with multiple rows.
We then need to rejoin Products in order to update it.
create or alter trigger CheckQuantity
on Products
after update
as
set nocount on;
if not(update(Products_QOH))
or TRIGGER_NESTLEVEL(##PROCID, 'AFTER', 'DML') > 1
or not exists (select 1 from inserted)
return; -- early bail-out
update p
set Product_ReOrder = 1
from Products p
join (
select i.YourPrimaryKey, i.Products_QOH
from inserted i
where i.Product_QOH < 5
except
select d.YourPrimaryKey, d.Products_QOH
from deleted d
) i on i.YourPrimaryKey = p.YourPrimaryKey;
However, I don't understand why you are using a trigger at all.
I strongly suggest you use a computed column for this instead:
ALTER TABLE Products
DROP COLUMN Product_ReOrder;
ALTER TABLE Products
ADD Product_ReOrder AS (CASE WHEN Product_QOH < 5 THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END);

Multiple Row Update SQL Trigger from Single Update SQL Statement

Ok. I am quite new to SQL triggers and have had some issues with them. Insert trigger works just fine, and the Delete trigger also. At first, doing a delete on multiple rows would only delete one, but I managed to figure that one out for myself :)
However, even after extensive searching (here and on Google) I am unable to find a satisfactory answer to the UPDATE trigger that I have. If I do an update like
UPDATE Customers Set CustomerUser = 0 Where CustomerStatus = 3
Then unfortunately, only the one record would be updated, and the other would remain as they were. Obviously, this is no good.
The trigger I am using is:
ALTER TRIGGER [dbo].[TRG_TriggerName] ON [dbo].[USER_Customers]
FOR UPDATE
AS
declare #customerid int;
declare #customervenue int;
declare #customeruser int;
declare #customerarea int;
declare #customerevent int;
declare #customerproject int;
declare #customerstatus int;
select #customerid=i.CustomerID from inserted i;
select #customervenue=i.CustomerVenue from inserted i;
select #customerarea=i.CustomerArea from inserted i;
select #customerevent=i.CustomerEvent from inserted i;
select #customerproject=i.CustomerProject from inserted i;
select #customeruser=i.CustomerUser from inserted i;
select #customerstatus=i.CustomerStatus from inserted i;
Update USER_Instances Set InstanceArea = #customerarea, InstanceVenue = #customervenue, InstanceUser = #customeruser, InstanceStatus = #customerstatus, InstanceEvent = #customerevent, InstanceLastUpdate = GetDate() Where InstanceObject = 17 AND InstanceIdentity = #customerid
GO
As you will immediately realize, this trigger is great - if you want to update just one record. Otherwise, it fails. Now - the main question here would be - How do I catch all the records that need updating, and update them all in one trigger action.
The examples I have seen here on Stack Overflow confuse me somewhat, or seem ineffective - for instance, it seems most of them deal with updating just ONE value in a second/other table, and not a whole bunch like I am trying to do. The ones that appear to work on multiple values, I can not understand :(
So after about 2 hours of searches, I give up, and hope that you can help me :) I realize this is a trigger-newbie issue, and though I know my MS-SQL, triggers are something I have never used, until now. So any help is greatly welcome :)
W
It seems that you need something like this
ALTER TRIGGER [dbo].[TRG_TriggerName] ON [dbo].[USER_Customers]
FOR UPDATE
AS
UPDATE USER_Instances
SET InstanceArea = i.CustomerArea,
InstanceVenue = i.CustomerVenue,
InstanceUser = i.CustomerUser,
InstanceStatus = i.CustomerStatus,
InstanceEvent = i.CustomerEvent,
InstanceLastUpdate = GetDate()
FROM USER_Instances JOIN inserted i
ON InstanceIdentity = i.CustomerID AND InstanceObject = 17
Since inserted virtual table can contain multiple rows you need to JOIN it to correctly do your UPDATE.

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.

How to refer to "New", "Old" row for Triggers in SQL server?

SO I'm new to SQL server from SQLite and I am used to using the New|Old keywords. I have seen that some people use the inserted value refer to a newly created row, but this would only apply on an insert and not an update. Howe can I get something like the New I use in this query?
create trigger ports_country_id_in_check
on [SISTEMA].Puerto
after insert, update
AS
BEGIN
update [SISTEMA].Puerto
set country_id = (select secuencia from [SISTEMA].Pais where codigo = New.pais_asociado)
where [SISTEMA].Puerto.secuencia = New.secuencia
end
Inserted also will also apply to update. One updated row will be seen as a deleted and an inserted row. So you can check both what was and what it is now.
create trigger ports_country_id_in_check
on [SISTEMA].Puerto
after insert, update
AS
BEGIN
Declare #pais_asociado, #secuencia int
select #pais_asociado = Puerto.pais_asociado, #secuencia = Puerto.secuencia
from Puerto join inserted
where Puerto.secuencia = inserted.secuencia
update [SISTEMA].Puerto
set country_id = (select secuencia from [SISTEMA].Pais where codigo = #pais_asociado)
where [SISTEMA].Puerto.secuencia = #secuencia
end

SQl trigger after insert issue

I am working on triggers using SQL server 2005. I have a trigger for a table which is after update. After declaring the variables, the code is like this.
if #isconfirmed_before = 0 and #isconfirmed_after = 1
begin
if #invite_userid <> ''
begin
select #points = points from dbo.InvitePoint where code = 'USR' and packageid = #packageid
INSERT INTO InviteCount
([userID]
,[joinMerchantID]
,[packageID]
,[points]
,[joinDate])
VALUES
(#invite_userid
,#merchantid
,#packageid
,#points
,getdate())
end
SET #alpha_numeric=''
SELECT #alpha_numeric=#alpha_numeric+CHAR(n) FROM
(
SELECT TOP 8 number AS n FROM master..spt_values
WHERE TYPE='p' and (number between 48 and 57 or number between 65 and 90)
ORDER BY NEWID()
) AS t
update merchant
set reg_code = #alpha_numeric
where merchantid = #merchantid
END
The last part of
update merchant
set reg_code = #alpha_numeric
where merchantid = #merchantid
This reg_code shoule be inserted only once when the row is inserted but it is changing every time there is an update to the table. How do i make it happen. Please help me, Thank you in advance!!
update merchant
set reg_code = #alpha_numeric
where merchantid = #merchantid
That code is executing every time there is an update, because you have no conditional flow preventing it from executing sometimes. If you want to only execute that given a certain condition, you'll need to wrap it in an IF block.
You say: "This reg_code shoule be inserted only once when the row is inserted but it is changing every time there is an update to the table." Why is that in an AFTER UPDATE trigger then? It looks like it should be in an AFTER INSERT trigger. Unless I am misunderstanding you.
OK you are very much in trouble with triggers. First you need to show the actual create trigger code. I suspect you don't have it set correctly to only fire on insert.
Next you need to assume that the trigger must be able to handle multiple record inserts. Anytime you are setting a value to a scalar variable in a trigger, you are probably doing something wrong. This can't be your whole trigger either because you haven't shown how you get the varible values.