How to Skip Rows that Violate Constraints When Inserting Data in SQLite

In SQLite, when you try to insert multiple rows into a table, and any of those rows violates a constraint on that table, the operation will fail.

This is to be expected, after all, that’s what the constraint is for.

But what if you just want to ignore any rows that violate constraints? In other words, if a row violates a constraint, you want SQLite to skip that row, then carry on processing the next row, and so on.

Fortunately, there’s an easy way to do this in SQLite.

The ON CONFLICT Clause

SQLite has the ON CONFLICT clause that allows you to specify how to handle constraint conflicts. More specifically, it applies to UNIQUE, NOT NULL, CHECK, and PRIMARY KEY constraints (but not FOREIGN KEY constraints).

The ON CONFLICT clause is used in CREATE TABLE statements, but when inserting data, the clause is replaced with OR.

Therefore, you can use this clause to determine how to handle constraint violations when inserting data.

There are five possible values you can use with this clause:

  • ROLLBACK
  • ABORT
  • FAIL
  • IGNORE
  • REPLACE

For the purposes of this article, we’ll be using the IGNORE option.

Using IGNORE causes SQLite to skip the one row that contains the constraint violation and continue processing subsequent rows as if nothing went wrong.

Example

Here’s a CREATE TABLE statement for a table called Products:

CREATE TABLE Products( 
    ProductId INTEGER PRIMARY KEY, 
    ProductName NOT NULL, 
    Price 
);

Notice that this table includes a NOT NULL constraint on the ProductName column.

Now let’s try to insert data that violates that constraint.

INSERT INTO Products VALUES 
    (1, 'Widget Holder', 139.50),
    (2, NULL, 11.00),
    (3, 'Widget Stick', 89.75);

Result:

Error: NOT NULL constraint failed: Products.ProductName

Not surprisingly, we get an error indicating that the NOT NULL constraint was violated.

Now let’s see how many rows were inserted into the table.

SELECT COUNT(*) FROM Products;

Result:

0

So we know that only the second row violated the constraint, but this prevented any data from being inserted.

We can change this by adding OR IGNORE to our INSERT statement:

INSERT OR IGNORE INTO Products VALUES 
    (1, 'Widget Holder', 139.50),
    (2, NULL, 11.00),
    (3, 'Widget Stick', 89.75);

That’s all that’s required. Running this code does not result in an error like the previous code. Running this code results in the good data being inserted, and the bad data being ignored.

Now if we run a SELECT statement against the table, we can see that the good data was in fact inserted.

SELECT * FROM Products;

Result:

ProductId   ProductName    Price     
----------  -------------  ----------
1           Widget Holder  139.5     
3           Widget Stick   89.75