СУБД: MS Sql Server 2005, Standard
Я бы хотел сделать ограничение таблицы, чтобы только одна запись имела определенное значение в подмножестве таблицы (где строки разделяют значение в определенном столбце). Возможно ли это?
Пример:
У меня есть записи в myTable, которые имеют неуникальный внешний ключ (fk1) и битовый столбец с именем isPrimary, чтобы отметить, что этот конкретный должен использоваться нашим приложением для специальной логики.
в аннотации это выглядит так:
myTable
-------------
pk1 (int, not null)
name (varchar(50), null)
fk1 (int, not null)
isPrimary (bit, not null)
Я хочу убедиться, что существует одна и только одна запись с флагом isPrimary, установленным в 1, для каждого уникального значения fk1.
Пример данных:
Это должно быть законно:
pk1 name fk1 isPrimary
---- ----- ----- ----------
1 Bill 111 1
2 Tom 111 0
3 Dick 222 1
4 Harry 222 0
Но это должно быть , а не (более одного, где fk = 111):
pk1 name fk1 isPrimary
---- ----- ----- ----------
1 Bill 111 1
2 Tom 111 1
3 Dick 222 1
4 Harry 222 0
И это тоже не должно (ни где fk = 222):
pk1 name fk1 isPrimary
---- ----- ----- ----------
1 Bill 111 1
2 Tom 111 0
3 Dick 222 0
4 Harry 222 0
Есть ли способ сделать это с помощью ограничения таблицы?
UPDATE
Я согласился с ответом Мартина Смита, хотя я буду настаивать на рефакторе JohnFx в следующем выпуске, так как это лучшее долгосрочное решение. Однако я хотел опубликовать свой обновленный UDF, основываясь на ответе Raze2dust, на случай, если будущие читатели решат, что он лучше соответствует их потребностям.
CREATE FUNCTION [dbo].[OneIsPrimaryPerFK1](@fk1 INT, @dummyIsPrimary BIT)
RETURNS INT
AS
BEGIN
DECLARE @retval INT;
DECLARE @primarySum INT;
SET @retval = 0;
DECLARE @TempTable TABLE (
fk1 INT,
PrimarySum INT)
INSERT INTO @TempTable
SELECT fk1, SUM(CAST(isPrimary AS INT)) AS PrimarySum
FROM FacAdmin
WHERE fk1 = @fk1
GROUP BY fk1;
SELECT @primarySum = PrimarySum FROM @TempTable;
IF(@primarySum=1)
BEGIN
SET @retval = 1
END
RETURN @retval
END;
Изменения:
- Используется @tempTable вместо
tempTable (в памяти v. Записано на диск) в соответствии с требованиями udf
- передал @ fk1 в качестве параметра, чтобы я мог выбрать уникальность в пределах одного
группа значений fk1.
- хитрый должен был также передать isPrimary, хотя это не так
необходимо для логики
функция, иначе SQL2005
оптимизатор не запускает проверку
ограничение, когда isPrimary
обновлен.