Come risolvere questo problema di stored procedure

sql sqlbulkcopy sql-server

Domanda

Ho 2 tavoli. Le seguenti sono solo una versione ridotta di questi tavoli.

TableA
Id <pk> incrementing
Name varchar(50)

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

Ora queste tabelle hanno una relazione l'una con l'altra.

Scenario

L'utente 1 viene sul mio sito e fa alcune azioni (in questo caso aggiunge righe alla tabella A). Quindi uso uno SqlBulkCopy tutti questi dati nella Tabella A.

Tuttavia, ho bisogno di aggiungere i dati anche alla tabella B, ma non conosco gli ID appena creati dalla tabella A, in quanto SQLBulkCopy non li restituirà.

Quindi sto pensando di avere una stored procedure che trova tutti gli id ​​che non esistono nella tabella B e quindi li inserisco.

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

Tuttavia questo ha un problema. Un utente in qualsiasi momento può cancellare qualcosa da TableB, quindi se un utente cancella dire una riga e poi arriva un altro utente o anche lo stesso utente si avvicina e fa qualcosa alla Tabella A, la mia stored procedure riporterà quella riga cancellata nella Tabella B. Dal momento che continuerà a esistere nella Tabella A ma non nella Tabella B e quindi soddisferà la condizione della stored procedure.

Quindi c'è un modo migliore per gestire due tabelle che devono essere aggiornate quando si utilizza l'inserimento di massa?

Risposta accettata

SQLBulkCopy complica questo, quindi vorrei prendere in considerazione l'utilizzo di una tabella di staging e una clausola OUTPUT

Esempio, in una combinazione di pseudo codice cliente e 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

Gli appunti:

  • Tentativo sarà locale per la connessione ed essere isolato

  • le scritture su A e B saranno atomiche
  • le scritture sovrapposte o successive non si preoccupano di ciò che accade più tardi in A e B
  • enfatizzando l'ultimo punto, A e B verranno sempre popolati solo dal set di righe in #temptable

Alternativa:

Aggiungi un'altra colonna ad A e B chiamata sessionid e usala per identificare i lotti di righe.


Risposta popolare

Proprio come una soluzione alternativa è possibile utilizzare i trigger del database per aggiornare la seconda tabella.



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché