Проверьте ограничение - подзапросы не разрешены в этом контексте - PullRequest
7 голосов
/ 15 марта 2012

Я попытался добавить Проверка ограничения , и пока мне не удалось.Как можно обойти это:

Сообщение 1046, Уровень 15, Состояние 1, Строка 6

Подзапросы в этом контексте не разрешены.Допускаются только скалярные выражения.

Это код:

ALTER TABLE dbo.PropertySeasonDiscount ADD CONSTRAINT
[CC_PropertySeasonDiscount_MadeFrom_MadeTo]
CHECK (
    (SELECT COUNT(PropertySeasonDiscountId) FROM dbo.PropertySeasonDiscounts apsdeb 
        WHERE 
            (apsdeb.PropertySeasonId = PropertySeasonId) AND
            (
                (apsdeb.ValidForReservationsMadeTo >= ValidForReservationsMadeFrom AND ValidForReservationsMadeFrom >= apsdeb.ValidForReservationsMadeFrom) OR
                (apsdeb.ValidForReservationsMadeFrom <= ValidForReservationsMadeTo AND ValidForReservationsMadeTo <= apsdeb.ValidForReservationsMadeTo)
            )
    ) = 0
);

Ответы [ 2 ]

11 голосов
/ 15 марта 2012

SQL Server в настоящее время не поддерживает подзапросы для CHECK CONSTRAINTs .

Как вы обнаружили, могут возникнуть проблемы с ограничениями CHECK , в которых используются UDF при попытке обойти ограничение подзапроса.

Альтернативные стратегии реализации ограничения: инициируемые процедурные и встроенные процедурные . Первое предпочтительнее, поскольку, как и декларативные ограничения, их нельзя обойти.

Реализация триггерной процедурной стратегии, которая хорошо оптимизирована и решает проблемы параллелизма, является нетривиальной, но все же выполнимой. Я настоятельно рекомендую книгу Прикладная математика для специалистов по базам данных. Лекс де Хаан, Тун Коппелаарс , глава 11 (примеры кода - Oracle, но их легко перенести на SQL Server).

3 голосов
/ 16 марта 2012

Как уже упоминалось другими, этот тип проверочных ограничений еще не реализован в SQL-сервере.Помимо триггеров, вы также можете изучить возможность изменения дизайна таблицы.

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

Другая возможность - хранить не одну строку (с начальной и конечнойдата) для скидки, как вы делаете сейчас, но целый ряд строк (по одной на каждую дату интервала скидки).Принудительные ограничения будут еще проще, но у вас будет много строк вместо каждой вашей текущей таблицы.

...