W SQLite, gdy próbujesz wstawić wiele wierszy do tabeli, a którykolwiek z tych wierszy narusza ograniczenie w tej tabeli, operacja zakończy się niepowodzeniem.
Należy się tego spodziewać, w końcu po to jest ograniczenie.
Ale co, jeśli chcesz po prostu zignorować wszystkie wiersze, które naruszają ograniczenia? Innymi słowy, jeśli wiersz narusza ograniczenie, chcesz, aby SQLite pominął ten wiersz, a następnie kontynuował przetwarzanie następnego wiersza i tak dalej.
Na szczęście istnieje prosty sposób na zrobienie tego w SQLite.
Klauzula ON CONFLICT
SQLite ma ON CONFLICT
klauzula, która pozwala określić sposób obsługi konfliktów ograniczeń. Dokładniej, dotyczy to UNIQUE
, NOT NULL
, CHECK
i PRIMARY KEY
ograniczenia (ale nie FOREIGN KEY
ograniczenia).
ON CONFLICT
klauzula jest używana w CREATE TABLE
oświadczenia, ale podczas wstawiania danych klauzula jest zastępowana przez OR
.
Dlatego możesz użyć tej klauzuli, aby określić, jak postępować z naruszeniami ograniczeń podczas wstawiania danych.
Istnieje pięć możliwych wartości, których można użyć w tej klauzuli:
ROLLBACK
ABORT
FAIL
IGNORE
REPLACE
Na potrzeby tego artykułu będziemy używać IGNORE
opcja.
Używanie IGNORE
powoduje, że SQLite pomija jeden wiersz, który zawiera naruszenie ograniczenia i kontynuuje przetwarzanie kolejnych wierszy, tak jakby nic nie poszło nie tak.
Przykład
Oto CREATE TABLE
oświadczenie dla tabeli o nazwie Produkty :
CREATE TABLE Products(
ProductId INTEGER PRIMARY KEY,
ProductName NOT NULL,
Price
);
Zauważ, że ta tabela zawiera NOT NULL
ograniczenie w ProductName kolumna.
Teraz spróbujmy wstawić dane, które naruszają to ograniczenie.
INSERT INTO Products VALUES
(1, 'Widget Holder', 139.50),
(2, NULL, 11.00),
(3, 'Widget Stick', 89.75);
Wynik:
Error: NOT NULL constraint failed: Products.ProductName
Nic dziwnego, że otrzymujemy błąd wskazujący, że NOT NULL
ograniczenie zostało naruszone.
Zobaczmy teraz, ile wierszy zostało wstawionych do tabeli.
SELECT COUNT(*) FROM Products;
Wynik:
0
Wiemy więc, że tylko drugi wiersz naruszył ograniczenie, ale zapobiegło to wszelkim dane przed wstawieniem.
Możemy to zmienić, dodając OR IGNORE
do naszego INSERT
oświadczenie:
INSERT OR IGNORE INTO Products VALUES
(1, 'Widget Holder', 139.50),
(2, NULL, 11.00),
(3, 'Widget Stick', 89.75);
To wszystko, co jest wymagane. Uruchomienie tego kodu nie powoduje błędu, jak w poprzednim kodzie. Uruchomienie tego kodu spowoduje wstawienie dobrych danych i zignorowanie złych danych.
Teraz, jeśli uruchomimy SELECT
oświadczenie w stosunku do tabeli, widzimy, że dobre dane zostały faktycznie wstawione.
SELECT * FROM Products;
Wynik:
ProductId ProductName Price ---------- ------------- ---------- 1 Widget Holder 139.5 3 Widget Stick 89.75