Empêcher SqlBulkCopy de restaurer une transaction en cas d'échec d'une insertion

sqlbulkcopy sql-server

Question

J'utilise SqlBulkCopy pour insérer des lots d'enregistrements sur un serveur. Si un enregistrement échoue à cause d'une contrainte unique, je ne souhaite pas annuler le lot complet, mais je souhaite plutôt mettre à jour l'enregistrement existant.

J'espérais pouvoir consigner les valeurs clés des enregistrements défaillants, puis une fois l'insertion en bloc terminée, revenir en arrière et les traiter individuellement.

Cependant, je ne vois aucun moyen de dire à SqlBulkCopy de ne pas annuler la transaction en cas d'échec, ni d'obtenir des informations sur l'enregistrement défaillant.

Je pourrais vérifier que l’enregistrement existe avant de l’ajouter au DataTable SqlBulkCopy, mais cela entraînerait une surcharge considérable.

J'ai vérifié les réponses ici qui indiquent l'utilisation d'une table intermédiaire et d'un autre sproc pour effectuer l'insertion / la mise à jour après l'insertion en bloc, mais je pense que sproc devrait traiter chaque enregistrement individuellement pour insérer un nouvel enregistrement ou mettre à jour les enregistrements existants - très long.

Avez-vous d'autres conseils ou rien n'a-t-il changé au cours des 4 dernières années?

Réponse acceptée

Je ne recommanderais pas d'utiliser la déclaration de fusion. Il y a des problèmes dans la section Utilisation prudente de l'instruction MERGE de SQL Server , et personnellement, à mon humble avis, je trouve difficile à suivre et offre peu, voire pas du tout, une simple instruction de mise à jour par insertion (sucre syntaxique pas si doux).

INSERT INTO A
SELECT *
FROM   #B B
       LEFT OUTER JOIN A
               ON A.ID  = B.ID
WHERE  A.ID IS NULL

ou

UPDATE A
SET    BLAH = 'BLAH'    
FROM   A
       INNER JOIN #B B
               ON B.ID  = A.ID

Si vous utilisez un outil plutôt que SQL pur, vous voudrez peut-être examiner SSIS, qui peut gérer ce que vous recherchez.


Réponse populaire

N'utilisez pas SqlBulkCopy.

Directement.

Insérer dans une table temporaire (évite également le comportement de verrouillage horrible de SqlBulkCopy) puis FUSIONNER dans la table finale avec les règles appropriées.

C'est simple, c'est comme ça que je fais toutes mes mises à jour en masse.



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi