Проверка Ограничения работают только в одной строке, но вы можете использовать скалярные UDF в пределах ограничения.
Вы можете нарушить однострочную проверку, используя UDF, которые проверяют другие строки в таблице.Хотя в отличие от триггера, в котором вы можете получить доступ к виртуальной таблице DELETED и обрабатывать ее по отдельности, SQL Server, похоже, хранит записи в виде транзакции и выполняет CHECK для каждой строки после изменения, а затем, наконец, принимает или прерывает CRUD в пакете.
См. Этот контрольный пример
Создать таблицу
create table usertable (UserId int,
CompanyId int, IsPrimaryUser int)
Заполнить
insert usertable select
1, 1, 1 union all select
2, 1, 0 union all select
3, 1, 0 union all select
4, 1, 0 union all select
5, 2, 1 union all select
6, 2, 0 union all select
7, 2, 0 union all select
8, 2, 0
Помощник скалярной функции
create function dbo.anyprimaryuser(@userid int, @company int) returns bit as
begin
return
case when exists (
select * from usertable
where companyid=@company and isprimaryuser=1 and userid<>@userid)
then 1 else 0 end
end
ПРОВЕРЬТЕ ограничение
alter table usertable add constraint usertable_ck1
check (isprimaryuser=0 or dbo.anyprimaryuser(userid,companyid)=0)
Тесты
insert usertable select 9,2,1 -- fail
insert usertable select 9,2,0 -- ok
insert usertable select 19,4,1 union all select 20,4,0 -- ok
insert usertable select 19,3,1 union all select 20,3,0 union all select 21,3,1
-- not ok, accepting the multi-row insert will breach the constraint
update usertable set IsPrimaryUser=1-IsPrimaryUser where CompanyId=4
-- ok! sets one and unsets the other in one go
(примечание) Я обновил ответ после комментария Мартина ниже