SQL:有没有办法阻止一个表中存在的两个相同的行

SQL:有没有办法阻止一个表中存在的两个相同的行,sql,sqlite,Sql,Sqlite,因此,在创建表时,我想添加一个条件,以确保两行不完全相同,而不考虑ID。因此,一个或多个列可以相同,但不能是整行。这可能吗?理想情况下,如果有一种方法在SQLite中工作,我希望使用这种方法 非常感谢。为表中所有列添加唯一索引: CREATE UNIQUE INDEX idx ON yourTable (col1, col2, ..., colN); -- assuming N columns 有了此索引,任何插入一条记录的尝试都将失败,因为该记录的所有值都与表中已有的记录匹配。如果表的主键以

因此,在创建表时,我想添加一个条件,以确保两行不完全相同,而不考虑ID。因此,一个或多个列可以相同,但不能是整行。这可能吗?理想情况下,如果有一种方法在SQLite中工作,我希望使用这种方法


非常感谢。

为表中所有列添加唯一索引:

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;