SQLite,根据联合子查询的结果插入或忽略

SQLite, insert or ignore based on result of a union subquery

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
);

以上代码无效。

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

'黑色' '绵羊' 'eats' 'grass'

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

'sheep' 'black' 'eats' 'grass'

或条目如下:

'black' 'sheep'' 'eats' 'watermelon'

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

如果需要 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 不允许向现有 table 添加约束。
您必须重新创建 table(您可以在此处找到有关如何操作的说明:ALTER TABLE or here: SQLite ALTER TABLE