Mam tabelę konfiguracji w mojej bazie danych SQL Server i ta tabela powinna mieć tylko jeden wiersz. Aby pomóc przyszłym programistom zrozumieć to, chciałbym zapobiec dodawaniu więcej niż jednego wiersza danych. Zdecydowałem się użyć do tego wyzwalacza, jak poniżej ...
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
Nie powoduje to błędu, ale nie pozwala wejść do pierwszego wiersza.
Czy istnieje też bardziej skuteczny / bardziej samoobjaśniający sposób ograniczenia liczby wierszy, które można wstawić do tabeli do 1, niż ten? Czy brakuje mi wbudowanej funkcji SQL Server?
Odpowiedzi:
Te dwa ograniczenia byłyby wystarczające:
Potrzebujesz zarówno
PRIMARY KEY
(lubUNIQUE
ograniczenia), aby żadne dwa wiersze nie miały tej samejID
wartości, aCHECK
ograniczenie, aby wszystkie wiersze miały tę samąID
wartość (dowolnie wybrane1
).W połączeniu dwa prawie przeciwne ograniczenia ograniczają liczbę wierszy do zera lub jednego.
Na fikcyjnym DBMS (żadna bieżąca implementacja SQL nie pozwala na taką konstrukcję), który pozwala na klucz podstawowy składający się z 0 kolumn, byłoby to również rozwiązanie:
źródło
Możesz zdefiniować identyfikator jako kolumnę obliczeniową, której wynikiem będzie stała wartość, i zadeklaruj tę kolumnę jako unikalną:
źródło
Możesz także użyć wyzwalacza ..
źródło
Wydaje się to trochę dziwnym wymaganiem, ale dziwne :) Możesz mieć ograniczenie na stole, a następnie zezwalać tylko na aktualizacje (bez wstawiania lub usuwania) w tabeli?
Jest to trochę hackey sposób, aby to zrobić, czy nie byłoby lepiej po prostu wymusić zmiany w konfiguracji za pomocą procedury składowanej, która może następnie obsłużyć całą tę logikę?
źródło
ID
posiadania wartości0
ujemnej. A jak wskazuje @Mat, nie powiedzie się, jeśli spróbujesz wstawić kolejny wiersz, jeśli pierwszy zostanie usunięty.INSERT INTO dbo.Config DEFAULT VALUES;
Tylko raz, ale możesz śledzić toSET IDENTITY_INSERT dbo.Config ON; INSERT INTO dbo.Config (ID) VALUES (0); SET IDENTITY_INSERT dbo.Config OFF;
wiele razy, a skończysz na tabeli z wieloma wierszami.