2011-05-31 3 views
3

Je dois m'assurer qu'une valeur est unique dans deux colonnes (ce n'est pas un problème d'index "deux colonnes").Contrainte SQL pour avoir une valeur unique dans deux colonnes

Table A 
Column A1  Column A2 

Memphis   New York  -> ok 
San Francisco Miami  -> ok 
Washington  Chicago  -> ok 
Miami   Las Vegas -> Forbidden ! Miami already exists 

Est-ce possible?

Mon exemple est avec les villes mais ne focalise pas sur cela. Mon besoin réel concerne les identifiants hexadécimaux générés.

Répondre

2

Vous devez ajouter un déclencheur de contrainte qui le recherche après insertion/mise à jour.

+0

_Befor e_ insérer/mettre à jour, non? –

+0

J'utiliserais après, moi-même, puisque les déclencheurs suivants peuvent changer les valeurs de la ligne si vous utilisez un déclencheur avant. –

+0

Le déclenchement après est-il trop tard pour annuler l'opération d'insertion/mise à jour si l'unicité échoue? –

3

Dans SQL Server, il est possible d'imposer l'unicité à l'aide d'une vue indexée. Vous aurez également besoin d'une table de nombres (si vous n'en avez pas déjà) dans la même base de données que votre Table A.

Voici mon scénario de test avec quelques commentaires:

CREATE TABLE MyNumbersTable (Value int); 
-- You need at least 2 rows, by the number of columns 
-- you are going to implement uniqueness on 
INSERT INTO MyNumbersTable 
SELECT 1 UNION ALL 
SELECT 2; 
GO 
CREATE TABLE MyUniqueCities ( -- the main table 
    ID int IDENTITY, 
    City1 varchar(50) NOT NULL, 
    City2 varchar(50) NOT NULL 
); 
GO 
CREATE VIEW MyIndexedView 
WITH SCHEMABINDING -- this is required for creating an indexed view 
AS 
SELECT 
    City = CASE t.Value -- after supplying the numbers table 
    WHEN 1 THEN u.City1 -- with the necessary number of rows 
    WHEN 2 THEN u.City2 -- you can extend this CASE expression 
    END     -- to add more columns to the constraint 
FROM dbo.MyUniqueCities u 
    INNER JOIN dbo.MyNumbersTable t 
    ON t.Value BETWEEN 1 AND 2 -- change here too for more columns 
GO 
-- the first index on an indexed view *must* be unique, 
-- which suits us perfectly 
CREATE UNIQUE CLUSTERED INDEX UIX_MyIndexedView ON MyIndexedView (City) 
GO 
-- the first two rows insert fine 
INSERT INTO MyUniqueCities VALUES ('London', 'New York'); 
INSERT INTO MyUniqueCities VALUES ('Amsterdam', 'Prague'); 
-- the following insert produces an error, because of 'London' 
INSERT INTO MyUniqueCities VALUES ('Melbourne', 'London'); 
GO 
DROP VIEW MyIndexedView 
DROP TABLE MyUniqueCities 
DROP TABLE MyNumbersTable 
GO 

Lecture utile:

+0

Cette solution est-elle compatible avec 9.999.999.999.999.999 différentes valeurs? – Zofren

+0

@Zofren: Pour être honnête, je ne sais pas. –

Questions connexes