Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在存在唯一约束的情况下模拟UPSERT_Sql_Sqlite - Fatal编程技术网

Sql 在存在唯一约束的情况下模拟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));

模拟上塞特已经是以前的事了。但在我的例子中,我有主键和额外的唯一约束,并且我希望对主键执行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,
                   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);