Sql 在存在唯一约束的情况下模拟UPSERT
模拟上塞特已经是以前的事了。但在我的例子中,我有主键和额外的唯一约束,并且我希望对主键执行upsert语义-替换现有行(如果存在),同时检查唯一约束 以下是使用插入或替换的尝试:Sql 在存在唯一约束的情况下模拟UPSERT,sql,sqlite,Sql,Sqlite,模拟上塞特已经是以前的事了。但在我的例子中,我有主键和额外的唯一约束,并且我希望对主键执行upsert语义-替换现有行(如果存在),同时检查唯一约束 以下是使用插入或替换的尝试: drop table if exists test; create table test (id INTEGER, name TEXT, s INTEGER, PRIMARY KEY (id, s), UNIQUE (name, s));
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,
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子句应用于唯一约束
create table test (id INTEGER, name TEXT,
PRIMARY KEY (id) on conflict replace,
UNIQUE (name) on conflict replace);
SQLite是一个没有客户机/服务器通信开销的嵌入式数据库,因此不需要在一条语句中尝试这样做 要模拟UPSERT,只需分别执行UPDATE/INSERT语句:
c.execute(“更新测试集s=?其中id=?和name=?,[0,1,a]”)
如果c.rowcount==0:
c、 执行(“插入测试(s,id,name)值(?,,?),[0,1,a”])
由于SQLite 3.24.0,您可以直接使用。我认为这与我的第一次尝试相当,因为“插入或替换”基本上是在每个约束上添加替换行为。当我尝试这个建议时,加上上面第一个示例中的数据,仅使用“insert”,我就替换了两个现有行。这是我现在掌握的代码,它完成了工作。尽管如此,两条语句的开销还是比一条语句大,这不是一种优雅的方法。如果使用子选择进行插入,则这不是一个选项
create table test (id INTEGER, name TEXT,
PRIMARY KEY (id) on conflict replace,
UNIQUE (name) on conflict replace);