2010-07-16 8 views
4

Je souhaite avoir un déclencheur au lieu de supprimer afin que je puisse extraire les valeurs de champ de texte de la ligne du tableau en cours de suppression pour conserver ces champs lorsque la suppression réelle se produit. Pour une raison quelconque, je ne peux pas les extraire du tableau Supprimé dans un déclencheur standard Supprimer (erreurs SQL hors).Supprimer les enregistrements dans le déclencheur Au lieu de supprimer

Existe-t-il un moyen d'effectuer une suppression réelle dans un déclencheur "au lieu de supprimer" sans que le déclencheur ne se répète?

Ou une meilleure façon d'obtenir des champs de texte une fois qu'une ligne est supprimée pour enregistrer dans un nouvel enregistrement?

+1

Si je ne le dis pas à quelqu'un d'autre, alors voilà. "Pouvez-vous faire cela dans un sproc? Pourquoi voulez-vous utiliser un déclencheur au lieu de sélectionner l'enregistrement avant la suppression?" –

+1

Si vous rencontrez des problèmes avec le code existant, vous pourriez peut-être afficher ce code ici. Peut-être que quelqu'un détectera une erreur. –

Répondre

11

Cette méthode devrait faire l'affaire. Au lieu de trigger, vous ferez ce que vous spécifiez au lieu de faire la suppression automatiquement. Cela signifie qu'il est important que vous le supprimiez manuellement ou que l'enregistrement ne soit pas supprimé. Il ne fonctionnera pas récursivement. Cela ne peut se faire que sur une table sans suppression en cascade activée. Fondamentalement, l'astuce consiste à vous joindre à la table orginal sur le champ id afin d'obtenir les données du champ auquel vous n'avez pas accès dans le pseudotable supprimé.

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 

Si vous pouvez modifier le champ varchar (max) ou nvarchar (max) qui est la meilleure solution si. Texte et ntext sont obsolètes et doivent être supprimés complètement de SQL Server dans la prochaine version.

-2

J'ai déjà eu besoin d'attraper des enregistrements qui étaient en cours de suppression; J'ai écrit un déclencheur qui copie des enregistrements dans une autre table avec la même structure que le premier: il a quelque chose comme ceci:

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 pour CURSEUR dans un déclencheur, ne voyant pas le type de données "texte" – gbn

+2

@brismith, curseur uniquement en dernier recours! vous pouvez remplacer votre curseur par: 'insert into delta (... champs ...) SELECT ... fields ... from deleted' Il insère une ligne pour chaque ligne renvoyée par select. Cependant, cela posera un problème avec le type de données TEXTE obsolète mentionné par l'OP. –

+0

Merci pour le conseil! Je pensais que je devais itérer à travers le dossier record-by-record, en copiant l'enregistrement à la nouvelle table – brismith

2

Il est sans doute préférable de le faire avec un déclencheur AFTER. Moins complexe.

Si vous avez les tableaux suivants

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

et

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

, après déclenchement doit insérer une ligne dans la table de vérification chaque fois qu'une ligne est supprimée de la table des données

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

Le seul problème est que les champs de texte ne peuvent pas être insérés à partir de la table supprimée. – Caveatrob

+0

"Impossible d'utiliser des colonnes text, ntext ou image dans les tables 'inserted' et 'deleted'." – Caveatrob

+4

Pouvez-vous convertir les données de texte en nvarchar (max)? Il semble que les types de données text ntext et image sont obsolètes selon ce http://technet.microsoft.com/en-us/library/bb510662.aspx – etoisarobot

Questions connexes