J'ai une table de configuration dans ma base de données SQL Server et cette table ne doit avoir qu'une seule ligne. Pour aider les futurs développeurs à comprendre cela, j'aimerais empêcher l'ajout de plusieurs lignes de données. J'ai choisi d'utiliser un déclencheur pour cela, comme ci-dessous ...
ALTER TRIGGER OnlyOneConfigRow
ON [dbo].[Configuration]
INSTEAD OF INSERT
AS
BEGIN
DECLARE @HasZeroRows BIT;
SELECT @HasZeroRows = CASE
WHEN COUNT (Id) = 0 THEN 1
ELSE 0
END
FROM
[dbo].[Configuration];
IF EXISTS(SELECT [Id] FROM inserted) AND @HasZeroRows = 0
BEGIN
RAISERROR ('You should not add more than one row into the config table. ', 16, 1)
END
END
Cela ne génère pas d'erreur mais ne permet pas à la première ligne d'entrer.
Existe-t-il également un moyen plus efficace/plus explicite de limiter le nombre de lignes pouvant être insérées dans une table à seulement 1? Suis-je en train de manquer une fonctionnalité SQL Server intégrée?
Ces deux contraintes feraient:
CREATE TABLE dbo.Configuration
( ConfigurationID TINYINT NOT NULL DEFAULT 1,
-- the rest of the columns
CONSTRAINT Configuration_PK
PRIMARY KEY (ConfigurationID),
CONSTRAINT Configuration_OnlyOneRow
CHECK (ConfigurationID = 1)
) ;
Vous avez besoin à la fois du PRIMARY KEY
(ou une contrainte UNIQUE
) donc deux lignes n'ont pas la même valeur ID
et la contrainte CHECK
donc toutes les lignes ont la même valeur ID
(arbitrairement choisi pour 1
).
En combinaison, les deux contraintes presque opposées limitent le nombre de lignes à zéro ou à un.
Sur un SGBD fictif (aucune implémentation SQL actuelle ne permet cette construction) qui autorise une clé primaire composée de 0 colonnes, ce serait aussi une solution:
CREATE TABLE dbo.Configuration
( -- no ConfigurationID needed at all
-- the rest of the columns
CONSTRAINT Configuration_PK
PRIMARY KEY () -- 0 columns!
) ;
Vous pouvez définir l'ID comme une colonne calculée évaluant une valeur constante et déclarer cette colonne comme unique:
CREATE TABLE dbo.Configuration
(
ID AS CAST(1 AS tinyint), -- or: AS bit
... -- other columns
CONSTRAINT UQ_Configuration_ID UNIQUE (ID)
);
Vous pouvez également utiliser le déclencheur.
create trigger LimitTable
on YourTableToLimit
after insert
as
declare @tableCount int
select @tableCount = Count(*)
from YourTableToLimit
if @tableCount > 50
begin
rollback
end
go
Semble un peu une exigence étrange mais ho-hum :) Vous pourriez simplement avoir une contrainte sur la table et autoriser uniquement les mises à jour (pas d'insertion ou de suppression) de la table?
CREATE TABLE dbo.Config (
ID INT identity(1,1),
CONFIGURATION VARCHAR(MAX),
constraint ck_limitrows CHECK (ID <=1)
);
Cependant, c'est un peu une manière hackey de le faire, ne serait-il pas préférable d'appliquer simplement des changements à la configuration via une procédure stockée qui peut alors gérer toute cette logique pour vous?