Trong SQLite, khi bạn cố gắng chèn nhiều hàng vào bảng và bất kỳ hàng nào trong số đó vi phạm một ràng buộc trên bảng đó, thao tác sẽ không thành công.
Rốt cuộc, điều này được mong đợi, đó là điều mà ràng buộc dành cho.
Nhưng nếu bạn chỉ muốn bỏ qua bất kỳ hàng nào vi phạm các ràng buộc? Nói cách khác, nếu một hàng vi phạm một ràng buộc, bạn muốn SQLite bỏ qua hàng đó, sau đó tiếp tục xử lý hàng tiếp theo, v.v.
May mắn thay, có một cách dễ dàng để thực hiện việc này trong SQLite.
Điều khoản ON MFLICT
SQLite có ON CONFLICT
mệnh đề cho phép bạn chỉ định cách xử lý xung đột ràng buộc. Cụ thể hơn, nó áp dụng cho UNIQUE
, NOT NULL
, CHECK
và PRIMARY KEY
ràng buộc (nhưng không phải FOREIGN KEY
ràng buộc).
ON CONFLICT
mệnh đề được sử dụng trong CREATE TABLE
nhưng khi chèn dữ liệu, mệnh đề được thay thế bằng OR
.
Do đó, bạn có thể sử dụng điều khoản này để xác định cách xử lý các vi phạm ràng buộc khi chèn dữ liệu.
Có năm giá trị khả thi mà bạn có thể sử dụng với mệnh đề này:
-
ROLLBACK
-
ABORT
-
FAIL
-
IGNORE
-
REPLACE
Vì mục đích của bài viết này, chúng tôi sẽ sử dụng IGNORE
tùy chọn.
Sử dụng IGNORE
khiến SQLite bỏ qua một hàng có vi phạm ràng buộc và tiếp tục xử lý các hàng tiếp theo như thể không có gì sai.
Ví dụ
Đây là CREATE TABLE
câu lệnh cho bảng có tên Sản phẩm :
CREATE TABLE Products(
ProductId INTEGER PRIMARY KEY,
ProductName NOT NULL,
Price
);
Lưu ý rằng bảng này bao gồm NOT NULL
ràng buộc về Tên sản phẩm cột.
Bây giờ chúng ta hãy thử chèn dữ liệu vi phạm ràng buộc đó.
INSERT INTO Products VALUES
(1, 'Widget Holder', 139.50),
(2, NULL, 11.00),
(3, 'Widget Stick', 89.75);
Kết quả:
Error: NOT NULL constraint failed: Products.ProductName
Không có gì ngạc nhiên khi chúng tôi gặp lỗi cho biết rằng NOT NULL
ràng buộc đã bị vi phạm.
Bây giờ, hãy xem có bao nhiêu hàng được chèn vào bảng.
SELECT COUNT(*) FROM Products;
Kết quả:
0
Vì vậy, chúng tôi biết rằng chỉ hàng thứ hai vi phạm ràng buộc, nhưng điều này đã ngăn chặn bất kỳ dữ liệu từ việc được chèn.
Chúng tôi có thể thay đổi điều này bằng cách thêm OR IGNORE
vào INSERT
của chúng tôi tuyên bố:
INSERT OR IGNORE INTO Products VALUES
(1, 'Widget Holder', 139.50),
(2, NULL, 11.00),
(3, 'Widget Stick', 89.75);
Đó là tất cả những gì cần thiết. Chạy mã này không bị lỗi như mã trước. Việc chạy mã này dẫn đến dữ liệu tốt được chèn vào và dữ liệu xấu sẽ bị bỏ qua.
Bây giờ nếu chúng ta chạy SELECT
so với bảng, chúng ta có thể thấy rằng dữ liệu tốt trên thực tế đã được chèn vào.
SELECT * FROM Products;
Kết quả:
ProductId ProductName Price ---------- ------------- ---------- 1 Widget Holder 139.5 3 Widget Stick 89.75