SQLite,根据联合子查询的结果插入或忽略
Posted
技术标签:
【中文标题】SQLite,根据联合子查询的结果插入或忽略【英文标题】:SQLite, insert or ignore based on result of a union subquery 【发布时间】:2021-03-14 19:04:49 【问题描述】:INSERT INTO table (field1, field2, field3, field4) VALUES (@field1, @field2, @field3, @field4)
WHERE NOT EXISTS
(
SELECT 1 FROM table WHERE field1 = @field1 AND field2 = @field2
UNION
SELECT 1 FROM table WHERE field1 = @field2 AND field2 = @field1
);
上面的代码不起作用。
当我在数据库中有条目时:
'黑色''羊''吃''草'
我尝试插入新条目,例如:
'羊' '黑色' '吃''草'
或者像这样的条目:
'黑色' '羊'' '吃' '西瓜'
我不想让任何东西进入数据库。
【问题讨论】:
【参考方案1】:如果您想要 WHERE
子句,则必须使用 INSERT ... SELECT
。
你也可以通过避免UNION
来简化WHERE
子句:
INSERT INTO table (field1, field2, field3, field4)
SELECT @field1, @field2, @field3, @field4
WHERE NOT EXISTS (
SELECT 1 FROM table
WHERE (field1, field2) = (@field1, @field2)
OR (field1, field2) = (@field2, @field1)
)
如果您的 SQLite 版本是 3.31.0+,最好创建 GENERATED
列,您可以在其基础上设置 UNIQUE
约束:
CREATE TABLE tablename(
field1 text,
field2 text,
field3 text,
field4 text,
un_min text GENERATED ALWAYS AS (MIN(field1, field2)),
un_max text GENERATED ALWAYS AS (MAX(field1, field2)),
UNIQUE(un_min, un_max)
);
现在您可以使用 INSERT OR IGNORE 插入新行:
INSERT OR IGNORE INTO table (field1, field2, field3, field4) VALUES (@field1, @field2, @field3, @field4);
不幸的是,SQLite 不允许向现有表添加约束。 您必须重新创建表(您可以在此处找到有关如何执行此操作的说明:ALTER TABLE 或此处:SQLite ALTER TABLE)
【讨论】:
非常感谢!事实证明,这相当缓慢。我想我应该为此创建一个唯一索引,例如有black+sheep+sheep+black 转成md5什么的 你的 SQLite 版本是多少? 1.0.113。用这种方式插入 30k 条记录大约需要一分钟 @NickFarsi 不,这不是 SQLite 的版本。执行SELECT sqlite_version()
。如果它是 3.31.0,那么有一个解决方案可以生成列来创建唯一约束。
@NickFarsi 查看我编辑的答案。如果可以重新创建表,最好使用唯一约束。以上是关于SQLite,根据联合子查询的结果插入或忽略的主要内容,如果未能解决你的问题,请参考以下文章