Eine der nicht standardmäßigen Erweiterungen von SQLite für SQL ist ON CONFLICT
Klausel.
Mit dieser Klausel können Sie festlegen, was passieren soll, wenn bestimmte Konflikte aufgrund einer Einschränkungsverletzung auftreten.
Eines der Dinge, für die Sie diese Klausel verwenden können, ist das Ersetzen von NULL
Werte mit dem Standardwert einer Spalte beim Einfügen oder Aktualisieren von Daten in einer Tabelle.
Standardmäßig, wenn Sie versuchen, explizit NULL
einzufügen in eine Spalte mit NOT NULL
Einschränkung, es wird scheitern.
Und wenn Sie versuchen, explizit NULL
einzufügen in eine Spalte ohne a NOT NULL
Einschränkung, dann NULL
wird dieser Spalte zugewiesen, auch wenn es einen DEFAULT
gibt Klausel.
Sie können jedoch den ON CONFLICT
verwenden -Klausel, um sie auf den Standardwert anstelle von NULL
zu setzen .
Beispiel
Der folgende Code zeigt, was ich meine.
DROP TABLE IF EXISTS Products;
CREATE TABLE Products(
ProductId INTEGER PRIMARY KEY,
ProductName NOT NULL,
Price NOT NULL ON CONFLICT REPLACE DEFAULT 0.00
);
INSERT INTO Products (ProductId, ProductName, Price) VALUES
(1, 'Widget Holder', NULL);
SELECT * FROM Products;
In diesem Beispiel verwende ich ON CONFLICT REPLACE
um NULL
zu setzen Werte auf den Standardwert anstelle von NULL
.
Hier ist das Ergebnis von SELECT
Anweisung in der letzten Zeile:
ProductId ProductName Price ---------- ------------- ---------- 1 Widget Holder 0.0
Das sehen wir am Preis Spalte hat den Standardwert von 0,0, obwohl ich versucht habe, explizit NULL
einzufügen .
Mal sehen, was passiert, wenn ich NOT NULL
entferne Einschränkung.
DROP TABLE IF EXISTS Products;
CREATE TABLE Products(
ProductId INTEGER PRIMARY KEY,
ProductName NOT NULL,
Price DEFAULT 0.00
);
INSERT INTO Products (ProductId, ProductName, Price) VALUES
(1, 'Widget Holder', NULL);
SELECT * FROM Products;
Ergebnis:
ProductId ProductName Price ---------- ------------- ---------- 1 Widget Holder
Jetzt enthält die Spalte NULL
.
Implizites Einfügen von NULL
Es ist wichtig zu beachten, dass sich dieser Artikel hauptsächlich mit dem Einfügen von NULL
befasst ausdrücklich .
Wenn Sie versuchen, NULL
einzufügen implizit , dann führt das vorherige Beispiel zu einem anderen Ergebnis.
Was ich meine ist, wenn Sie die Spalte nicht in INSERT
einfügen -Anweisung, die DEFAULT
Einschränkung wird automatisch verwendet. Das ist DEFAULT
Beschränkungen sind für – um einen Wert bereitzustellen, wenn Sie nicht explizit einen angeben.
Folgendes passiert, wenn ich das tue.
DROP TABLE IF EXISTS Products;
CREATE TABLE Products(
ProductId INTEGER PRIMARY KEY,
ProductName NOT NULL,
Price DEFAULT 0.00
);
INSERT INTO Products (ProductId, ProductName) VALUES
(1, 'Widget Holder');
SELECT * FROM Products;
Ergebnis:
ProductId ProductName Price ---------- ------------- ---------- 1 Widget Holder 0.0
Also habe ich nur den Preis entfernt Spalte aus INSERT
Aussage.
ON CONFLICT für die INSERT-Anweisung
Das erste Beispiel verwendet ON CONFLICT
auf CREATE TABLE
Aussage.
Was aber, wenn die Tabelle nicht mit dem ON CONFLICT
erstellt wurde Klausel?
Glücklicherweise gibt es auch eine Möglichkeit, es auf INSERT
zu verwenden Erklärung.
Die Syntax ist etwas anders. Bei Verwendung auf INSERT
-Anweisung müssen Sie ON CONFLICT
ersetzen mit OR
.
Lassen Sie uns den Code ändern, um diese Methode zu verwenden.
DROP TABLE IF EXISTS Products;
CREATE TABLE Products(
ProductId INTEGER PRIMARY KEY,
ProductName NOT NULL,
Price NOT NULL DEFAULT 0.00
);
INSERT OR REPLACE INTO Products (ProductId, ProductName, Price) VALUES
(1, 'Widget Holder', NULL);
SELECT * FROM Products;
Ergebnis:
ProductId ProductName Price ---------- ------------- ---------- 1 Widget Holder 0.0
Also ersetzte ich INSERT INTO
mit INSERT OR REPLACE INTO
.
Hier ist, was das Ergebnis wäre, wenn ich diese Klausel nicht eingefügt hätte.
DROP TABLE IF EXISTS Products;
CREATE TABLE Products(
ProductId INTEGER PRIMARY KEY,
ProductName NOT NULL,
Price NOT NULL DEFAULT 0.00
);
INSERT INTO Products (ProductId, ProductName, Price) VALUES
(1, 'Widget Holder', NULL);
SELECT * FROM Products;
Ergebnis:
Error: NOT NULL constraint failed: Products.Price
Keine STANDARD-Einschränkung?
Für den Fall, dass Sie den Code ON CONFLICT
verwenden -Klausel für eine Spalte ohne DEFAULT
Einschränkung wird die SQL-Anweisung mit einem SQLITE_CONSTRAINT-Fehler abgebrochen. Alle Änderungen, die von der aktuellen SQL-Anweisung vorgenommen wurden, werden rückgängig gemacht. Änderungen, die durch frühere SQL-Anweisungen innerhalb derselben Transaktion verursacht wurden, bleiben jedoch erhalten und die Transaktion bleibt aktiv.