2012-06-13 15 views
27

Ho una tabella in cui sto inserendo righe per dipendente ma la prossima volta quando voglio inserire riga non voglio inserire nuovamente i dati per quel dipendente voglio solo aggiorna con le colonne richieste se esce lì, se no, quindi crea una nuova rigaCome eseguire l'upster (aggiornamento o inserimento) in SQL Server 2005

Come possiamo farlo in SQL Server 2005?

Sto usando jsp

la mia domanda è

String sql="insert into table1(id,name,itemname,itemcatName,itemQty)values('val1','val2','val3','val4','val5')"; 

se è prima volta poi inserirla nel database altrimenti se esiste aggiornamento è

come fare?

+1

Come utilizzare una ** clausola MERGE ** insieme a una tabella temporanea con i dettagli dell'utente? Non è meglio? –

+0

Sakhile - Sì, lo è - quindi dove è la tua risposta nella sezione ... risposta ...? –

+0

'MERGE' sarebbe appropriato per questo caso d'uso ma si dovrebbe notare che è stato introdotto solo in SQL Server 2008 (presumibilmente, l'OP non sta ancora utilizzando il 2005 sei anni dopo). –

risposta

32

tenta di controllare per l'esistenza:

IF NOT EXISTS (SELECT * FROM dbo.Employee WHERE ID = @SomeID) 

    INSERT INTO dbo.Employee(Col1, ..., ColN) 
    VALUES(Val1, .., ValN) 

ELSE 

    UPDATE dbo.Employee 
    SET Col1 = Val1, Col2 = Val2, ...., ColN = ValN 
    WHERE ID = @SomeID 

Si potrebbe facilmente avvolgere questo in una stored procedure e basta chiamare che stored procedure dall'esterno (ad esempio da un linguaggio di programmazione come C# o qualsiasi altra cosa che si sta utilizzando) .

Aggiornamento: o si può semplicemente scrivere questo intera istruzione in una lunga serie (fattibile - ma non è davvero molto utile) - o si può avvolgerlo in una stored procedure:

CREATE PROCEDURE dbo.InsertOrUdpateEmployee 
     @ID INT, 
     @Name VARCHAR(50), 
     @ItemName VARCHAR(50), 
     @ItemCatName VARCHAR(50), 
     @ItemQty DECIMAL(15,2) 
AS BEGIN 
    IF NOT EXISTS (SELECT * FROM dbo.Table1 WHERE ID = @ID) 
     INSERT INTO dbo.Table1(ID, Name, ItemName, ItemCatName, ItemQty) 
     VALUES(@ID, @Name, @ItemName, @ItemCatName, @ItemQty) 
    ELSE 
     UPDATE dbo.Table1 
     SET Name = @Name, 
      ItemName = @ItemName, 
      ItemCatName = @ItemCatName, 
      ItemQty = @ItemQty 
     WHERE ID = @ID 
END 

e poi basta chiama la stored procedure dal tuo codice ADO.NET

+0

dove scrivere sopra il codice nella stringa sql sopra o creare un trigger o una procedura. – ybc126

+1

scrittura in stringa singola sarà simile a String sql = "IF NOT EXIST (SELECT * FROM Dipendente WHERE ID = @ someid) INSERT INTO DIPENDENTE (col1, ..., colN) valori (val1, .., valN) ELSE AGGIORNA SET DI IMPIEGATI col1 = val1, col2 = val2, ..., colN = valN WHERE ID = @ someID " Funzionerà. – ybc126

+0

@ ybc126: se hai gli spazi necessari nel tuo SQL - sì. Ma qualcosa del genere è ** sicuramente ** non consigliabile! Mettendo questo in una stored procedure (o usando un ORM per gestire questo) sarebbe ** molto meglio ** –

1

È possibile eseguire questa operazione con un trigger INSTEAD OF INSERT nella tabella, che verifica l'esistenza della riga e quindi aggiorna/inserisce a seconda che esista già. V'è un esempio di come fare questo per SQL Server 2000 + su MSDN here:

CREATE TRIGGER IO_Trig_INS_Employee ON Employee 
INSTEAD OF INSERT 
AS 
BEGIN 
SET NOCOUNT ON 
-- Check for duplicate Person. If no duplicate, do an insert. 
IF (NOT EXISTS (SELECT P.SSN 
     FROM Person P, inserted I 
     WHERE P.SSN = I.SSN)) 
    INSERT INTO Person 
     SELECT SSN,Name,Address,Birthdate 
     FROM inserted 
ELSE 
-- Log attempt to insert duplicate Person row in PersonDuplicates table. 
    INSERT INTO PersonDuplicates 
     SELECT SSN,Name,Address,Birthdate,SUSER_SNAME(),GETDATE() 
     FROM inserted 
-- Check for duplicate Employee. If no duplicate, do an insert. 
IF (NOT EXISTS (SELECT E.SSN 
     FROM EmployeeTable E, inserted 
     WHERE E.SSN = inserted.SSN)) 
    INSERT INTO EmployeeTable 
     SELECT EmployeeID,SSN, Department, Salary 
     FROM inserted 
ELSE 
--If duplicate, change to UPDATE so that there will not 
--be a duplicate key violation error. 
    UPDATE EmployeeTable 
     SET EmployeeID = I.EmployeeID, 
      Department = I.Department, 
      Salary = I.Salary 
    FROM EmployeeTable E, inserted I 
    WHERE E.SSN = I.SSN 
END 
11

È possibile utilizzare @@ROWCOUNT per verificare se fila dovrebbe essere inserita o aggiornata:

update table1 
set name = 'val2', itemname = 'val3', itemcatName = 'val4', itemQty = 'val5' 
where id = 'val1' 
if @@ROWCOUNT = 0 
insert into table1(id, name, itemname, itemcatName, itemQty) 
values('val1', 'val2', 'val3', 'val4', 'val5') 

in questo caso se aggiornamento non riesce, la nuova riga verrà inserita

4

(la mia risposta è al di sotto, ma dopo che ho capito che c'è una migliore domanda & risposta su questo a Insert into a MySQL table or update if exists)

È possibile verificare se esiste la riga, e quindi inserire o UPDATE, ma questo garantisce si esibiranno due operazioni SQL invece di uno:

  1. controllo se riga esiste
  2. inserimento o aggiornamento fila

una soluzione migliore è di aggiornare sempre al primo posto, e se nessuna riga sono state aggiornate, poi fare un INSERT, in questo modo:

update table1 
set name = 'val2', itemname = 'val3', itemcatName = 'val4', itemQty = 'val5' 
where id = 'val1' 

if @@ROWCOUNT = 0 
    insert into table1(id, name, itemname, itemcatName, itemQty) 
    values('val1', 'val2', 'val3', 'val4', 'val5') 

Questo richiederà una sola operazione SQL o due operazioni SQL, a seconda che la riga esista già.

Ma se le prestazioni sono davvero un problema, è necessario capire se è più probabile che le operazioni siano INSERT o UPDATE. Se UPDATE sono più comuni, fai quanto sopra. Se gli INSERT sono più comuni, puoi farlo al contrario, ma devi aggiungere la gestione degli errori.

BEGIN TRY 
    insert into table1(id, name, itemname, itemcatName, itemQty) 
    values('val1', 'val2', 'val3', 'val4', 'val5') 
END TRY 
BEGIN CATCH 
    update table1 
    set name = 'val2', itemname = 'val3', itemcatName = 'val4', itemQty = 'val5' 
    where id = 'val1' 
END CATCH 

essere davvero certo se avete bisogno di fare un UPDATE o INSERT, devi fare due operazioni in una singola transazione. Teoricamente, subito dopo il primo UPDATE o INSERT (o anche il controllo EXISTS), ma prima della successiva istruzione INSERT/UPDATE, il database potrebbe essere cambiato, causando comunque il fallimento della seconda istruzione. Questo è estremamente raro e il sovraccarico per le transazioni potrebbe non valerne la pena.

In alternativa, è possibile utilizzare un'unica operazione SQL denominata MERGE per eseguire un INSERT o un UPDATE, ma probabilmente è anche eccessivo per questa operazione a una riga.

Considerare la lettura di SQL transaction statements, race conditions, SQL MERGE statement.

+0

Il collegamento alla domanda che si menziona è specifico per MySql dove questo thread riguarda SQL Server che non ha l'opzione ON DUPLICATE KEY UPDATE. Potresti chiarire quale risposta intendi o è un errore da parte tua? –

Problemi correlati