No SQLite, quando você tenta inserir várias linhas em uma tabela e qualquer uma dessas linhas viola uma restrição nessa tabela, a operação falha.
Isso é de se esperar, afinal, é para isso que serve a restrição.
Mas e se você quiser apenas ignorar quaisquer linhas que violem restrições? Em outras palavras, se uma linha violar uma restrição, você deseja que o SQLite pule essa linha e continue processando a próxima linha e assim por diante.
Felizmente, existe uma maneira fácil de fazer isso no SQLite.
A Cláusula DE CONFLITO
SQLite tem o
ON CONFLICT
cláusula que permite especificar como lidar com conflitos de restrição. Mais especificamente, aplica-se a UNIQUE
, NOT NULL
, CHECK
e PRIMARY KEY
restrições (mas não FOREIGN KEY
restrições). O
ON CONFLICT
cláusula é usada em CREATE TABLE
instruções, mas ao inserir dados, a cláusula é substituída por OR
. Portanto, você pode usar essa cláusula para determinar como lidar com violações de restrição ao inserir dados.
Existem cinco valores possíveis que você pode usar com esta cláusula:
ROLLBACK
ABORT
FAIL
IGNORE
REPLACE
Para os propósitos deste artigo, usaremos o
IGNORE
opção. Usando
IGNORE
faz com que o SQLite ignore a linha que contém a violação de restrição e continue processando as linhas subsequentes como se nada tivesse dado errado. Exemplo
Aqui está um
CREATE TABLE
instrução para uma tabela chamada Produtos :CREATE TABLE Products(
ProductId INTEGER PRIMARY KEY,
ProductName NOT NULL,
Price
);
Observe que esta tabela inclui um
NOT NULL
restrição no ProductName coluna. Agora vamos tentar inserir dados que violem essa restrição.
INSERT INTO Products VALUES
(1, 'Widget Holder', 139.50),
(2, NULL, 11.00),
(3, 'Widget Stick', 89.75);
Resultado:
Error: NOT NULL constraint failed: Products.ProductName
Não surpreendentemente, recebemos um erro indicando que o
NOT NULL
restrição foi violada. Agora vamos ver quantas linhas foram inseridas na tabela.
SELECT COUNT(*) FROM Products;
Resultado:
0
Portanto, sabemos que apenas a segunda linha violou a restrição, mas isso impediu qualquer dados sejam inseridos.
Podemos mudar isso adicionando
OR IGNORE
ao nosso INSERT
demonstração:INSERT OR IGNORE INTO Products VALUES
(1, 'Widget Holder', 139.50),
(2, NULL, 11.00),
(3, 'Widget Stick', 89.75);
Isso é tudo o que é necessário. A execução desse código não resulta em um erro como o código anterior. A execução desse código resulta na inserção de dados bons e ignorados nos dados ruins.
Agora, se executarmos um
SELECT
declaração contra a tabela, podemos ver que os dados bons foram de fato inseridos. SELECT * FROM Products;
Resultado:
ProductId ProductName Price ---------- ------------- ---------- 1 Widget Holder 139.5 3 Widget Stick 89.75