Delete records within Instead Of Delete trigger
I want to have an instead of delete trigger so that I can get text field values out of the table row that's being deleted to preserve those fields when the actual delete occurs. For some reason I can't pull them from the Deleted table in a standard Delete trigger (SQL errors out).
Is there a way to do an actual delete within in an "instead of delete" trigger without making the trigg开发者_如何学编程er refire?
Or a better way of getting text fields once a row is deleted to save into a new record?
This method should do the trick. An instead of trigger will do whatever you specify instead of doing the delete automatically. This means it is key that you do the delete in it manually or the record will not get deleted. It will not run recursively. It can only be done on a table without cascade delete enabled. Basically the trick is you join to the orginal table on the id field in order to get the data from the field you don't have access to in the deleted pseudotable.
create table dbo.mytesting (test_id int, sometext text)
go
create table dbo.myaudit (test_id int, sometext text)
go
insert into dbo.mytesting
values (1, 'test')
go
Create Trigger audit_Table_Deletes on dbo.mytesting INSTEAD OF delete
as
if @@rowcount = 0 return;
Insert into dbo.myaudit (test_id, sometext)
Select d.test_id, t.sometext from deleted d
join dbo.mytesting t on t.test_id = d.test_id
Delete dbo.mytesting where test_id in (select test_id from deleted)
go
delete dbo.mytesting where test_id = 1
select * from dbo.mytesting
select * from dbo.myaudit
Go
drop table dbo.mytesting
drop table dbo.myaudit
If you can change the field to varchar(max) or nvarchar(max) that is the best solution though. Text and ntext are deprecated and should be removed altogether from SQL Server in the next version.
It is probably better to do this with an After Trigger. Less complex.
If you have the following tables
CREATE TABLE [dbo].[Data](
[DocumentID] [smallint] NULL,
[Data] [nvarchar](max) NULL
)
and
CREATE TABLE [dbo].[Audit](
[DocumentID] [smallint] NULL,
[Data] [nvarchar](max) NULL
)
The following After trigger should insert a row into the audit table whenever a row is deleted from the Data Table
Create Trigger audit_Table_Deletes on dbo.Data for delete
as
if @@rowcount = 0 return;
Insert into audit (DocumentID, Data) Select DocumentID, Data from deleted;
Go
None of the answers above worked for me, I am assuming people were using SQL 2008 so this answer works for SQL 2012
CREATE TRIGGER People_LogTriggerDelete ON People
INSTEAD OF DELETE
AS
SET NOCOUNT ON;
INSERT INTO People_AuditLog (Event, Date, Id, Name, LastName, SqlUser)
SELECT 'DELETE', GETDATE(), d.Id, d.Name, d.LastName, CONCAT(SUSER_SNAME(),'/',@@SERVERNAME)
FROM People t INNER JOIN deleted d ON t.Id = d.Id
DELETE People FROM People JOIN deleted ON People.Id = deleted.Id
I once needed to catch records which were being deleted; I wrote a trigger which would copy records into a different table with the same structure as the first one: it went something like this:
create trigger [delta_del] on [customer]
for delete
as
declare <variables> from deleted;
open mycurs
fetch next from mycurs into @v1, @v2
while (@@fetch_status = 0
begin
insert into delta (fields) values (@v1, @v2)
fetch next from mycursor into @v1, @v2
end
close mycursor
deallocate mycursor
etc.
精彩评论