Ajoutez une contrainte de contrôle comme ceci. La différence est que vous retournerez false si Status = 1 et Count > 0.
http://msdn.microsoft.com/en-us/library/ms188258.aspx
CREATE TABLE CheckConstraint
(
Id TINYINT,
Name VARCHAR(50),
RecordStatus TINYINT
)
GO
CREATE FUNCTION CheckActiveCount(
@Id INT
) RETURNS INT AS BEGIN
DECLARE @ret INT;
SELECT @ret = COUNT(*) FROM CheckConstraint WHERE Id = @Id AND RecordStatus = 1;
RETURN @ret;
END;
GO
ALTER TABLE CheckConstraint
ADD CONSTRAINT CheckActiveCountConstraint CHECK (NOT (dbo.CheckActiveCount(Id) > 1 AND RecordStatus = 1));
INSERT INTO CheckConstraint VALUES (1, 'No Problems', 2);
INSERT INTO CheckConstraint VALUES (1, 'No Problems', 2);
INSERT INTO CheckConstraint VALUES (1, 'No Problems', 2);
INSERT INTO CheckConstraint VALUES (1, 'No Problems', 1);
INSERT INTO CheckConstraint VALUES (2, 'Oh no!', 1);
INSERT INTO CheckConstraint VALUES (2, 'Oh no!', 2);
-- Msg 547, Level 16, State 0, Line 14
-- The INSERT statement conflicted with the CHECK constraint "CheckActiveCountConstraint". The conflict occurred in database "TestSchema", table "dbo.CheckConstraint".
INSERT INTO CheckConstraint VALUES (2, 'Oh no!', 1);
SELECT * FROM CheckConstraint;
-- Id Name RecordStatus
-- ---- ------------ ------------
-- 1 No Problems 2
-- 1 No Problems 2
-- 1 No Problems 2
-- 1 No Problems 1
-- 2 Oh no! 1
-- 2 Oh no! 2
ALTER TABLE CheckConstraint
DROP CONSTRAINT CheckActiveCountConstraint;
DROP FUNCTION CheckActiveCount;
DROP TABLE CheckConstraint;
1 votes
Cette conception est une douleur courante. Avez-vous envisagé de modifier la conception de sorte que les enregistrements théoriquement "supprimés" soient physiquement supprimés de la table et peut-être déplacés vers une table "d'archives" ?
1 votes
...parce que l'incapacité d'écrire une contrainte UNIQUE pour renforcer une clé simple devrait être considérée comme une "odeur de code", IMO. Si vous ne pouvez pas modifier la conception (DDL SQL) parce que de nombreuses autres tables font référence à cette table, je parie que votre DML SQL en pâtit également, c'est-à-dire que vous devez vous rappeler d'ajouter " ...AND Table.RecordStatus = 1 " à la plupart des conditions de recherche et des conditions de jointure impliquant cette table et que vous rencontrez des bogues subtils lorsque cette contrainte est inévitablement omise à l'occasion.