Oracle
 sql >> Base de données >  >> RDS >> Oracle

Utilisation d'une sous-requête dans une instruction Check dans Oracle

Il existe trois méthodes de base pour résoudre ce type de problème puisque les contraintes CHECK ne peuvent pas être basées sur une requête.

Option 1 :Déclencheurs

L'approche la plus simpliste consisterait à placer un déclencheur sur TANK qui interroge TANKS et lève une exception si LEVEL dépasse CAPACITY. Le problème avec ce type d'approche simpliste, cependant, est qu'il est presque impossible de gérer correctement les problèmes de concurrence. Si la session 1 diminue la CAPACITÉ, puis la session 2 augmente le NIVEAU, puis les deux transactions sont validées, les déclencheurs ne pourront pas détecter la violation. Cela peut ne pas être un problème si l'une des tables ou les deux sont rarement modifiées, mais en général, ce sera un problème.

Option 2 :Vues matérialisées

Vous pouvez résoudre le problème de simultanéité en créant une vue matérialisée ON COMMIT qui joint les tables TANK et TANKS, puis en créant une contrainte CHECK sur la vue matérialisée qui vérifie que LEVEL <=CAPACITY. Vous pouvez également éviter de stocker les données deux fois en faisant en sorte que la vue matérialisée ne contienne que des données qui violeraient la contrainte. Cela nécessitera des journaux de vue matérialisés sur les deux tables de base, ce qui ajoutera un peu de surcharge aux insertions (bien que moins que l'utilisation de déclencheurs). Pousser la vérification au moment de la validation résoudra le problème de simultanéité, mais cela introduit un peu un problème de gestion des exceptions puisque l'opération COMMIT peut maintenant échouer car l'actualisation de la vue matérialisée a échoué. Votre application devrait être capable de gérer ce problème et d'en avertir l'utilisateur.

Option 3 :Modifier le modèle de données

Si vous avez une valeur dans la table A qui dépend d'une limite dans la table B, cela peut indiquer que la limite dans B doit être un attribut de la table A (au lieu ou en plus d'être un attribut de la table B). Cela dépend des spécificités de votre modèle de données, bien sûr, mais cela vaut souvent la peine d'être pris en compte.