Q: Нужно ли отключать ограничения для вставки?
A: В Oracle нет, нет, если ограничения внешнего ключа DEFERRABLE
(см. Пример ниже)
Для Oracle:
SET CONSTRAINTS ALL DEFERRED;
INSERT INTO Departments values ('foo','dummy');
INSERT INTO Employees values ('bar','foo');
UPDATE Departments SET EmployeeID = 'bar' WHERE DepartmentID = 'foo';
COMMIT;
Давайте распакуем это:
- (автокоммит должен быть выключен)
- отсрочить применение ограничения внешнего ключа
- вставить строку в таблицу Department с помощью фиктивного значения для столбца FK
- вставить строку в таблицу Employee с указанием FK для Отдела
- заменить "фиктивное" значение в отделе ФК на реальную ссылку
- повторно включить применение ограничений
ПРИМЕЧАНИЯ: отключение ограничения внешнего ключа вступает в силу для ВСЕХ сеансов, ОТСУТСТВУЯ ограничение на уровне транзакции (как в примере) или на уровне сеанса (ALTER SESSION SET CONSTRAINTS=DEFERRED;
)
Oracle допускает, чтобы ограничения внешнего ключа определялись как DEFERRABLE, по крайней мере, в течение десятилетия. Я определяю все ограничения внешнего ключа (как само собой разумеющееся) как ЗАДЕРЖАЕМЫЕ ПЕРВОНАЧАЛЬНО НЕМЕДЛЕННЫЕ. Это сохраняет поведение по умолчанию, как все ожидают, но позволяет манипулировать, не требуя отключения внешних ключей.
см. AskTom: http://www.oracle.com/technology/oramag/oracle/03-nov/o63asktom.html
см. AskTom: http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:10954765239682
см. Также: http://www.idevelopment.info/data/Oracle/DBA_tips/Database_Administration/DBA_12.shtml
[РЕДАКТИРОВАТЬ]
A: В Microsoft SQL Server вы не можете отложить ограничения внешнего ключа, как в Oracle. Отключение и повторное включение ограничения внешнего ключа является подходом, но я вздрагиваю от перспективы 1) влияния на производительность (ограничение внешнего ключа проверяется для таблицы ENTIRE при повторном включении ограничения), 2) обработка исключения, если (когда?) повторное включение ограничения не выполняется. Обратите внимание, что отключение ограничения повлияет на все сеансы, поэтому, пока ограничение отключено, другие сеансы могут потенциально вставлять и обновлять строки, что приведет к сбою повторного включения ограничения.
В SQL Server лучшим подходом является удаление ограничения NOT NULL и использование NULL в качестве временного заполнителя при вставке / обновлении строк.
Для SQL Server:
-- (with NOT NULL constraint removed from Departments.EmployeeID)
insert into Departments values ('foo',NULL)
go
insert into Employees values ('bar','foo')
go
update Departments set EmployeeID = 'bar' where DepartmentID = 'foo'
go
[/ EDIT]