SQLite ON CONFLICT 子句的正确用法

Correct usage of the SQLite ON CONFLICT clause

我有一个 SQLite 数据库,其中包括以下 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)
);  

约束 pk_bias_mix 用于确保所有三列 datalinkbias_type 的两行不能具有相同的值。所以假设我这样做

INSERT INTO biases (data,link,bias_type,ignores) VALUES(1,1,1,1);

事情按预期进行 - table 中插入了新行。如果我再次发出相同的 INSERT,我会得到错误

UNIQUE CONSTRAINT FAILED: biases.data,biases.link,biases.bias_type

正如预期的那样。我尝试使用 SQLite ON CONFLICT 子句

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;

它如我所愿地工作 - 而不是添加新行或抛出错误 SQLite 增加了行中 ignores 列的值与匹配的 data, linkbias_type 值。

然而,这只是实验的结果。从 SQLite 文档中我并不能立即清楚这确实是 ON CONFLICT 应该表现的方式——即可以给它两个或多个冲突约束来检查。我所说的两个或多个约束的意思是在 CONFLICT(...) 内指定多个逗号分隔的列,就像我在上面的示例中所做的那样。

我怀疑这是正确的用法,因为我只是指定了一个 CONFLICT 条件来复制我指定的 CONSTRAINT。但是,我在文档的任何地方都看不到这一点的明确解释。如果有人能证实这一点,我将不胜感激。

来自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.

和:

The special UPSERT processing happens only for uniqueness constraint on the table that is receiving the INSERT.

因此 DO UPDATE 部分不是由任何约束冲突触发,而是由唯一约束违规触发。

还有:

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.

因此不可能在一个语句中检查两个或更多个冲突约束。
但是,您可以使用单独的 UPSERT 语句来检查 2 个不同的唯一约束违规。

请参阅简化的 demo,其中我向 table:

添加了 1 个 UNIQUE 约束
CONSTRAINT con_scraps UNIQUE(scraps)