案例 1 没有失败,因为 NULL(NULL 被认为与所有其他 NULL 不同)它失败了,因为已经有一行具有 execute 在access_type 列。
即消息告诉您失败(发生冲突)的唯一约束是 access_type 列。
案例 2 同样失败,因为 id 列中有另一行有 3。
也许考虑以下(注意 DROP TABLE 以便它可以重新运行):-
DROP TABLE IF EXISTS access_type;
CREATE TABLE IF NOT EXISTS access_type(
id NUMBER NOT NULL PRIMARY KEY,
access_type VARCHAR(10) UNIQUE,
access_value VARCHAR(2) UNIQUE
);
insert into access_type (id,access_type,access_value) values (3,'execute',NULL);
insert into access_type (id,access_type,access_value) values (4,NULL,'E');
insert into access_type (id,access_type,access_value) values (5,NULL,NULL);
运行时消息是:-
insert into access_type (id,access_type,access_value) values (3,'execute',NULL)
> Affected rows: 1
> Time: 0.091s
-- insert into access_type (id,access_type,access_value) values (3,NULL,'E'); /* fails because id 3 has been used */
insert into access_type (id,access_type,access_value) values (4,NULL,'E')
> Affected rows: 1
> Time: 0.095s
insert into access_type (id,access_type,access_value) values (5,NULL,NULL)
> Affected rows: 1
> Time: 0.107s
您可能想回顾一下 UNIQUE 的用法,因为您要强加一组非常严格的术语。猜测您可能希望将许多行作为 access_type 执行,并且您可能想要相同的 access_value。您可能不想要的是相同的 id 和 access_type 和/或相同的 access_value。
因此,您可能希望 ID 3 的访问类型为 exceute,而 ID 3 也有一行用于 noop 类型。然后,您可能需要复合 PRIMARY KEY 或 UNIQUE 索引。
例如考虑以下改编:-
DROP TABLE IF EXISTS access_type;
CREATE TABLE IF NOT EXISTS access_type(
id NUMBER NOT NULL /* PRIMARY KEY */ /* PRIMARY KEY IMPLIES UNIQUE */,
access_type VARCHAR(10) /* UNIQUE */,
access_value VARCHAR(2) /* UNIQUE */ , /*<<<<< added comma */
PRIMARY KEY (id,access_type) /*<<<<< compound PRIMARY KEY */
);
insert into access_type (id,access_type,access_value) values (3,'execute',NULL);
insert into access_type (id,access_type,access_value) values (3,'noop',NULL);
insert into access_type (id,access_type,access_value) values (4,NULL,'E');
insert into access_type (id,access_type,access_value) values (5,NULL,NULL);
但是,如果尝试了insert into access_type (id,access_type,access_value) values (3,'execute',NULL);,那么它会失败。
您可能还想考虑 INSERT OR IGNORE 在这种情况下,UNIQUE 约束冲突将是 NOOP 而不是失败。