SQLite:防止插入重复行而不会失败

SQLite: Prevent insertion of duplicate rows without failing

我读过 ,其中建议对必要的列设置约束。但是,据我了解,如果我要插入多行,例如

insert into tableA
select *
from tableB

其中一个违反约束,整个插入操作将失败。

有没有办法避免重复,允许插入不违反约束的行,而不允许插入违反约束的行?

我的 "naive" 方法是根据我需要唯一的列在源数据和我的目标 table 之间进行内部连接,并从我的源数据中删除匹配的行,但是我我想知道是否有一种方法可以让我在目的地 table 处抛出任意数量的行,而无需添加额外的步骤。

您可以使用 INSERT INTO ... SELECT,它使用存在的逻辑来检查重复项是否已经存在:

INSERT INTO tableA (col1, col2, col3)
SELECT col1, col2, col3
FROM tableB b
WHERE NOT EXISTS (SELECT 1 FROM tableA a WHERE a.col1 = b.col1 AND a.col2 = b.col2);

这假定 "duplicate" 由两个或多个具有相同值的 col1col2 的记录确定。您可以根据需要调整此逻辑。基本思想是整个 select 应该 运行,只排除那些您知道会导致约束失败的记录。

你可以用 INSERT OR IGNORE INTO 来完成......:[=​​15=]

create table tableA(
  col1 int, 
  col2 text unique
);
insert into tableA(col1, col2) values
(1, 'a'), (2, 'b');

create table tableB(
  col1 int, 
  col2 text unique
);
insert into tableB(col1, col2) values
(1, 'a'), (2, 'b'), (3, 'c');

insert or ignore into tableA(col1, col2) 
select col1, col2 
from tableB;

select * from tableA;

参见demo
结果:

| col1 | col2 |
| ---- | ---- |
| 1    | a    |
| 2    | b    |
| 3    | c    |