L'une des extensions non standard de SQLite pour SQL est le ON CONFLICT
clause.
Cette clause vous permet de déterminer ce qui doit se passer lorsque certains conflits surviennent en raison d'une violation de contrainte.
L'une des choses pour lesquelles vous pouvez utiliser cette clause est de remplacer NULL
valeurs par la valeur par défaut d'une colonne lors de l'insertion ou de la mise à jour de données dans une table.
Par défaut, si vous essayez d'insérer explicitement NULL
dans une colonne avec un NOT NULL
contrainte, cela échouera.
Et si vous essayez d'insérer explicitement NULL
dans une colonne sans un NOT NULL
contrainte, puis NULL
sera assigné à cette colonne, même s'il y a un DEFAULT
clause.
Cependant, vous pouvez utiliser le ON CONFLICT
clause pour la définir sur la valeur par défaut au lieu de NULL
.
Exemple
Le code suivant illustre ce que je veux dire.
DROP TABLE IF EXISTS Products;
CREATE TABLE Products(
ProductId INTEGER PRIMARY KEY,
ProductName NOT NULL,
Price NOT NULL ON CONFLICT REPLACE DEFAULT 0.00
);
INSERT INTO Products (ProductId, ProductName, Price) VALUES
(1, 'Widget Holder', NULL);
SELECT * FROM Products;
Dans cet exemple, j'utilise ON CONFLICT REPLACE
pour définir NULL
valeurs à la valeur par défaut au lieu de NULL
.
Voici le résultat du SELECT
déclaration sur la dernière ligne :
ProductId ProductName Price ---------- ------------- ---------- 1 Widget Holder 0.0
Nous pouvons voir que le Prix la colonne a la valeur par défaut de 0.0 même si j'ai essayé d'insérer explicitement NULL
.
Voyons ce qui se passe si je supprime le NOT NULL
contrainte.
DROP TABLE IF EXISTS Products;
CREATE TABLE Products(
ProductId INTEGER PRIMARY KEY,
ProductName NOT NULL,
Price DEFAULT 0.00
);
INSERT INTO Products (ProductId, ProductName, Price) VALUES
(1, 'Widget Holder', NULL);
SELECT * FROM Products;
Résultat :
ProductId ProductName Price ---------- ------------- ---------- 1 Widget Holder
Maintenant, la colonne contient NULL
.
Insérer NULL implicitement
Il est important de noter que cet article concerne principalement l'insertion de NULL
explicitement .
Si vous essayez d'insérer NULL
implicitement , l'exemple précédent produira un résultat différent.
Ce que je veux dire, c'est que si vous n'incluez pas la colonne dans le INSERT
déclaration, le DEFAULT
contrainte sera utilisée automatiquement. C'est ce que DEFAULT
les contraintes sont pour - pour fournir une valeur lorsque vous n'en fournissez pas explicitement.
Voici ce qui se passe lorsque je fais cela.
DROP TABLE IF EXISTS Products;
CREATE TABLE Products(
ProductId INTEGER PRIMARY KEY,
ProductName NOT NULL,
Price DEFAULT 0.00
);
INSERT INTO Products (ProductId, ProductName) VALUES
(1, 'Widget Holder');
SELECT * FROM Products;
Résultat :
ProductId ProductName Price ---------- ------------- ---------- 1 Widget Holder 0.0
Donc, tout ce que j'ai fait, c'est supprimer le Prix colonne de INSERT
déclaration.
EN CONFLIT pour l'instruction INSERT
Le premier exemple utilise ON CONFLICT
sur le CREATE TABLE
déclaration.
Mais que se passe-t-il si la table n'a pas été créée avec le ON CONFLICT
clause ?
Heureusement, il existe également un moyen de l'utiliser sur le INSERT
déclaration.
La syntaxe est légèrement différente. Lorsqu'il est utilisé sur le INSERT
déclaration que vous devez remplacer ON CONFLICT
avec OR
.
Modifions le code pour utiliser cette méthode.
DROP TABLE IF EXISTS Products;
CREATE TABLE Products(
ProductId INTEGER PRIMARY KEY,
ProductName NOT NULL,
Price NOT NULL DEFAULT 0.00
);
INSERT OR REPLACE INTO Products (ProductId, ProductName, Price) VALUES
(1, 'Widget Holder', NULL);
SELECT * FROM Products;
Résultat :
ProductId ProductName Price ---------- ------------- ---------- 1 Widget Holder 0.0
J'ai donc remplacé INSERT INTO
avec INSERT OR REPLACE INTO
.
Voici quel serait le résultat si je n'avais pas inséré cette clause.
DROP TABLE IF EXISTS Products;
CREATE TABLE Products(
ProductId INTEGER PRIMARY KEY,
ProductName NOT NULL,
Price NOT NULL DEFAULT 0.00
);
INSERT INTO Products (ProductId, ProductName, Price) VALUES
(1, 'Widget Holder', NULL);
SELECT * FROM Products;
Résultat :
Error: NOT NULL constraint failed: Products.Price
Pas de contrainte DEFAULT ?
Dans le cas où vous utilisez le ON CONFLICT
clause sur une colonne sans DEFAULT
contrainte, l'instruction SQL est abandonnée avec une erreur SQLITE_CONSTRAINT toutes les modifications apportées par l'instruction SQL actuelle sont annulées ; mais les modifications causées par les instructions SQL précédentes dans la même transaction sont conservées et la transaction reste active.