I have a SQLite database which, amongst other things, has the following table.
CREATE TABLE IF NOT EXISTS biases
(
data INTEGER NOT NULL,
link INTEGER DEFAULT 0,
bias_type INTEGER,
ignores INTEGER DEFAULT 0,
desists INTEGER DEFAULT 0,
encashes INTEGER DEFAULT 0,
accesses INTEGER DEFAULT 0,
scraps INTEGER DEFAULT 0,
CONSTRAINT pk_bias_mix PRIMARY KEY(data,link,bias_type)
);
The constraint pk_bias_mix
is being used to ensure that no two rows can have the same values for all three columns data
, link
and bias_type
columns. So suppose I do
INSERT INTO biases (data,link,bias_type,ignores) VALUES(1,1,1,1);
things work as expected - a new row is inserted in the table. If I issue the same INSERT again I get the error
UNIQUE CONSTRAINT FAILED: biases.data,biases.link,biases.bias_type
just as expected. I tried to use the SQLite ON CONFLICT
clause thus
INSERT INTO biases (data,link,bias_type,ignores) VALUES(1,1,1,1)
ON CONFLICT(data,link,bias_type) DO UPDATE SET ignores = ignores + 1;
and it worked as I had hoped - instead of adding a new row or throwing up an error SQLite incremented the value of the ignores
column in the row with the matching data
, link
and bias_type
values.
However, this is just the result of an experiment. It is not immediately clear to me from the SQLite docs that this is indeed how ON CONFLICT
is supposed to behave - i.e it can be given two or more conflict constraints to be checked. What I mean by two or more constraints is specifying multiple, comma separated, columns inside CONFLICT(...)
as I have done in the example above.
I suspect that this is the right usage since I am merely specifying a CONFLICT
condition that replicates my indicated CONSTRAINT
. However, I cannot see this explained explicitly anywhere in the docs. I'd be much obliged to anyone who might be able to confirm this.
From UPSERT:
UPSERT is a special syntax addition to INSERT that causes the INSERT to behave as an UPDATE or a no-op if the INSERT would violate a uniqueness constraint.
and:
The special UPSERT processing happens only for uniqueness constraint on the table that is receiving the INSERT.
So the DO UPDATE
part is not triggered by any constraint conflict but only by a unique constraint violation.
Also:
The syntax that occurs in between the "ON CONFLICT" and "DO" keywords is called the "conflict target". The conflict target specifies a specific uniqueness constraint that will trigger the upsert.
So it is not possible to have two or more conflict constraints to be checked in one statement.
However you can use separate UPSERT
statements to check for 2 different unique constraint violations.
See a simplified demo where I added 1 more UNIQUE
constraint to your table:
CONSTRAINT con_scraps UNIQUE(scraps)