Vorgehensweise WENN IN SQLite NICHT EXISTIERT

80

Ich versuche, diese Zeile von MS SQL Server nach SQLite zu portieren

IF NOT EXISTS(SELECT 1 FROM EVENTTYPE WHERE EventTypeName = 'ANI Received') 
    INSERT INTO EVENTTYPE (EventTypeName) VALUES ('ANI Received');

Es scheint, dass SQLite WENN NICHT EXISTIERT nicht unterstützt wird oder ich es zumindest nicht zum Laufen bringen kann. Vermisse ich etwas Einfaches? Gibt es eine Problemumgehung?

AngryHacker
quelle

Antworten:

120

Wie wäre es damit?

INSERT OR IGNORE INTO EVENTTYPE (EventTypeName) VALUES 'ANI Received'

(Ungetestet, da ich kein SQLite habe ... dieser Link ist jedoch ziemlich beschreibend.)

Darüber hinaus sollte dies auch funktionieren:

INSERT INTO EVENTTYPE (EventTypeName)
SELECT 'ANI Received'
WHERE NOT EXISTS (SELECT 1 FROM EVENTTYPE WHERE EventTypeName = 'ANI Received');
Strand
quelle
14
Vielen Dank. Es sollte jedoch beachtet werden, dass das Stück INSERT OR IGNORE nur funktioniert, wenn EventTypeName als eindeutig festgelegt ist.
AngryHacker
2
Wahr. Ich nahm an, dass es einzigartig war, da es in der Beispiel-SQL verwendet wurde. Wenn nicht, sollte die zweite Methode verwendet werden.
Strand
Kann die zweite Methode wirklich verwendet werden, wenn EventTypeName nicht eindeutig ist? Ich versuche etwas Ähnliches zu tun und stelle fest, dass die SELECT WHERE NOT EXISTS-Klausel mehrere Zeilen zurückgibt, und zwar jede Zeile, in der (das Äquivalent von) EventTypeName! = 'ANI Received' wahr ist.
Michael
EventTypeName soll eindeutig sein. Der neue Wert 'ANI Received' wird nur in die Tabelle EVENTTYPE eingefügt, wenn er noch nicht in der Tabelle vorhanden ist. Hier kommt die WHERE NOT EXISTS-Klausel ins Spiel. Die SELECT WHERE NOT EXISTS-Klausel kann nur eine einzelne Zeile zurückgeben. Es gibt keine FROM-Klausel - es gibt keine Möglichkeit, mehrere Zeilen zurückzugeben. Hoffe das klärt es auf.
Strand
1
Dies ist ein sehr schlechter Codierungsstil. Bei jedem Fehler schlägt die Abfrage stillschweigend fehl! Aus den Dokumenten: IGNOREWenn eine anwendbare Einschränkungsverletzung auftritt, überspringt der IGNORE-Auflösungsalgorithmus die eine Zeile, die die Einschränkungsverletzung enthält, und verarbeitet die nachfolgenden Zeilen der SQL-Anweisung weiter, als ob nichts schief gelaufen wäre. Andere Zeilen vor und nach der Zeile, die die Einschränkungsverletzung enthielt, werden normal eingefügt oder aktualisiert. Bei Verwendung des IGNORE-Konfliktlösungsalgorithmus wird kein Fehler zurückgegeben.
ManuelSchneid3r
12

Wenn Sie das Einfügen eines vorhandenen Werts ignorieren möchten, muss Ihre Tabelle ein Schlüsselfeld enthalten. Erstellen Sie einfach eine Tabelle mit Primärschlüsselfeld wie:

CREATE TABLE IF NOT EXISTS TblUsers (UserId INTEGER PRIMARY KEY, UserName varchar(100), ContactName varchar(100),Password varchar(100));

Und dann Abfrage in die Tabelle einfügen oder ersetzen / einfügen oder ignorieren wie:

INSERT OR REPLACE INTO TblUsers (UserId, UserName, ContactName ,Password) VALUES('1','UserName','ContactName','Password');

Der vorhandene Primärschlüsselwert wird nicht erneut eingegeben. Auf diese Weise können Sie überprüfen, ob ein Wert in der Tabelle vorhanden ist oder nicht.

TheDean
quelle
1

Sie können auch eine Einschränkung für eine Tabelle mit den KEY-Feldern festlegen und On Conflict auf "Ignorieren" setzen.

Wenn eine anwendbare Einschränkungsverletzung auftritt, überspringt der IGNORE-Auflösungsalgorithmus die eine Zeile, die die Einschränkungsverletzung enthält, und verarbeitet die nachfolgenden Zeilen der SQL-Anweisung weiter, als ob nichts schief gelaufen wäre. Andere Zeilen vor und nach der Zeile, die die Einschränkungsverletzung enthielt, werden normal eingefügt oder aktualisiert. Bei Verwendung des IGNORE-Konfliktlösungsalgorithmus wird kein Fehler zurückgegeben.

SQLite-Dokumentation

1lb3r
quelle