Comment résoudre ce problème de procédure stockée

sql sqlbulkcopy sql-server

Question

J'ai 2 tables. Ce qui suit n'est qu'une version simplifiée de ces tables.

TableA
Id <pk> incrementing
Name varchar(50)

TableB
TableAId <pk> non incrementing
Name varchar(50)

Maintenant, ces tables ont une relation entre elles.

Scénario

L'utilisateur 1 vient sur mon site et effectue certaines actions (dans ce cas, ajoute des lignes au tableau A). Donc, j'utilise un SqlBulkCopy toutes ces données dans le tableau A.

Cependant, je dois également ajouter les données à la table B, mais je ne connais pas les identifiants nouvellement créés à partir de la table A, car SQLBulkCopy ne les retournera pas.

Je pense donc à une procédure stockée qui trouve tous les identifiants qui n'existent pas dans le tableau B, puis les insère dans.

INSERT INTO TableB (TableAId , Name)
SELECT Id,Name FROM TableA as tableA
WHERE not exists( ...)

Cependant, cela vient avec un problème. Un utilisateur peut à tout moment supprimer quelque chose de TableB. Ainsi, si un utilisateur supprime une ligne, un autre utilisateur ou même le même utilisateur revient et fait quelque chose au tableau A ma procédure stockée ramènera cette ligne supprimée au tableau B. Puisqu'il existera toujours dans la table A mais pas la table B et satisfera ainsi la condition de procédure stockée.

Existe-t-il donc une meilleure façon de traiter deux tables qui doivent être mises à jour lors de l'utilisation d'un insert en bloc?

Réponse acceptée

SQLBulkCopy complique cela alors je considérerais d'utiliser une table de transfert et une clause OUTPUT

Exemple, dans un mélange de pseudo-code client et de SQL

create SQLConnection

Create #temptable
Bulkcopy to #temptable

Call proc on same SQLConnection

proc:
   INSERT tableA (..)
   OUTPUT INSERTED.key, .. INTO TableB
   SELECT .. FROM #temptable

close connection

Remarques:

  • tentant sera local à la connexion et être isolé

  • les écritures à A et B seront atomiques
  • le chevauchement ou les écritures ultérieures ne se soucient pas de ce qui se passera plus tard pour A et B
  • soulignant le dernier point, A et B ne seront jamais peuplés à partir de l'ensemble de lignes dans #temptable

Alternative:

Ajoutez une autre colonne à A et B appelée sessionid et utilisez-la pour identifier les lots de lignes.


Réponse populaire

Une solution alternative consiste à utiliser des déclencheurs de base de données pour mettre à jour le second tableau.



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