Me gustaría definir una restricción entre dos FK numerables en una tabla donde si uno es nulo, el otro necesita un valor, pero ambos no pueden ser nulos y ambos no pueden tener valores La lógica es la tabla derivada hereda los datos de cualquiera de las tablas FK para determinar su tipo. Además, para los puntos de bonificación de diversión, ¿es esta una mala idea?Agregar una restricción XOR de SQL entre dos FK con nulos
Respuesta
Una forma de lograrlo es simplemente escribir lo que "O exclusiva" significa en realidad:
CHECK (
(FK1 IS NOT NULL AND FK2 IS NULL)
OR (FK1 IS NULL AND FK2 IS NOT NULL)
)
Sin embargo, si tiene muchos FKs, el método anterior puede convertirse rápidamente en poco manejable, en cuyo caso se puede hacer algo como esto:
CHECK (
1 = (
(CASE WHEN FK1 IS NULL THEN 0 ELSE 1 END)
+ (CASE WHEN FK2 IS NULL THEN 0 ELSE 1 END)
+ (CASE WHEN FK3 IS NULL THEN 0 ELSE 1 END)
+ (CASE WHEN FK4 IS NULL THEN 0 ELSE 1 END)
...
)
)
por cierto, hay usos legítimos para ese patrón, por ejemplo this one (aunque no aplicable a MS SQL Server debido a la falta de limitaciones diferidos). Si es legítimo en su caso particular, no puedo juzgarlo en base a la información que proporcionó hasta el momento.
más simple: 'CHECK (fk1 IS NULL! = Fk2 IS NULL)' –
@ StephenJ.Fuhry Lamentablemente, MS SQL Server no trata el tipo booleano como un ciudadano de primera clase, por lo que no se aceptará la sintaxis. –
pero funciona en PostgreSQL, que es para lo que lo necesito. gracias por la breve expresión, @ StephenJ.Fuhry. por supuesto, sería mejor tener XOR. dado cuánto material se ha acumulado en el sistema que parece una omisión extraña. – mARK
Puede utilizar check constraint:
create table #t (
a int,
b int);
alter table #t add constraint c1
check (coalesce(a, b) is not null and a*b is null);
insert into #t values (1,null);
insert into #t values (null ,null);
de reproducción:
The INSERT statement conflicted with the CHECK constraint "c1".
El 'coalesce (a, b)' devolverá no NULL cuando ** both ** 'a' y' b' no son NULL y CHECK pasará, lo que no debería ocurrir (OP fue explícito de que ambos no pueden tener valores). En otras palabras, el 'insert into #t values (1, 1)' debería fallar. –
seguro. Gracias. Repararé mi respuesta. – danihp
camino alternativo es definir esta restricción de comprobación en un procedimiento. Antes de insertar un registro en la tabla derivada, se debe cumplir la restricción. Otra inserción falla o devuelve un error.
- 1. SQL Server restricción UNIQUE con nulos duplicados
- 2. Privilegios insuficientes al agregar la restricción FK (Oracle)
- 3. Agregar una clave foránea que admite nulos.
- 4. Servidor SQL: Drop Table con FK
- 5. ¿Cómo crear una restricción de verificación entre dos columnas en SQL?
- 6. Consulta SQL para agregar valores de dos columnas que contienen valores nulos?
- 7. ALTER TABLE agregar restricción
- 8. función genérica con una restricción "tiene la propiedad X"?
- 9. con la restricción de verificación Agregar seguido de restricción CHECK CONSTRAINT vs ADD
- 10. Resta entre dos consultas sql
- 11. Únete a una tabla con dos columnas no FK con Fluido NHibernate
- 12. SQL Server 2005 Restricción única en dos columnas
- 13. Restricción NULL de SQL Server
- 14. Restricción de comprobación de clave externa de T-SQL
- 15. SQL restricción servidor expresión regular
- 16. ¿Puedo crear una restricción predeterminada nombrada en una instrucción agregar columna en SQL Server?
- 17. Eliminación de una restricción predeterminada después de agregar una nueva columna en el código primero
- 18. Capturando una violación de restricción en psql
- 19. Restricción SQL minvalue/maxvalue?
- 20. Una restricción que solo permite que una de dos tablas haga referencia a una tabla base
- 21. ¿Hay alguna forma de insertar a granel en dos tablas con FK de una a la otra?
- 22. Problema de restricción único de SQL Server
- 23. No se puede agregar o actualizar una fila secundaria: falla una restricción de clave externa
- 24. SQL Server 2005: Restricción de clave externa anulable
- 25. Combinar dos filas en SQL
- 26. Consulta SQL NO entre dos fechas
- 27. Powershell 2.0 genera nulos entre caracteres
- 28. Restricción autorreferencial en MS SQL
- 29. Diferencia entre restricción de clave externa y referencias en Rails
- 30. Cómo crear una restricción única compuesta en SQL Server 2005
[También podría considerar el patrón de tipo super/tipo de subtítulo que se muestra aquí] (http://stackoverflow.com/q/7771869/73226) –