Een van SQLite's niet-standaard extensies voor SQL is de ON CONFLICT
clausule.
Met deze clausule kunt u bepalen wat er moet gebeuren wanneer bepaalde conflicten optreden als gevolg van een schending van een beperking.
Een van de dingen waarvoor u deze clausule kunt gebruiken, is om NULL
te vervangen waarden met de standaardwaarde van een kolom bij het invoegen of bijwerken van gegevens in een tabel.
Standaard, als u expliciet probeert NULL
. in te voegen in een kolom met een NOT NULL
beperking, het zal mislukken.
En als u probeert om expliciet NULL
in te voegen in een kolom zonder a NOT NULL
beperking, dan NULL
wordt aan die kolom toegewezen, zelfs als er een DEFAULT
. is clausule.
U kunt echter de ON CONFLICT
clausule om het in te stellen op de standaardwaarde in plaats van NULL
.
Voorbeeld
De volgende code laat zien wat ik bedoel.
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 dit voorbeeld gebruik ik ON CONFLICT REPLACE
om NULL
in te stellen waarden naar de standaardwaarde in plaats van NULL
.
Hier is het resultaat van de SELECT
uitspraak op de laatste regel:
ProductId ProductName Price ---------- ------------- ---------- 1 Widget Holder 0.0
We kunnen zien dat de Prijs kolom heeft de standaardwaarde 0.0, ook al heb ik geprobeerd om expliciet NULL
in te voegen .
Eens kijken wat er gebeurt als ik de NOT NULL
. verwijder beperking.
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;
Resultaat:
ProductId ProductName Price ---------- ------------- ---------- 1 Widget Holder
Nu bevat de kolom NULL
.
Impliciet NULL invoegen
Het is belangrijk op te merken dat dit artikel voornamelijk gaat over het invoegen van NULL
expliciet .
Als u probeert NULL
. in te voegen impliciet , dan zal het vorige voorbeeld een ander resultaat opleveren.
Wat ik bedoel is, als je de kolom niet opneemt in de INSERT
statement, de DEFAULT
beperking wordt automatisch gebruikt. Dat is wat DEFAULT
beperkingen zijn voor - om een waarde te bieden wanneer u deze niet expliciet opgeeft.
Dit is wat er gebeurt als ik dat doe.
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;
Resultaat:
ProductId ProductName Price ---------- ------------- ---------- 1 Widget Holder 0.0
Dus alles wat ik deed was de Prijs . verwijderen kolom uit de INSERT
verklaring.
OVER CONFLICT voor de INSERT-verklaring
Het eerste voorbeeld gebruikt ON CONFLICT
op de CREATE TABLE
verklaring.
Maar wat als de tabel niet is gemaakt met de ON CONFLICT
clausule?
Gelukkig is er ook een manier om het te gebruiken op de INSERT
uitspraak.
De syntaxis is iets anders. Bij gebruik op de INSERT
verklaring die u moet vervangen ON CONFLICT
met OR
.
Laten we de code aanpassen om deze methode te gebruiken.
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;
Resultaat:
ProductId ProductName Price ---------- ------------- ---------- 1 Widget Holder 0.0
Dus ik verving INSERT INTO
met INSERT OR REPLACE INTO
.
Dit is wat het resultaat zou zijn als ik die clausule niet had ingevoerd.
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;
Resultaat:
Error: NOT NULL constraint failed: Products.Price
Geen STANDAARD beperking?
In het geval dat u de ON CONFLICT
. gebruikt clausule op een kolom zonder een DEFAULT
beperking, de SQL-instructie wordt afgebroken met een SQLITE_CONSTRAINT-fout, alle wijzigingen die door de huidige SQL-instructie zijn aangebracht, worden ongedaan gemaakt; maar wijzigingen veroorzaakt door eerdere SQL-instructies binnen dezelfde transactie blijven behouden en de transactie blijft actief.