Ваш check constraint будет выглядеть так:
ALTER TABLE dbo.[File]
ADD CONSTRAINT CHK_File__Name_Slug
CHECK ((Slug IS NULL AND Name IS NULL) OR (Name IS NOT NULL AND Slug IS NOT NULL));
-- TESTS
INSERT dbo.[File] (MimeType, Name, Slug) VALUES ('X', NULL, 'X'); -- FAIL
INSERT dbo.[File] (MimeType, Name, Slug) VALUES ('X', 'X', 'X');
INSERT dbo.[File] (MimeType, Name, Slug) VALUES ('X', 'X', NULL); -- FAIL
INSERT dbo.[File] (MimeType, Name, Slug) VALUES ('X', NULL, NULL);
EDIT
(Мой комментарий был слишком долго ...)
Я не думаю, что есть более короткий путь, и даже если бы это было только синтаксический сахар, логически была бы выполнена одна и та же проверка.
Если реальный пример намного больше столбцов, и вы действительно беспокоитесь о стоимости проверки всех столбцов, а затем создать таблицу расширений, что-то вроде:
CREATE TABLE dbo.[FileExendedProperties]
(
FileID INT NOT NULL,
Name NVARCHAR (80) NOT NULL,
Slug NVARCHAR (80) NOT NULL,
CONSTRAINT PK_FileExendedProperties__FileID PRIMARY KEY (FileID),
CONSTRAINT FK_FileExendedProperties__FileID FOREIGN KEY (FileID)
REFERENCES dbo.[File] (FileID)
);
Так как столбцы в таблице расширения не являются нулевыми, они должны либо быть не равными нулю, либо вообще не быть записью, например все столбцы будут пустыми.
в основном устанавливает ограничение на '(имя равно null) xor (slug is null)': http://stackoverflow.com/questions/5411619/t-sql-xor-operator –
Вы уверены, что MS SQL Server поддерживает xor ? Я пытался и, похоже, не поддерживал его. –
Вот почему я связался с тем, как делать xor ... –