删除而不是删除触发器中的记录

时间:2010-07-16 15:24:19

标签: sql sql-server triggers delete-row

我想要一个而不是删除触发器,以便我可以从正被删除的表行中获取文本字段值,以便在实际删除时保留这些字段。出于某种原因,我无法在标准的Delete触发器中删除它们(SQL错误)。

有没有办法在“而不是删除”触发器内进行实际删除,而不会触发重启?

或者,删除行以保存到新记录后获取文本字段的更好方法是什么?

4 个答案:

答案 0 :(得分:11)

这种方法应该可以解决问题。而不是触发器将执行您指定的任何操作,而不是自动执行删除操作。这意味着手动删除它或者记录不会被删除是关键。它不会递归运行。它只能在没有启用级联删除的表上完成。基本上,技巧是你加入id字段的原始表,以便从已删除的伪表中无法访问的字段中获取数据。

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

如果您可以将字段更改为varchar(max)或nvarchar(max),那么这是最佳解决方案。不推荐使用Text和ntext,应该在下一版本中从SQL Server中删除它们。

答案 1 :(得分:2)

使用After Trigger执行此操作可能更好。不那么复杂。

如果您有以下表格

CREATE TABLE [dbo].[Data](
[DocumentID] [smallint] NULL,
[Data] [nvarchar](max) NULL
) 

CREATE TABLE [dbo].[Audit](
[DocumentID] [smallint] NULL,
[Data] [nvarchar](max) NULL
) 

以下After触发器应在从数据表中删除行

时向审计表中插入一行
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

答案 2 :(得分:2)

以上答案均不适用于我,我假设人们使用的是SQL 2008,因此此答案适用于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

答案 3 :(得分:-2)

我曾经需要抓住被删除的记录;我写了一个触发器,它将记录复制到一个不同的表中,结构与第一个相同:它是这样的:

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.