防止SQL查询中的重复项?

时间:2010-07-03 20:41:23

标签: sql mysql

如果其中一个字段与其他字段之一重复,插入新记录是否有一种简单的方法可以使其失败?

我不希望该字段成为主键或类似的东西......

3 个答案:

答案 0 :(得分:9)

将列设置为唯一

更多关于此

http://php.about.com/od/mysqlcommands/g/add_unique.htm

答案 1 :(得分:0)

正如hgulyan所说,如果你想让table.col1独一无二,那就在列上添加一个唯一约束。

如果您希望插入失败,如果列table1.col1 = table1.col2,那么您可以在触发器中实现此功能。请参阅MYSQL Create Trigger

要在触发器中引发异常,以便插入失败,请参阅TRIGGERs that cause INSERTs to fail? Possible?

类似的东西:

CREATE TRIGGER Employee_beforeinsert before insert
ON Employee FOR EACH ROW
    BEGIN
    IF new.age = new.age2 THEN
        DECLARE dummy INT;

        SELECT 'Your meaningful error message goes here' INTO dummy 
        FROM Employee
        WHERE Employee.id=new.id
    END IF;
END;

答案 2 :(得分:0)

以下是标准SQL,而不是mySQL方言,但mySQL与标准的合规程度很高,我相信你应该能够遵循我的观点。

您没有发布架构或示例数据,因此我不得不猜测您的表格可能是什么样的:

CREATE TABLE Mothers
(
 mother_ID INTEGER NOT NULL UNIQUE
);

CREATE TABLE Children
(
 child_ID INTEGER NOT NULL UNIQUE
);

CREATE TABLE MothersOfTwins
(
 mother_ID INTEGER NOT NULL 
    UNIQUE REFERENCES Mothers (mother_ID), 
 twin_1_child_ID INTEGER 
    REFERENCES Children (child_ID), 
 twin_2_child_ID INTEGER 
    REFERENCES Children (child_ID), 
 CHECK (twin_1_child_ID <> twin_2_child_ID)
);

INSERT INTO Mothers (mother_ID) VALUES (101), (102), (103);

INSERT INTO Children (child_ID) VALUES (551), (552), (553), (554);

INSERT INTO MothersOfTwins (mother_ID, twin_1_child_ID, twin_2_child_ID) 
VALUES 
(101, 551, 552), 
(102, 552, 551);  -- duplicate

最后INSERT成功即使它应该失败,即在行之间转换child_ID值会欺骗你想要放在列上的任何UNIQUE约束。我想这与您面临的问题类似。

这个问题的一个解决方案是创建一个基表,它需要多行来模拟兄弟,使用带有约束的'occurrence'列来确保不能有两个以上的兄弟(即双胞胎):

DROP TABLE MothersOfTwins;

CREATE TABLE MothersOfTwinsBase
(
 mother_ID INTEGER NOT NULL
    REFERENCES Mothers (mother_ID), 
 twin_occurrence INTEGER NOT NULL
    CHECK (twin_occurrence BETWEEN 1 AND 2), 
 twin_child_ID INTEGER NOT NULL UNIQUE 
    REFERENCES Children (child_ID), 
 UNIQUE (mother_ID, twin_occurrence)
);

INSERT INTO MothersOfTwinsBase (mother_ID, twin_occurrence, twin_child_ID) 
VALUES 
(101, 1, 551), 
(101, 2, 552),
(102, 1, 553),
(103, 2, 554);

然后,您可以使用VIEW重新创建以前的基表的数据结构,例如

CREATE VIEW MothersOfTwins
(
 mother_ID, 
 twin_1_child_ID, twin_2_child_ID
)
AS
SELECT M1.mother_ID, 
       M1.twin_child_ID AS twin_1_child_ID, 
       M2.twin_child_ID AS twin_2_child_ID
  FROM MothersOfTwinsBase AS M1 
       INNER JOIN MothersOfTwinsBase AS M2
          ON M1.mother_ID = M2.mother_ID
             AND M1.twin_occurrence = 1
             AND M2.twin_occurrence = 2
UNION ALL
SELECT M1.mother_ID, 
       M1.twin_child_ID AS twin_1_child_ID, 
       NULL AS twin_2_child_ID
  FROM MothersOfTwinsBase AS M1 
 WHERE NOT EXISTS (
                   SELECT *
                     FROM MothersOfTwinsBase AS M2
                          WHERE M1.mother_ID = M2.mother_ID
                                AND M2.twin_occurrence = 2
                  )
UNION ALL
SELECT M2.mother_ID, 
       NULL AS twin_1_child_ID, 
       M2.twin_child_ID AS twin_2_child_ID
  FROM MothersOfTwinsBase AS M2
 WHERE NOT EXISTS (
                   SELECT *
                     FROM MothersOfTwinsBase AS M1
                          WHERE M1.mother_ID = M2.mother_ID
                                AND M1.twin_occurrence = 1
                  );