ON CONFLICT子句是特定于SQLite的非标准扩展,可以出现在许多其他SQL命令中。由于它不是标准SQL的一部分,因此在本文档中有单独的部分,因此可能不熟悉。
自版本3.0.0(2004-06-18)以来,此处描述的ON CONFLICT子句已成为SQLite的一部分。短语“ ON CONFLICT”也是UPSERT的一部分,它是对3.24.0版(2018-06-04)中添加的INSERT的扩展。不要混淆“ ON CONFLICT”这两个单独的用法。
ON CONFLICT子句的语法如上面CREATE TABLE命令所示。对于INSERT和UPDATE命令,将关键字“ ON CONFLICT”替换为“ OR”,以便语法更自然地读取。例如,我们使用“ INSERT OR IGNORE”代替“ INSERT ON CONFLICT IGNORE”。关键字会发生变化,但是子句的含义是相同的。
ON CONFLICT子句适用于UNIQUE,NOT NULL, CHECK和PRIMARY KEY约束。ON CONFLICT算法不适用于FOREIGN KEY约束。有五个冲突解决算法选择:ROLLBACK,ABORT,FAIL,IGNORE和REPLACE。默认的冲突解决算法是ABORT。这是他们的意思:
当发生适用的约束违规时,ROLLBACK解析算法将终止当前的SQL语句,并显示SQLITE_CONSTRAINT错误,并回滚当前的事务。如果没有事务处于活动状态(除了在每个命令上创建的隐式事务),那么ROLLBACK解析算法的工作方式与ABORT算法相同。
当发生适用的约束违例时,ABORT解析算法会中止当前SQL语句,并显示SQLITE_CONSTRAINT错误,并撤消当前SQL语句所做的任何更改;但是在同一事务中由先前SQL语句引起的更改将保留,并且该事务保持活动状态。这是默认行为,也是SQL标准指定的行为。
当发生适用的约束冲突时,FAIL解决算法会中止当前SQL语句,并显示SQLITE_CONSTRAINT错误。但是,FAIL解决方案不会撤消失败的SQL语句的先前更改,也不会结束事务。例如,如果UPDATE语句在尝试更新的第100行遇到约束冲突,则将保留前99行的更改,但永远不会发生对第100行及以后的更改。
FAIL行为仅适用于唯一性,NOT NULL和CHECK约束。一个外键约束冲突导致的退出。
当发生适用的约束违例时,IGNORE解析算法将跳过包含约束违例的一行,并继续处理SQL语句的后续行,就好像什么都没出错。包含约束违例的行之前和之后的其他行将正常插入或更新。使用IGNORE冲突解决算法时,不针对唯一性,NOT NULL和UNIQUE约束错误返回任何错误。但是,对于外键约束错误,IGNORE冲突解决算法的工作方式类似于ABORT 。
当发生UNIQUE或PRIMARY KEY约束冲突时,REPLACE算法会在插入或更新当前行之前删除导致约束冲突的现有行,并且该命令将继续正常执行。如果发生NOT NULL约束冲突,则REPLACE冲突解决方案将NULL值替换为该列的默认值,或者如果该列没有默认值,则使用ABORT算法。如果发生CHECK约束或外键约束冲突,则REPLACE冲突解决算法的工作方式类似于ABORT。
当REPLACE冲突解决策略为了满足约束条件而删除行时,仅当启用了递归触发器时,delete触发器才会 触发。
该更新挂钩,则不会调用该由REPLACE冲突解决策略删除的行。REPLACE也不会增加更改计数器。本段中定义的异常行为可能会在将来的版本中更改。
在INSERT或UPDATE的OR子句中指定的算法将覆盖在CREATE TABLE中指定的任何算法。如果未在任何地方指定算法,则使用ABORT算法。