Q: ¿Debo desactivar las restricciones para que la inserción ocurra?
A: En Oracle, no hay ni siquiera si las restricciones de claves foráneas son DEFERRABLE
(ver ejemplo a continuación)
Para 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;
vamos a descomprimir que:
- (autocommit debe estar desactivado)
- aplazar la aplicación de la restricción de clave externa
- insertar una fila a la tabla Departamento con un valor de "prueba" para la columna FK
- insertar una fila de tabla de empleados con referencia FK al Departamento
- sustituir el valor "ficticio" en el Departamento de FK con referencia verdadera
- volver a habilitar la aplicación de las restricciones
NOTAS: la desactivación de una restricción de clave externa entra en vigor para todas las sesiones, difiriendo una restricción está en un nivel de transacción (como en el ejemplo), o en el nivel de sesión (ALTER SESSION SET CONSTRAINTS=DEFERRED;
)
Oracle ha permitido que las restricciones de clave externa se definan como DEFERRABLE durante al menos una década. Defino todas las restricciones de clave externa (como una cuestión de rutina) para ser DEFERRABLE INICIALMENTE INMEDIATO. Eso mantiene el comportamiento predeterminado como todo el mundo espera, pero permite la manipulación sin necesidad de que se deshabiliten las claves externas.
ver AskTom:
http://www.oracle.com/technology/oramag/oracle/03-nov/o63asktom.html
ver AskTom: http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:10954765239682
véase también: http://www.idevelopment.info/data/Oracle/DBA_tips/Database_Administration/DBA_12.shtml
[EDIT]
A: En Microsoft SQL Server, no se puede difiera las restricciones de clave externa como puede en Oracle. Desactivar y volver a habilitar la restricción de clave externa es un enfoque, pero tiemblo ante la perspectiva de 1) impacto en el rendimiento (la restricción de clave externa que se verifica para la tabla COMPLETA cuando la restricción se vuelve a habilitar), 2) manejar la excepción si (¿cuándo?) falla la reactivación de la restricción. Tenga en cuenta que la inhabilitación de la restricción afectará a todas las sesiones, por lo tanto, mientras la restricción esté desactivada, otras sesiones podrían potencialmente insertar y actualizar filas, lo que provocará que la restricción de la restricción falle.
Con SQL Server, un mejor enfoque es eliminar la restricción NOT NULL y permitir un NULL como marcador de posición temporal mientras se insertan/actualizan las filas.
Para 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]
Esto parece una extraña esquema para mí, ¿puede explicar por qué tiene las relaciones de esta manera? – Bob
¿Está EmployeeId en la mesa de su departamento como un gerente de departamento o algo así? –
En Oracle, el "truco" es definir la (s) clave (s) externa (s) DEFERRABLE (s). – spencer7593