2010-07-03 6 views
1

Existe-t-il un moyen facile lors de l'insertion d'un nouvel enregistrement de le faire échouer si l'un des champs est un doublon de l'un des autres champs?Empêcher les doublons dans une requête SQL?

Je veux ne pas le champ à une clé primaire ou quelque chose comme ça ...

+0

met un index unique/contrainte sur le champ « quelque chose comme ça »? –

+2

Voulez-vous dire qu'une des colonnes a la même valeur que l'une des autres colonnes de la même ligne, ou voulez-vous dire que les valeurs de la colonne sont uniques? –

Répondre

0

Comme cela a été dit par hgulyan, si vous voulez un table.col1 soit unique, ajouter une contrainte unique sur la colonne. Si vous voulez dire que vous voulez que l'insertion échoue si la colonne table1.col1 = table1.col2, vous pouvez l'implémenter dans un déclencheur. Voir MYSQL Create Trigger.

Pour soulever une exception dans la gâchette, de sorte que l'insert échoue, voir TRIGGERs that cause INSERTs to fail? Possible?

Quelque chose comme:

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

Voici standard SQL, plutôt que le dialecte mySQL, mais mySQL est a une bon niveau de conformité à la norme et j'espère que vous serez en mesure de suivre mon point de vue.

Vous ne pouvez pas poster votre schéma ou des données d'échantillon, donc je devais deviner ce que vos tables pourraient ressembler à:

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 

Cette dernière INSERT réussit même si elle devrait ne pas transposer à-dire les valeurs child_id entre les lignes seront tromper toute contrainte UNIQUE que vous voulez mettre sur les colonnes. Je suppose que c'est semblable au problème auquel vous faites face.

Une solution à ce problème est de créer une table de base qui nécessite plusieurs lignes pour modéliser les frères et sœurs, en utilisant une colonne « occurrence » avec une contrainte pour assurer qu'il ne peut y avoir plus de deux frères et sœurs (c.-à-jumeaux):

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

Vous pouvez ensuite recréer la structure de données de votre ancienne table de base à l'aide d'un VIEW par exemple.

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