Ограничение T-SQL для проверки, является ли значение либо 0, либо уникальным

#sql #sql-server #tsql #constraints #ddl

#sql #sql-server #tsql #ограничения #ddl

Вопрос:

Я разрабатываю базу данных, в которой сотрудники должны быть активированы администратором. Когда регистрируется новый сотрудник, для его рабочей станции (int) по умолчанию устанавливается значение 0. Однако я также не могу разрешить иметь более 1 сотрудника на рабочую станцию. Итак, я подумал, есть ли способ разрешить дублирование значения 0, но обеспечить, чтобы любое другое число было уникальным.

Ответ №1:

Вы можете использовать частичный уникальный индекс. Например:

 create unique index ix1 on employees (workstation) where workstation <> 0;
  

Как в:

 create table employees (
  id int, 
  name varchar(10), 
  workstation int not null
);

create unique index ix1 on employees (workstation) where workstation <> 0;

insert into employees (id, name, workstation) values (1, 'Anne', 100);

insert into employees (id, name, workstation) values (2, 'Peter', 101);

insert into employees (id, name, workstation) values (3, 'Joel', 100); -- fails

insert into employees (id, name, workstation) values (4, 'Niko', 0);

insert into employees (id, name, workstation) values (5, 'Akina', 0); -- succeeds
  

Это одно из ограничений, которые вы не можете применить с помощью традиционных ограничений.

Смотрите пример выполнения в db<>fiddle. Как вы видите, отклоняется только Joel, 100 . Вставлены два других случая с workstation = 0.

Комментарии:

1. Да, это называется отфильтрованным индексом и является необходимым, поскольку это один из редких сценариев, когда SQL Server отклоняется от стандарта и обрабатывает два отдельных нуля как равные.

2. @AaronBertrand . . . Я бы не сказал «один из редких сценариев»: вместо || , нет поддержки null безопасных сравнений, нет полной поддержки range оконных фреймов, использование = в качестве оператора присваивания для псевдонимов столбцов, отсутствие поддержки extract() и кучи других «стандартных» функций, требование offset with fetch . . . Я мог бы продолжать. Моя точка зрения заключается не в том, чтобы на самом деле выбирать SQL Server, но я бы не назвал NULL обработку редким примером. 😉

3. @Gordon Я имел в виду редкий сценарий, когда он обрабатывает нули нестандартным способом, а не редкий сценарий, когда он нарушает стандарт. Многие проприетарные материалы могут быть полезными, и ни одна СУБД не соответствует требованиям на 100%. Если бы все они были совместимыми и только совместимыми, они все были бы одинаковыми. 🙂