Ответ 1
Пока SQL Server не поддерживает их. В чем проблема, которую вы решаете?
Используются ли в любых версиях SQL Server отложенные ограничения (DC)?
Начиная с версии 8.0 Oracle поддерживает отложенные ограничения - ограничения, которые оцениваются только при фиксации группы операторов, а не при вставке или обновлять отдельные таблицы. Отложенные ограничения отличаются от ограничений отключения/включения, поскольку ограничения по-прежнему активны - их просто оценивают позже (когда пакет выполняется).
Преимущество DC заключается в том, что они позволяют устанавливать обновления, которые по отдельности были бы незаконными для оценки, которые могут привести к действительному состоянию завершения. Примером является создание круговых ссылок в таблице между двумя строками, где каждая строка требует наличия значения. Никакая отдельная инструкция insert не передаст ограничение - но группа может.
Чтобы прояснить мою цель, я ищу, чтобы переносить реализацию ORM в С# на SQLServer - к сожалению, реализация полагается на Oracle DC, чтобы избежать вычисления вставки/обновления/удаления заказов среди строк.
Пока SQL Server не поддерживает их. В чем проблема, которую вы решаете?
OT: Есть IMHO немало вещей, которые SQL Server не поддерживает, но имеет смысл в корпоративной среде:
Все эти мелочи делают многие из ссылочной целостности и транзакционных функций, которые вы ожидаете от полноразмерной RDBMS, почти бесполезной в SQL Server. Например, поскольку отложенные ограничения не поддерживаются, понятие "транзакция" как внешне согласованное подразделение работы частично отрицается, единственное жизнеспособное решение - за исключением некоторых грязных обходных решений - заключается в том, чтобы вообще не определять ограничения ссылочной целостности. Я бы ожидал, что естественное поведение транзакции заключается в том, что вы можете работать внутри нее в порядке и порядке операций, которые вам нравятся, и система будет следить за тем, чтобы она была согласованной в момент ее совершения. Подобные проблемы возникают из-за ограничения, что ограничение ссылочной целостности с ON DELETE CASCADE может быть определено только таким образом, что только одно ограничение может привести к каскадному удалению объекта. Это действительно не подходит для большинства реальных сценариев.
По-видимому, нет.
Я обнаружил около пяти разных сообщений в блогах, в которых говорилось, что SQLServer (в разных версиях) не поддерживает Deferrable Constraints.
С другой стороны, я также нашел сообщение, которое пытается имитировать эту функцию, используя "сохраненные вычисленные столбцы" (прокрутите до последняя запись), но caveat emptor
Похоже, что проблема заключается в том, что SQL не поддерживает то, что Date и Darwen называют "множественным назначением". Стандартным ответом SQL на это были "отложенные ограничения", которые SQL Server не поддерживает. Ограничение SQL Server FK или CHECK может быть помечено NOCHECK, но это не совсем то же самое. Подробнее см. В MSDN: ALTER TABLE (Transact-SQL).
Если у вас есть собственный уровень ORM, одним из решений вашей проблемы может быть разделение обновления объекта с помощью эталонного обновления по логике вашего уровня ORM. Затем ваш ORM будет работать с транзакциями на основе изменения клиентской стороны в несколько этапов:
Это должно решить вашу проблему, поскольку все ссылки на объекты существуют в любое время, когда установлено значение внешнего ключа...
Существует метод, позволяющий обойти отсутствующее принуждение к отложенному ограничению при определенных условиях (по состоянию на январь 2017 года в SQL Server нет поддержки отложенных ограничений). Рассмотрим следующую схему базы данных:
Отказ от ответственности: качество схемы или прецедента не обсуждается здесь, оно приводится в качестве основного примера обходного пути
CREATE TABLE T (Id TYPE NOT NULL PRIMARY KEY, NextId TYPE NOT NULL);
ALTER TABLE T WITH CHECK ADD CONSTRAINT FK_T2T
FOREIGN KEY (NextId) REFERENCES T (Id);
CREATE UNIQUE NONCLUSTERED INDEX UC_T ON T (NextId);
Где TYPE - это подходящий тип данных для суррогатного ключа. Предполагается, что значение для суррогатного ключа назначается СУРБД во время операции ВСТАВКИ (т.е. ИДЕНТИФИКАЦИЯ).
Вариант использования - сохранить "последнюю" версию объекта T с NextId = NULL и сохранить предыдущие версии, поддерживая односвязный список T.NextId → T.Id.
Очевидно, что данная схема подвержена проблеме с отсроченным ограничением, потому что вставка новой "последней" версии должна предшествовать обновлению старого "последнего", и в течение этого времени в базе данных будут две записи: то же значение NextId.
Теперь, если:
Тип данных первичного ключа не обязательно должен быть числовым и может быть рассчитан заранее (т.е. UNIQUEIDENTIFIER), то проблема с отложенным ограничением обойдется с использованием оператора MERGE, например:
DECLARE TABLE @MergeTable TABLE (Id UNIQUEIDENTIFIER);
DECLARE @NewLatestVersion UNIQUEIDENTIFIER = NEWID();
INSERT INTO @MergeTable (Id) VALUES (@NewLatestVersion);
INSERT INTO @MergeTable (Id) VALUES (@OldLatestVersion);
MERGE INTO T
USING @MergeTable m ON T.Id = m.Id
WHEN MATCHED THEN UPDATE SET T.NextId = @NewLatestVersion
WHEN NOT MATCHED THEN INSERT (Id) VALUES (@NewLatestVersion);
По-видимому, оператор MERGE завершает все манипуляции данными перед проверкой ограничений.