6

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

有没有办法在“而不是删除”触发器中进行实际删除而不使触发器重新触发?

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

4

4 回答 4

13

这种方法应该可以解决问题。而不是触发器将执行您指定的任何操作,而不是自动执行删除。这意味着您手动删除它是关键,否则记录将不会被删除。它不会递归运行。它只能在没有启用级联删除的表上完成。基本上,诀窍是您加入 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 中完全删除。

于 2010-07-16T18:14:53.637 回答
3

使用 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
于 2010-07-16T15:58:54.977 回答
3

上面的答案都不适合我,我假设人们使用的是 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
于 2018-11-23T00:33:06.927 回答
-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.
于 2010-07-16T15:37:45.230 回答