2011-01-16 9 views
15

Vorrei combinare una query di inserimento con un "dove non esiste" in modo da non violare i vincoli PK. Tuttavia, la sintassi come la seguente mi dà un errore Incorrect syntax near the keyword 'WHERE' -Come posso fare un inserto dove non esiste?

INSERT INTO myTable(columns...) 
VALUES(values...) 
WHERE NOT EXISTS 
    (SELECT * 
    FROM myTable 
    WHERE pk_part1 = value1, 
     AND pk_part2 = value2) 

Come posso fare questo?

(In generale, si può combinare un inserto con una clausola dove?)

+1

E 'MySQL. Non sono sicuro che MySQL supporterà tale sub-query. – Nishant

+0

@Nishant - No, non MySql, c'è un tag SQL ... Aggiungerò un tag SQL Server per chiarezza – froadie

+0

Dovresti usare una stored procedure e dare un'occhiata al seguente link: http://weblogs.sqlteam.com /mladenp/archive/2007/07/30/60273.aspx –

risposta

18
INSERT INTO myTable(columns...) 
Select values... 
WHERE NOT EXISTS 
    (SELECT * 
    FROM myTable 
    WHERE pk_part1 = value1, 
     AND pk_part2 = value2) 

Edit: Dopo aver letto collegamento martins, se ammettere, che la soluzione migliore è:

BEGIN TRY 
    INSERT INTO myTable(columns...) 
    values(values...) 
END TRY 
BEGIN CATCH 
    IF ERROR_NUMBER() <> 2627 
     RAISERROR etc 
END CATCH; 
+2

Ciò può ancora portare a tentativi di inserire duplicati sotto carico. Se l'OP è su SQL Server 2008 utilizzando "Unisci", evita questo problema. –

+3

Come descritto qui http://stackoverflow.com/questions/3407857/only-inserting-a-row-if-its-not-already-there –

+0

@Martin Suppongo, devo riscrivere più di questa risposta –

3

Il modo più semplice per mantenere un elenco univoco di valori è a) impostare le colonne come chiave primaria o b) creare un vincolo univoco sulle colonne. Ciascuno di questi comporterebbe un errore quando si tenta di inserire/aggiornare valori su qualcosa che già esiste nella tabella, quando un NOT EXISTS/etc fallirebbe in modo silenzioso - nessun errore, la query verrà eseguita correttamente.

Detto questo, utilizzare un INSERT/SELECT (non includere la porzione VALORI):

INSERT INTO myTable(columns...) 
SELECT [statically defined values...] 
    FROM ANY_TABLE 
WHERE NOT EXISTS (SELECT NULL 
        FROM myTable 
        WHERE pk_part1 = value1 
         AND pk_part2 = value2) 
+0

Genera un errore PK ... Voglio evitare quell'errore controllando che ci sia il primo – froadie

+0

@froadie: capisco, ma dovrei usare l'errore restituito per poter informare il utente che i valori esistono già. –

+0

Se la tupla esiste, viene generato il seguente errore: La clausola VALUES deve contenere almeno un elemento. Gli elementi vuoti non sono ammessi. –

-1

MySQL ha l'inserto ignorare query:

Se si utilizza la parola chiave Ignora, errori che si verificano durante l'esecuzione dell'istruzione INSERT vengono invece considerati come avvertimenti. Ad esempio, senza IGNORE, una riga che duplica un indice UNIQUE esistente o un valore PRIMARY KEY nella tabella causa un errore di chiave duplicata e l'istruzione viene interrotta. Con IGNORE, la riga non viene ancora inserita, ma non viene emesso alcun errore. Le conversioni di dati che causerebbero errori annullano l'istruzione se IGNORE non è specificato. Con IGNORE, i valori non validi vengono adattati ai valori più vicini e inseriti; gli avvertimenti sono prodotti ma la dichiarazione non abortisce. È possibile determinare con la funzione API C mysql_info() quante righe sono state effettivamente inserite nella tabella.

http://dev.mysql.com/doc/refman/5.0/en/insert.html

ON DUPLICATE KEY UPDATE è disponibile anche

Problemi correlati