74

我正在尝试将数据插入表中。如果该列还没有数据,我想插入该行 - 无论其他列如何。

CREATE TABLE t (
    id          INTEGER PRIMARY KEY,
    name        VARCHAR,
    other       INT
);
INSERT OR IGNORE INTO t (name) VALUES ('a');
INSERT OR IGNORE INTO t (name) VALUES ('a');
INSERT OR IGNORE INTO t (name) VALUES ('a');

使用上面的代码段,我最终得到 3 行,而不是我想象的 1 行。如果实际的 sql 发生在INSTEAD OF INSERT触发器内部很重要,那么这只是一个简单的测试用例。

4

2 回答 2

124

代替

CREATE TABLE t (
    id          INTEGER PRIMARY KEY,
    name        VARCHAR,
    other       INT
);

CREATE TABLE t (
    id          INTEGER PRIMARY KEY,
    name        VARCHAR UNIQUE,
    other       INT
);

然后你会得到

sqlite> CREATE TABLE t (
   ...>     id          INTEGER PRIMARY KEY,
   ...>     name        VARCHAR UNIQUE,
   ...>     other       INT
   ...> );
sqlite> INSERT OR IGNORE INTO t (name) VALUES ('a');
sqlite> INSERT OR IGNORE INTO t (name) VALUES ('a');
sqlite> INSERT OR IGNORE INTO t (name) VALUES ('a');
sqlite> select * from t ;
1|a|
于 2012-08-24T07:58:51.240 回答
23

这仅适用于主键字段或唯一约束:

可选的冲突子句允许在这个INSERT命令期间使用替代约束冲突解决算法的规范。

更远:

ON CONFLICT子句适用于 UNIQUE 和 NOT NULL 约束(以及在本节中与 UNIQUE 约束相同的 PRIMARY KEY 约束)。ON CONFLICT 算法不适用于 FOREIGN KEY 约束。有五种冲突解决算法选择:ROLLBACK、ABORT、FAIL、IGNORE 和 REPLACE。默认的冲突解决算法是 ABORT。

于 2012-08-24T07:59:55.763 回答