我有一个带有两个约束的SQLite表:
CREATE TABLE t (a INTEGER, b INTEGER, c INTEGER,
UNIQUE (b, c), PRIMARY KEY (a, c));
我想做一个INSERT
,它会忽略违反(a, c)
约束的记录,即使也违反了(b, c)
约束,但是如果 only 就会失败违反了(b, c)
约束。
换句话说,如果我从这里开始:
INSERT INTO t (a, b, c) VALUES (1, 2, 3);
这应该不做任何事情:
INSERT INTO t (a, b, c) VALUES (1, 2, 3);
但这应该是一个错误:
INSERT INTO t (a, b, c) VALUES (4, 2, 3);
如果我尝试使用相对较新的类似PostgreSQL的UPSERT语法来做到这一点:
INSERT INTO t (a, b, c) VALUES (1, 2, 3) ON CONFLICT (a, c) DO NOTHING;
它使用SQLite 3.26完成了我想要的操作 ,但是由于在SQLite 3.24上违反了(b, c
)约束,因此失败了,而changelog看起来像是是偶然的,而不是表明我想要的行为得到保证。
如果我在定义约束时设置冲突解决方案,
CREATE TABLE t (a INTEGER, b INTEGER, c INTEGER,
UNIQUE (b, c), PRIMARY KEY (a, c) ON CONFLICT IGNORE);
然后我得到了两个版本都想要的行为(良好),但是我想知道我是否仍然依赖未定义的行为(不良)。
换句话说,如果违反了多个约束但具有不同的(显式或隐式)冲突处理,是否可以保证行为会发生什么?
FWIW,冲突解决顺序似乎与定义约束的顺序无关-在上述两种情况下,交换约束定义顺序都不会改变行为。