I SQLite, när du försöker infoga flera rader i en tabell, och någon av dessa rader bryter mot en begränsning på den tabellen, kommer operationen att misslyckas.
Detta är att vänta, trots allt, det är vad begränsningen är till för.
Men vad händer om du bara vill ignorera alla rader som bryter mot begränsningar? Med andra ord, om en rad bryter mot en begränsning vill du att SQLite ska hoppa över den raden och sedan fortsätta bearbeta nästa rad och så vidare.
Lyckligtvis finns det ett enkelt sätt att göra detta i SQLite.
ON CONFLICT-klausulen
SQLite har ON CONFLICT
klausul som låter dig specificera hur begränsningskonflikter ska hanteras. Mer specifikt gäller det UNIQUE
, NOT NULL
, CHECK
och PRIMARY KEY
begränsningar (men inte FOREIGN KEY
begränsningar).
ON CONFLICT
sats används i CREATE TABLE
satser, men när data infogas ersätts satsen med OR
.
Därför kan du använda den här klausulen för att avgöra hur du ska hantera överträdelser av begränsningar när du infogar data.
Det finns fem möjliga värden du kan använda med denna sats:
ROLLBACK
ABORT
FAIL
IGNORE
REPLACE
I den här artikeln kommer vi att använda IGNORE
alternativ.
Använder IGNORE
gör att SQLite hoppar över den ena raden som innehåller begränsningsöverträdelsen och fortsätter att bearbeta efterföljande rader som om inget gick fel.
Exempel
Här är en CREATE TABLE
uttalande för en tabell som heter Produkter :
CREATE TABLE Products(
ProductId INTEGER PRIMARY KEY,
ProductName NOT NULL,
Price
);
Observera att den här tabellen innehåller en NOT NULL
begränsning på Produktnamn kolumn.
Låt oss nu försöka infoga data som bryter mot denna begränsning.
INSERT INTO Products VALUES
(1, 'Widget Holder', 139.50),
(2, NULL, 11.00),
(3, 'Widget Stick', 89.75);
Resultat:
Error: NOT NULL constraint failed: Products.ProductName
Inte överraskande får vi ett fel som indikerar att NOT NULL
begränsningen överträddes.
Låt oss nu se hur många rader som infogades i tabellen.
SELECT COUNT(*) FROM Products;
Resultat:
0
Så vi vet att endast den andra raden bröt mot begränsningen, men detta förhindrade någon data från att infogas.
Vi kan ändra detta genom att lägga till OR IGNORE
till vår INSERT
uttalande:
INSERT OR IGNORE INTO Products VALUES
(1, 'Widget Holder', 139.50),
(2, NULL, 11.00),
(3, 'Widget Stick', 89.75);
Det är allt som krävs. Att köra den här koden resulterar inte i ett fel som den tidigare koden. Att köra den här koden resulterar i att bra data infogas och att dålig data ignoreras.
Om vi nu kör en SELECT
uttalande mot tabellen kan vi se att den goda informationen faktiskt infogades.
SELECT * FROM Products;
Resultat:
ProductId ProductName Price ---------- ------------- ---------- 1 Widget Holder 139.5 3 Widget Stick 89.75>