我想要一个而不是删除触发器,以便我可以从要删除的表行中获取文本字段值,以便在实际删除发生时保留这些字段。出于某种原因,我无法将它们从标准删除触发器中的已删除表中拉出(SQL 错误输出)。
有没有办法在“而不是删除”触发器中进行实际删除而不使触发器重新触发?
或者在删除一行以保存到新记录后获取文本字段的更好方法?
我想要一个而不是删除触发器,以便我可以从要删除的表行中获取文本字段值,以便在实际删除发生时保留这些字段。出于某种原因,我无法将它们从标准删除触发器中的已删除表中拉出(SQL 错误输出)。
有没有办法在“而不是删除”触发器中进行实际删除而不使触发器重新触发?
或者在删除一行以保存到新记录后获取文本字段的更好方法?
这种方法应该可以解决问题。而不是触发器将执行您指定的任何操作,而不是自动执行删除。这意味着您手动删除它是关键,否则记录将不会被删除。它不会递归运行。它只能在没有启用级联删除的表上完成。基本上,诀窍是您加入 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 中完全删除。
使用 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
上面的答案都不适合我,我假设人们使用的是 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
我曾经需要捕获正在被删除的记录;我写了一个触发器,它将记录复制到与第一个结构相同的不同表中:它是这样的:
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.