2010-07-03 138 views
1

如果其中一個字段與其他字段之一重複,插入新記錄以使其失敗時,是否有簡單的方法?防止SQL查詢中的重複項?

我不希望字段作爲主鍵或類似的東西...

+0

在字段「類似的東西」上放置一個唯一的索引/約束? – 2010-07-03 20:46:58

+2

您的意思是其中一列與同一行中的其他列之一的值相同,還是意味着該列中的值是唯一的? – 2010-07-03 20:47:40

回答

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; 
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限制放在列上。我想這與你面臨的問題很相似。

一個解決這個問題是創建這需要多個行建模兄妹基表,使用「發生」列與一個約束,以確保不能有兩個以上的兄弟姐妹(即雙胞胎):

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 
       );