2010-07-03 8 views
1

Есть ли простой способ при вставке новой записи, чтобы она не срабатывала, если одно из полей является дубликатом одного из других полей?Предотвращение дублирования в SQL-запросе?

Я не хочу, чтобы поле быть первичным ключом или что-нибудь подобное ...

+0

Помещает уникальный индекс/ограничение на поле «что-то в этом роде»? –

+2

Вы имеете в виду, что один из столбцов имеет то же значение, что и один из других столбцов в одной строке, или вы имеете в виду, что значения в столбце уникальны? –

ответ

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 между рядами будет fool any 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 
       ); 
Смежные вопросы