在存在UNIQUE约束条件下模拟UPSERT
之前已经讨论过仿真UPSERT。 在我的情况下,我有PRIMARY KEY和额外的UNIQUE约束,并且我想要关于主键的upsert语义 - 在存在的情况下替换现有的行,同时检查唯一约束。
以下是使用插入或替换的尝试:
drop table if exists test;
create table test (id INTEGER, name TEXT, s INTEGER,
PRIMARY KEY (id, s),
UNIQUE (name, s));
insert or replace into test values (1, "a", 0);
insert or replace into test values (1, "a", 0);
insert or replace into test values (2, "b", 0);
insert or replace into test values (2, "a", 0);
最后一条语句替换了两行。 这是“插入或替换”的记录行为,但不是我想要的。
这是一个“冲突取代”的尝试:
drop table if exists test;
create table test (id INTEGER, name TEXT, s INTEGER,
PRIMARY KEY (id, s) on conflict replace,
UNIQUE (name, s));
insert into test values (1, "a", 0);
insert into test values (1, "a", 0);
我马上得到“UNIQUE约束失败”。 如果不在主键和唯一约束之间共享列,问题就会消失:
drop table if exists test;
create table test (id INTEGER, name TEXT,
PRIMARY KEY (id) on conflict replace,
UNIQUE (name));
insert into test values (1, "a");
insert into test values (1, "a");
insert into test values (2, "b");
insert into test values (2, "a");
在这里,我在最后一个陈述中违反了约束条件,这是正确的。 可悲的是,我确实需要在约束之间共享一列。
这是我不明白的关于SQL或SQLite问题,以及如何获得所需的效果,除了首先尝试插入,然后在失败时进行更新?
你可以尝试将ON CONFLICT REPLACE子句应用于UNIQUE约束吗?
create table test (id INTEGER, name TEXT,
PRIMARY KEY (id) on conflict replace,
UNIQUE (name) on conflict replace);
SQLite是一个没有客户端/服务器通信开销的嵌入式数据库,因此没有必要尝试在单个语句中执行此操作。
要模拟UPSERT,只需单独执行UPDATE / INSERT语句:
c.execute("UPDATE test SET s = ? WHERE id = ? AND name = ?", [0, 1, "a"])
if c.rowcount == 0:
c.execute("INSERT INTO test(s, id, name) VALUES (?, ?, ?)", [0, 1, "a"])
链接地址: http://www.djcxy.com/p/19795.html