【问题标题】:SQLite, insert or ignore based on result of a union subquerySQLite,根据联合子查询的结果插入或忽略
【发布时间】: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
);

上面的代码不起作用。

当我在数据库中有条目时:

'黑色''羊''吃''草'

我尝试插入新条目,例如:

'羊' '黑色' '吃''草'

或者像这样的条目:

'黑色' '羊'' '吃' '西瓜'

我不想让任何东西进入数据库。

【问题讨论】:

    标签: sql sqlite insert union exists


    【解决方案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 查看我编辑的答案。如果可以重新创建表,最好使用唯一约束。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-22
    • 1970-01-01
    • 1970-01-01
    • 2023-02-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多