SQL:有没有办法阻止一个表中存在的两个相同的行
因此,在创建表时,我想添加一个条件,以确保两行不完全相同,而不考虑ID。因此,一个或多个列可以相同,但不能是整行。这可能吗?理想情况下,如果有一种方法在SQLite中工作,我希望使用这种方法SQL:有没有办法阻止一个表中存在的两个相同的行,sql,sqlite,Sql,Sqlite,因此,在创建表时,我想添加一个条件,以确保两行不完全相同,而不考虑ID。因此,一个或多个列可以相同,但不能是整行。这可能吗?理想情况下,如果有一种方法在SQLite中工作,我希望使用这种方法 非常感谢。为表中所有列添加唯一索引: CREATE UNIQUE INDEX idx ON yourTable (col1, col2, ..., colN); -- assuming N columns 有了此索引,任何插入一条记录的尝试都将失败,因为该记录的所有值都与表中已有的记录匹配。如果表的主键以
非常感谢。为表中所有列添加唯一索引:
CREATE UNIQUE INDEX idx ON yourTable (col1, col2, ..., colN); -- assuming N columns
有了此索引,任何插入一条记录的尝试都将失败,因为该记录的所有值都与表中已有的记录匹配。如果表的主键以外的所有列都被定义为非空,则所有列上都会有一个唯一的约束:
CREATE TABLE tablename (
id INTEGER PRIMARY KEY,
col1 TEXT NOT NULL,
col2 TEXT NOT NULL,
col3 TEXT NOT NULL,
UNIQUE(col1, col2, col3)
);
足以保证所有行都是唯一的
但是对于这样的桌子:
CREATE TABLE tablename (
id INTEGER PRIMARY KEY,
col1 TEXT,
col2 TEXT,
col3 TEXT
);
“唯一”约束不会捕获以下两行:
id col1 col2 col3
--------------------
1 a b null
2 a b null
因为空值被认为是不相等的
您需要的是两个触发器,一个在插入之前,另一个在更新之前:
通过使用运算符IS而不是=可以将null匹配为相等。
这些触发器将引发一个错误消息:“行已存在”,并在新/更新的行与现有行匹配时中止操作。虽然唯一索引肯定会执行此操作,但通常您定义一个唯一约束,例如约束唯一col1、col2、col3。。。作为表定义的一部分。@TheImpler。我不会说一种方法比另一种更常用。它们的实现方式相同。约束的优点是可以为约束命名。但是,同样,索引的优点是您可以为索引指定一个名称。如果列中有空值,则约束和索引都不起作用,因为空值不被视为彼此相等。注意,SQLite认为行null、null和null、null是不同的。
CREATE TRIGGER unique_row_tablename_insert BEFORE INSERT ON tablename
BEGIN
SELECT
CASE WHEN EXISTS (
SELECT 1 FROM tablename t
WHERE t.col1 IS NEW.col1 AND t.col2 IS NEW.col2 AND t.col3 IS NEW.col3
) THEN RAISE (ABORT, 'The row already exists')
END;
END;
CREATE TRIGGER unique_row_tablename_update BEFORE UPDATE ON tablename
BEGIN
SELECT
CASE WHEN EXISTS (
SELECT 1 FROM tablename t
WHERE t.id <> NEW.id AND t.col1 IS NEW.col1 AND t.col2 IS NEW.col2 AND t.col3 IS NEW.col3
) THEN RAISE (ABORT, 'The row already exists')
END;
END;