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:
_Befor e_ insérer/mettre à jour, non? –
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. –
Le déclenchement après est-il trop tard pour annuler l'opération d'insertion/mise à jour si l'unicité échoue? –