Domanda sull'inserimento / aggiornamento dei file con SQL Server (ASP.NET MVC)
-
27-09-2019 - |
Domanda
Ho un grande tavolo con un sacco di righe, ogni riga ha statistiche per ogni utente per alcuni giorni. E ovviamente non ho alcun statistiche per il futuro. Quindi, per aggiornare le statistiche che uso
UPDATE Stats SET Visits=@val WHERE ... a lot of conditions ... AND Date=@Today
Ma cosa succede se la riga non esiste? Dovrei usare
INSERT INTO Stats (...) VALUES (Visits=@val, ..., Date=@Today)
Come è possibile verificare se la riga esiste o no? C'è un modo diverso dal fare il COUNT (*)?
Se riempio il tavolo con le celle vuote, ci vorrebbe centinaia di migliaia di righe di prendere megabyte e la memorizzazione di dati.
Soluzione
Se si utilizza SQL Server 2008 e fino, si dovrebbe anche indagare la dichiarazione MERGE
introdotta nella versione del 2008.
Altri suggerimenti
vorrei provare un UPDATE, quindi se @@ ROWCOUNT = 0 provare un INSERT
UPDATE Stats SET Visits=@val WHERE ... a lot of conditions ... AND Date=@Today
IF @@ROWCOUNT = 0
INSERT INTO Stats (...) VALUES (Visits=@val, ..., Date=@Today)
Oppure provate un INSERT all'interno di un try / catch e poi UPDATE se fallisce.
Non vorrei provare prima
Quello che tendo a fare in quei casi è solo eseguire la seguente (pseudo-codice siccome io sono un uomo di DB2 me):
try:
INSERT
catch already-exists:
try:
UPDATE
catch anything:
generate error
Si può farlo in ordine inverso Se siete più probabilità di avere le righe che non:
try:
UPDATE
catch not-there:
try:
INSERT
catch anything:
generate error
non di prova prima in un DBMS dal momento che il database può cambiare sotto di voi tra la prova e l'esecuzione (il principio "meglio chiedere perdono che chiedere il permesso").
Purtroppo SQL Server non ha alcun tipo di comando "inserire o aggiornare" (che io sappia), come alcuni motori DB. Ciò significa che si ha per controllare la fila prima o prendere l'errore come altre risposte suggeriscono. Speriamo che la riga ha una chiave primaria artificiale, così quello che si poteva è prima query per quella chiave utilizzando tutte le condizioni WHERE e poi, se una riga viene restituita fare un UPDATE ... WHERE key = ...
, altrimenti fare un inserto. In questo modo non sta eseguendo l'intera query due volte.