T-SQL trigger after deleting - sql

A need a trigger to run after a row is deleted from a table.
This trigger should delete rows from another table where a field on that table has a value matching the value of one of the columns of the deleted row from the other table.

If triggering the delete from a delete:
create trigger trg_mainTable
on dbo.mainTable
after delete
as
begin
delete
from dbo.relatedTable
where someColumn in
(
select someColumn
from deleted
)
end
go
If triggering the delete from an update:
create trigger trg_mainTable
on dbo.mainTable
after update
as
begin
if update(someColumn)
begin
delete
from dbo.relatedTable
where someColumn in
(
select someColumn
from deleted
)
end
end
go

Related

SQL Trigger prevent delete on single row

I have a table where there is a row of data that I don't want anyone to deleted it. The Table name is ProjectInProcessData. I want to make sure the data with ID 6050 can not delete. How can I do that?
Create Trigger [dbo].[triggerPreventDeleteFormula]
ON [dbo].[AHSC_Project_InprocessData]
INSTEAD OF DELETE
AS
BEGIN
IF EXISTS(
SELECT *
FROM deleted d
where d.AHSC_Project_InprocessData_ID = '6610' or d.AHSC_Project_InprocessData_ID = '6666'
)
BEGIN
ROLLBACK;
RAISERROR('Can not delete this record: this record contains default formula',16,1);
END
ELSE
BEGIN
DELETE [AHSC_Project_InprocessData]
WHERE EXISTS (Select * from deleted d where d.AHSC_Project_InprocessData_ID = [AHSC_Project_InprocessData].AHSC_Project_InprocessData_ID)
END
END
use where condition in times of delete
delete from ProjectInProcessData where id!=6050

Ms sql Trigger - Can Delete Trigger Affect Also Deleted Row Trigger

I Have Table Name Called Widgets And There is Delete Trigger On it. When i Delete one specific Row I want Delete Also Other Rows Which Has Relotionship
Trigger Like
ALTER TRIGGER [dbo].[Trigger_sys_widgets_Delete]
ON [dbo].[sys_widgets]
AFTER DELETE
AS
BEGIN
Delete From sys_Widgets Where parent in (Select id From deleted);
END
But This doesn't delete other Rows Just First Row Deleted !
Can i make This Trigger Works on Depete loop till Nothing Left in relative Childs
Also Try To Cascade Delete Like
Alter Table sys_widgets Add Constraint FK_sys_widgets foreign Key (parent) References sys_widgets(id) On Delete Cascade;
Is This Possible To Do That For Same Table
You may use recursive CTE to delete all children by one trigger run.
ALTER TRIGGER [dbo].[Trigger_sys_widgets_Delete]
ON [dbo].[sys_widgets]
AFTER DELETE
AS
BEGIN
WITH ForDelete AS
(
SELECT widgets.id
FROM [dbo].[sys_widgets] AS widgets
INNER JOIN deleted ON widgets.parent = deleted.id
UNION ALL
SELECT widgets.id
FROM [dbo].[sys_widgets] AS widgets
INNER JOIN ForDelete ON widgets.parent = ForDelete.id
)
DELETE FROM [dbo].[sys_widgets]
WHERE id in (SELECT id FROM ForDelete);
END

Delete after Insert trigger

I'm trying to create after insert trigger to delete a row from table whenever I insert the same row in the opposite table using the ID
But it doesn't work
Create Trigger [dbo].[MeritedDeceased] On [dbo].[Deceased]
After Insert
As
Begin
Delete From dbo.Merited Where dbo.Deceased.ID = dbo.Merited.ID
End
I think you mean to do something like this (maybe)...
CREATE TRIGGER [dbo].[MeritedDeceased] ON [dbo].[Deceased]
AFTER INSERT
AS
BEGIN
DELETE M
FROM [dbo].[MeritedDeceased] M
INNER JOIN Inserted I
ON I.ID = M.ID
;
END
;
Translation: Every time a row is inserted into dbo.Deceased, delete any rows with the same (inserted) ID from dbo.MeritedDeceased.
FYI, this TRIGGER won't just delete one row, but also a batch of rows that were inserted together. If that's what you want, then this should help.

Sql Server Triggers. How does the trigger checks for Update Command?

I have a trigger for auditing purchase and sales table. The trigger is on INSERT and DELETE. To check if its "Insert", the condition is
IF (SELECT COUNT(*) FROM INSERTED) > 0
BEGIN
END
How do I check if its an Update command inside the Trigger?
Arun
The "tables" that are in play in an update trigger are still called inserted and deleted, and the old values of the rows are in the deleted table, and the new values are in the inserted table.
You can use logic along these lines to detect whether you are in a insert, update or a delete:
CREATE TRIGGER MyTrigger
ON MyTable
AFTER INSERT,DELETE,UPDATE -- you need to add the "update" here,
-- in order to catch updates as well
AS
BEGIN
Declare #insertedCount int
Declare #deletedCount int
select #insertedCount = COUNT(*) from inserted
select #deletedCount = COUNT(*) from deleted
if (#insertedCount != 0) -- we have some new values
if (#deletedCount = 0) -- do we have old values?
print 'Inserting'
else
print 'Updating'
else
print 'Deleting'
END
An INSERT,DELETE trigger will not fire for updates.
.........................
CREATE an INSERT, UPDATE, DELETE all in one table
IF ##ROWCOUNT = 0
BEGIN
RETURN;
END;
IF EXISTS(SELECT * FROM inserted)
BEGIN
IF EXISTS(SELECT * FROM deleted)
BEGIN
-- for UPDATE
END
ELSE
BEGIN
-- for INSERT
END
END
ELSE
BEGIN
-- for DELETE
END;
Once you've updated your trigger (as Mitch says) to also apply to UPDATEs, you need to check for updates first:
IF EXISTS(select * from inserted) and EXISTS(select * from deleted)
BEGIN
--Update
END
Note that I've switch to EXISTS rather than COUNT(*). Exists more properly describes what we want to establish - that rows exist in the table. We don't care how many rows are in there.
I would like to thank "SWeko" for the clue.
Now, this what I did and the Trigger worked.
CREATE TRIGGER dbo.Sample
ON TableName
FOR INSERT, UPDATE, DELETE
AS
IF (SELECT COUNT(*) FROM INSERTED) > 0
BEGIN
IF (SELECT COUNT(*) FROM DELETED) > 0
BEGIN
-- UPDATE (TABLE).
END
ELSE
BEGIN
-- INSERT (TABLE).
END
END
ELSE
-- DELETE (TABLE).
BEGIN
END

Trigger to update another field in same table

I want to run a trigger when I update a certain field on the database, so it updates another field (basically we have 2 different unique IDs for each record, so when one is changed, we need to update the other too - yay!)
CREATE OR REPLACE TRIGGER trigger_name ON table AFTER
UPDATE AS
UPDATE table A
SET unique_to_update = NVL(
(SELECT b.unique_to_update_from
FROM table b
WHERE B.other_unique_id = A.unique_id_to_match
), 0);
I have no idea if this works (scared to test it, quite frankly, since I'm certain it'll break things) and even if it did, it'd run on every single update of that table - not just the one field that I wanted.
Any help would be much appreciated, thank you!
Test anything before putting it in production.
Something like this shoud be your trigger:
CREATE OR REPLACE TRIGGER trigger_name
BEFORE UPDATE of unique_id_to_match
ON table
FOR EACH ROW
AS
BEGIN
select
NVL(
(SELECT b.unique_to_update_from
FROM table b
WHERE B.other_unique_id = :new.unique_id_to_match
), 0)
into :new.unique_to_update
FROM dual;
END;
5000 rows x 900 columns is not so big :)
I was afraid it has 10M of rows :)
OK start
create temporary table tmp_my_important_columns on commit delete rows
as
select unique_id_to_match, unique_to_update_from,
other_unique_id , unique_to_update
from table where rownum < 1;
second
CREATE OR REPLACE TRIGGER trigger_before_upd_stmt
BEFORE UPDATE
ON table
AS
BEGIN
insert into
tmp_my_important_columns
select unique_id_to_match, unique_to_update_from,
other_unique_id , unique_to_update
from table;
END;
third,
CREATE OR REPLACE TRIGGER trigger_name
BEFORE UPDATE of unique_id_to_match
ON table
FOR EACH ROW
AS
BEGIN
select
NVL(
(SELECT b.unique_to_update_from
FROM tmp_my_important_columns b
WHERE B.other_unique_id = :new.unique_id_to_match
), 0)
into :new.unique_to_update
FROM dual;
END;
Comments:
After an update, if you update the same rows again, without commit
(which deletes the tmp table), you'll get problems. So, or you commit
after update, or you can add an after update trigger(without for each row) that deletes all, from tmp table, but this is somehow ugly.
You can add indexes on the temporary table.