2010-11-08 21 views
1

J'insère beaucoup de données avec un SqlBulkCopy. La source des données peut contenir des lignes dupliquées. J'ai la table de destination J'ai un indice d'unicité.La classe SQL Server .NET SqlBulkCopy reste active après l'exception

Lorsque la première ligne dupliquée apparaît, SqlBulkCopy lève une exception et annule la transaction interne. Je veux qu'il ignore l'exception et continue d'insérer. (UNIQUEMENT si l'exception concerne la ligne dupliquée).

Il y a quelques questions à propos de ce problème, mais ils recherchent tous des lignes dupliquées de rapports, je m'en fous.

+0

OK. Il n'y a donc aucun moyen de conserver SqlBulkCopy sans affecter ses performances. Dois-je fermer la question? – Diego

Répondre

0

Ceci est l'un des compromis avec SqlBulkCopy - Je l'utilise quand je sais que j'ai des données propres. Si vous devez être capable de gérer correctement les erreurs dans des situations comme celle-ci où vous n'avez pas de données propres, alors d'autres approches sont «meilleures» (c'est un compromis pour la performance). Suite à votre autre question, l'approche SqlDataAdapter vous donnerait cette capacité car il existe une propriété ContinueOnError que vous pouvez définir pour permettre au processus de continuer en cas d'erreurs comme celle-ci - très pratique. J'utilise cette approche lorsque je dois gérer des données non-propres/potentiellement problématiques de .NET. Mais comme je l'ai lié précédemment, vous verrez un coût de perf.

Si vous souhaitez obtenir des performances absolues et répondre à vos besoins initiaux en matière de séparation, vous devez dédoubler les données avant de les charger dans la base de données. Ou utilisez une approche comme TomTom suggérée

1

Résolvez le problème avant de procéder à l'insertion en masse. L'insert en vrac est spécifiquement défini pour ne pas manipuler des trucs comme celui-ci. Pour cela, il met SQL Server dans un mode d'insertion en bloc qui est plus rapide ... mais a des limitations. Toutes les violations de clé doivent être manipulées AVANT l'insertion.

Ce que vous voulez faire est d'insérer dans une table de transfert (double autorisé), puis MERGE dans la table principale (en utilisant la commande MERGE).

+0

J'évalue ceci comme posibilité. Mais la raison pour laquelle j'utilise SqlBulkCopy est parce que la quantité de données REALY LARGE me rend NECESAIRE pour minimiser le temps d'insertion. Faire cela va presque le doubler. – Diego

+0

Mais alors vous devez travailler dans les limites de la copie en bloc. Chargez les données dans une table de transfert temporaire, comme presque toutes les solutions ETL. Frottez-le, puis fusionnez-le dans les tables de fin. – TomTom