2010-07-16 123 views
4

我想有一個而不是刪除觸發器,以便我可以從正在刪除的錶行中獲取文本字段值,以便在發生實際刪除時保留這些字段。出於某種原因,我無法將它們從標準刪除觸發器中的Deleted表中拉出(SQL錯誤輸出)。刪除記錄而不是刪除觸發器

有沒有辦法做到實際刪除在「而不是刪除」觸發器沒有使觸發器重新啓動?

或者一旦一行被刪除以保存到新記錄中時,獲取文本字段的更好方法是?

+1

如果我不說別人會這樣,那麼這裏就是這樣。 「你可以在sproc中執行此操作嗎?爲什麼要使用觸發器而不是在刪除之前選擇記錄?」 – 2010-07-16 15:27:07

+1

如果您在使用現有代碼時遇到問題,也許您可​​以在此處顯示該代碼。也許有人會發現一個錯誤。 – 2010-07-16 15:29:04

回答

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(最大)或nvarchar(最大),這是最好的解決辦法,但。文本和ntext已被棄用,並應在下一版本中從SQL Server中完全刪除。

-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. 
+1

-1對於觸發器中的CURSOR,不會看到「text」數據類型 – gbn 2010-07-16 16:58:09

+2

@brismith,光標僅作爲最後的手段!你可以用下面的代替你的遊標:'insert into delta(... fields ...)SELECT ... fields from deleted'它爲從select中返回的每一行插入一行。但是,這會對OP提到的棄用的TEXT數據類型產生問題。 – 2010-07-16 17:45:49

+0

感謝您的提示!我以爲我必須遍歷逐個記錄的批記錄,將記錄複製到新表 – brismith 2010-07-19 12:26:59

2

這可能是更好地與AFTER觸發器來做到這一點。不太複雜。

如果你有下列表格

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

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

下扳機後應行插入審覈表每當行從數據表刪除

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 
+1

唯一的問題是無法從刪除的表中插入文本字段。 – Caveatrob 2010-07-16 16:18:37

+0

「不能在'已插入'和'已刪除'表中使用文本,ntext或圖像列。」 – Caveatrob 2010-07-16 16:19:19

+4

你可以將文本數據轉換爲nvarchar(max)嗎?它看起來像文字ntext和圖像數據類型已根據此http://archnet.microsoft.com/en-us/library/bb510662.aspx – etoisarobot 2010-07-16 16:52:59