sql >> Base de Datos >  >> RDS >> Oracle

Uso de una subconsulta en una instrucción Check en Oracle

Hay tres formas básicas de resolver este tipo de problema, ya que las restricciones CHECK no se pueden basar en una consulta.

Opción 1:Activadores

El enfoque más simple sería colocar un disparador en TANK que consulte TANKS y arroje una excepción si el NIVEL excede la CAPACIDAD. Sin embargo, el problema con este tipo de enfoque simplista es que es casi imposible manejar correctamente los problemas de concurrencia. Si la sesión 1 disminuye la CAPACIDAD, luego la sesión 2 aumenta el NIVEL y luego ambas transacciones se confirman, los activadores no podrán detectar la infracción. Esto puede no ser un problema si una o ambas tablas rara vez se modifican, pero en general será un problema.

Opción 2:vistas materializadas

Puede resolver el problema de concurrencia creando una vista materializada ON COMMIT que une la tabla TANK y TANKS y luego creando una restricción CHECK en la vista materializada que verifica que el NIVEL <=CAPACIDAD. También puede evitar almacenar los datos dos veces haciendo que la vista materializada contenga solo datos que violarían la restricción. Esto requerirá registros de vista materializados en ambas tablas base, lo que agregará un poco de sobrecarga a las inserciones (aunque menos que usar disparadores). Empujar la verificación al tiempo de compromiso resolverá el problema de concurrencia, pero presenta un problema de administración de excepciones, ya que la operación COMMIT ahora puede fallar porque la actualización de la vista materializada falló. Su aplicación necesitaría poder manejar ese problema y alertar al usuario sobre ese hecho.

Opción 3:cambiar el modelo de datos

Si tiene un valor en la tabla A que depende de un límite en la tabla B, eso puede indicar que el límite en B debe ser un atributo de la tabla A (en lugar de ser un atributo de la tabla B o además de serlo). Depende de las especificaciones de su modelo de datos, por supuesto, pero a menudo vale la pena considerarlo.