я могу иметь уникальное ограничение на пустые поля? - PullRequest
2 голосов
/ 09 августа 2011

У меня есть таблица со следующей скешмой

CREATE TABLE MyTable  
(  
  ID                INTEGER DEFAULT(1,1),  
  FirstIdentifier   INTEGER NULL,  
  SecondIdentifier  INTEGER NULL,  
--.... some other fields .....  
) 

Теперь каждый из FirstIdentifier & SecondIdentifier является уникальным, но NULLable. Я хочу наложить уникальное ограничение на каждый из этих столбцов, но не могу этого сделать, потому что его NULLable и может иметь две строки со значениями NULL, которые не будут соответствовать этим уникальным ограничениям. Любые идеи о том, как я могу решить эту проблему на уровне схемы?

Ответы [ 5 ]

7 голосов
/ 09 августа 2011

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

create unique index ix_FirstIdentifier on MyTable(FirstIdentifier) 
  where FirstIdentifier is not null
1 голос
/ 09 августа 2011

Как полагают некоторые, использование отфильтрованных индексов - это, вероятно, способ получить то, что вы хотите.

Но ответ книги на ваш прямой вопрос состоит в том, что столбец может иметь значение NULL, если он имеет уникальный индекс, но в этом поле будет только одна строка с нулевым значением. Любое более одного нуля нарушит индекс.

0 голосов
/ 09 августа 2011

Вы можете использовать предикат Filter для CREATE INDEX

С CREATE INDEX

CREATE [UNIQUE] [CLUSTERED |NONCLUSTERED] INDEX index_nameON (столбец [ASC | DESC] [, ... n])[ВКЛЮЧИТЬ (имя столбца [, ... n])] [ГДЕ <filter_predicate>] [WITH ([, ... n])][ON {имя_раздела_символа (имя столбца)|filegroup_name|дефолт}][FILESTREAM_ON {filestream_filegroup_name |имя_раздела_схемы |"НОЛЬ" } ][;]

WHERE <filter_predicate> Создает отфильтрованный индекс, указывая, какие строки включить в индекс.Отфильтрованный индекс должен быть некластеризованным индексом в таблице.Создает отфильтрованную статистику для строк данных в отфильтрованном индексе.

Предикат фильтра использует простую логику сравнения и не может ссылаться на вычисляемый столбец, столбец UDT, столбец типа пространственных данных или столбец типа данныхierarchyID.Сравнения с использованием литералов NULL недопустимы с операторами сравнения.Вместо этого используйте операторы IS NULL и IS NOT NULL.

Вот несколько примеров предикатов фильтра для таблицы Production.BillOfMaterials:

WHERE StartDate> '20040101' AND EndDate <= '20040630'</p>

ГДЕ ComponentID IN (533, 324, 753)

ГДЕ StartDate IN ('20040404', '20040905') И EndDate NOT NULL

Фильтрованные индексы не применяютсяв XML-индексы и полнотекстовые индексы.Для уникальных индексов только выбранные строки должны иметь уникальные значения индекса.Отфильтрованные индексы не допускают использование параметра IGNORE_DUP_KEY.

0 голосов
/ 09 августа 2011

Создайте отфильтрованный уникальный индекс для полей:

CREATE UNIQUE INDEX ix_IndexName ON MyTable (FirstIdentifier, SecondIdentifier)
   WHERE FirstIdentifier IS NOT NULL
   AND SecondIdentifier IS NOT NULL

Это позволит NULL, но все же обеспечит уникальность.

0 голосов
/ 09 августа 2011

Ваш вопрос немного сбивает с толку.Во-первых, в своем определении схемы вы говорите, что ваши столбцы не могут содержать нулевые значения, но в своем описании вы говорите, что они могут быть нулевыми.

В любом случае, если у вас неверная схема и вы действительно хотите, чтобы столбцы допускали нулевые значения, SQL Server позволяет сделать это, добавив WHERE NOT NULL в ограничение.* Что-то вроде:

CREATE UNIQUE NONCLUSTERED INDEX IDX_my_index
ON MyTable (firstIdentifier)
WHERE firstIdentifier IS NOT NULL
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...