I have a delete trigger on a table in my DB that is supposed to be inserting rows into an "audit" table, but when I delete rows from the trigger table, they do not show up in the audit table. I have insert and update triggers following this same format that work fine but I can't seem to get this one to work. Here is the trigger:
USE [OutageDev]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[tr_audOutageSummaryDelete]
ON [dbo].[Outage Summary]
AFTER DELETE
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
INSERT INTO dbo.[Outage Summary Audit]
(OutageSummaryID,
Dispatcher,
/*Removed columns for brevity*/
StateEmergency,
Comment,
AuditDateTime,
AuditUser,
AuditAction)
SELECT d.OutageSummaryID,
d.Dispatcher,
/*Removed columns for brevity*/
d.StateEmergency,
t.Comment,
GETDATE(),
SUSER_SNAME(),
'DELETE'
FROM deleted d
JOIN [Outage Summary] t
ON d.OutageSummaryID = t.OutageSummaryID
END
For future reference, I was joining the deleted table with the trigger table in order to select columns that were of type ntext because this was how it worked for my insert and update triggers. Since this is an after delete trigger, the row I was trying to select was already deleted. I converted columns from ntext to nvarchar(max) and got rid of the join and it works fine now.
Related
Using trigger, when I run update query on query browser for one
table, then I would like this to also update another table that contains the same field.
CREATE DEFINER=`root`#`localhost` TRIGGER `abcd`.`library_AFTER_UPDATE`
AFTER UPDATE ON `library` FOR EACH ROW
begin
-- here i want that same query with same value
-- that i have run on the query browser.
end
What code belongs where I have the comment above?
Use the values from the UPDATE query like below
CREATE DEFINER=`root`#`localhost` TRIGGER `abcd`.`library_AFTER_UPDATE`
AFTER UPDATE ON `library` FOR EACH ROW
begin
UPDATE another_table SET same_field = NEW.same_field
WHERE some_filter_condition;
end
Total novice at triggers... all the docs don't bother with beginner stuff.
I just want to update the row(s) that has/have been updated. My trigger below updates the entire table. The trigger below just tests two columns for changes.
How do I restrict this update trigger to the update only the updated rows and not the entire table?
ALTER TRIGGER [dbo].[geog_update] ON [dbo].[Site]
FOR UPDATE
AS
SET NOCOUNT ON
IF (UPDATE(Latitude) OR UPDATE(Longitude))
BEGIN
UPDATE Site
SET geog = geography::Point([Latitude], [Longitude], 4326)
WHERE Latitude is not null and Longitude is not null
END
Can I use the same trigger for inserted rows by just using FOR UPDATE, INSERT? Probably not since the IF checks for UPDATE() on a column, unless INSERT implies UPDATE.
Ok first, you never under any circumstances design a trigger to update only one row in SQL Server. You design it to update the rows that were inserted, deleted or updated. Triggers operate on batches and you cannot assume that you will never change more than one record in code that hits the database.
You do that by joining to one of two pseudotables that are available only in triggers, inserted or deleted. Inserted contains the new records or the values after an update, delted contains the values for the records deleted or the values before an update occurred.
You could try something like:
ALTER TRIGGER [dbo].[geog_update] ON [dbo].[Site]
FOR UPDATE
AS
SET NOCOUNT ON
UPDATE S
SET geog = geography::Point(i.[Latitude], i.[Longitude], 4326)
FROM Site s
JOIN Inserted I on s.id = i.id
WHERE Latitude is not null and Longitude is not null
Here is the final UPDATE trigger. I made an INSERT trigger that is almost identical.
CREATE TRIGGER [dbo].[geog_update] ON [dbo].[Site]
FOR UPDATE
AS
SET NOCOUNT ON
IF (UPDATE(Latitude) OR UPDATE(Longitude))
BEGIN
UPDATE t1
SET t1.geog = geography::Point(t1.Latitude, t1.Longitude, 4326)
FROM Site AS t1 INNER JOIN Inserted AS t2 ON t1.Site_ID = t2.Site_ID
WHERE (t1.Latitude IS NOT NULL)
AND (t1.Longitude IS NOT NULL)
AND (t1.Record_Archive_Date IS NULL)
END
So i see that SQL has some tables which hold the newly inserted and deleted data from tables one may refer. I didn't notice such a table for updated data. I am currently working with triggers and i need to apply a trigger to an update. How do i do that?
USE [examene]
GO
/****** Object: Trigger [dbo].[trig1] Script Date: 6/8/2013 6:48:26 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER trigger [dbo].[trig1] on [dbo].[participari]
after insert,update,delete
as
begin
if (exists (select * from deleted))
rollback
if (exists (select * from inserted,proiecte
where inserted.idpr = proiecte.idpr
and deadline<dela union
select * from inserted,proiecte
where inserted.idpr = proiecte.idpr and inserted.panala>proiecte.deadline))
rollback
end
this is my trigger so far
There is no such thing as updated virtual table. When update occurs old values might be found in deleted and new values in inserted
Use the inserted and deleted Tables
The deleted table stores copies of the affected rows during DELETE and
UPDATE statements. During the execution of a DELETE or UPDATE
statement, rows are deleted from the trigger table and transferred to
the deleted table.
The deleted table and the trigger table ordinarily
have no rows in common. The inserted table stores copies of the
affected rows during INSERT and UPDATE statements. During an insert or
update transaction, new rows are added to both the inserted table and
the trigger table. The rows in the inserted table are copies of the
new rows in the trigger table.
An update transaction is similar to a delete operation followed by an
insert operation; the old rows are copied to the deleted table first,
and then the new rows are copied to the trigger table and to the
inserted table.
I am currently in the process of writing my first trigger in MySQL within PHPmyadmin. I would like it so that when an item in one table is updated, a row in another table is inserted. Several columns of the row that is to be inserted in the second table are determined by the values being updated in the first table.
Therefore, I need to INSERT a new row in table B when an update occurs on table A. And some of the values of the columns in table B are to be defined by the values in the updated table A row which caused the trigger to run.
Please find the trigger below.
CREATE TRIGGER `before_categoryiteminstance_update` BEFORE UPDATE ON `TABLEA`
FOR EACH ROW BEGIN
declare f_guidcategoryiteminstance int;
declare f_guidcategory int;
INSERT INTO TABLEB
SET
f_guidcategoryiteminstance =(SELECT guidcategoryiteminstance FROM inserted),
f_guidcategory =(SELECT guidcategory FROM inserted),
guiduser= f_guidcategory,
guidcategoryinstance= f_guidcategoryiteminstance,
number= number +1,
dateofaction= NOW(); END
The trigger can be added to the DB fine. However, when I attempt to update a row on table A (which should cause the trigger to run), I get an error stating that the table Inserted does not exist. However, I was under the impression that Inserted should be a logical table that contains the results of the initial part of the trigger. Is this only the case if the trigger is being run on an insert and not an update? If so, is there an equivalent for an update trigger?
I have the following trigger:
CREATE TRIGGER sum
AFTER INSERT
ON news
FOR EACH ROW
UPDATE news SET NEW.sum = (NEW.int_views + NEW.ext_views)/NEW.pageviews
It sums the int_views and ext_views column of a table and divides them by the total pageviews.
Whenever I try to add a new row to news, I get the following error:
ERROR 1442 (HY000) at line 3: Can't update table 'news' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
The trigger seems pretty simple to me. Is there a reason why the trigger fails to run?
The symptom is, that you are running an UPDATE (for all rows) inside a INSERT trigger - both modify the table, which is not allowed.
That said, if I guess the intention of your trigger correctly, you do not want to update all rows, but only the newly inserted row. You can achieve that easily with
CREATE TRIGGER sum
BEFORE INSERT
ON news
FOR EACH ROW
SET NEW.sum = (NEW.int_views + NEW.ext_views)/NEW.pageviews
Mind that this is a BEFORE INSERT trigger, as you want to change the row before it is written to the table.
If you try to update/insert on the same table that cause trigger to fire do not use the common sql command like
-> UPDATE TABLE_NAME SET COLUMN_NAME = VALUE WHERE CONDITION_LIST;
-> INSERT INTO TABLE_NAME VALUES("VALUE1","VALUE2");
This will not work. Only use set to assign the value of the column you update.
Example:
CREATE TRIGGER trigger_name BEFORE/AFTER INSERT/UPDATE ON table_name
FOR EACH ROW
SET NEW.COLUMN_NAME = "VALUE";
I was in a similar condition where I had to run two triggers:
UPDATE 3 fields on INSERTing a new ROW
UPDATE 3 fields on UPDATEing a ROW
After lot of efforts, I was finally able to write the TRIGGER in following way:
FOR updating values on INSERT
CREATE TRIGGER `INSERT_DISCOUNT_SERVICES` BEFORE INSERT ON `services`
FOR EACH ROW SET
NEW.discount_5_rate = (NEW.ndis_rate*0.05),
NEW.discount_10_rate=(NEW.ndis_rate*0.10),
NEW.discount_15_rate=(NEW.ndis_rate*0.15)
Similarly
FOR updating values on UPDATE
CREATE TRIGGER `UPDATE_DISCOUNTS_SERVICES` BEFORE UPDATE ON `services`
FOR EACH ROW SET
NEW.discount_5_rate = (NEW.ndis_rate*0.05),
NEW.discount_10_rate=(NEW.ndis_rate*0.10),
NEW.discount_15_rate=(NEW.ndis_rate*0.15)