Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Unterabfrage in einer Check-Anweisung in Oracle verwenden

Es gibt drei grundlegende Möglichkeiten, diese Art von Problem zu lösen, da CHECK-Einschränkungen nicht auf einer Abfrage basieren können.

Option 1:Auslöser

Der einfachste Ansatz wäre, einen Trigger auf TANK zu setzen, der TANKS abfragt und eine Ausnahme auslöst, wenn LEVEL CAPACITY überschreitet. Das Problem bei dieser Art von vereinfachtem Ansatz ist jedoch, dass es fast unmöglich ist, Parallelitätsprobleme korrekt zu behandeln. Wenn Sitzung 1 die KAPAZITÄT verringert, dann Sitzung 2 den LEVEL erhöht und dann beide Transaktionen festgeschrieben werden, können Trigger die Verletzung nicht erkennen. Dies ist möglicherweise kein Problem, wenn eine oder beide Tabellen selten geändert werden, aber im Allgemeinen wird es ein Problem sein.

Option 2:Materialisierte Aufrufe

Sie können das Parallelitätsproblem lösen, indem Sie eine materialisierte ON COMMIT-Ansicht erstellen, die die Tabellen TANK und TANKS verbindet, und dann eine CHECK-Einschränkung für die materialisierte Ansicht erstellen, die überprüft, ob LEVEL <=CAPACITY. Sie können auch vermeiden, die Daten zweimal zu speichern, indem Sie die materialisierte Ansicht nur Daten enthalten lassen, die gegen die Einschränkung verstoßen würden. Dies erfordert materialisierte Ansichtsprotokolle für beide Basistabellen, was den Einfügungen etwas Overhead hinzufügt (allerdings weniger als die Verwendung von Triggern). Das Verschieben der Prüfung auf Commit-Zeit löst das Parallelitätsproblem, führt jedoch zu einem gewissen Ausnahmeverwaltungsproblem, da die COMMIT-Operation jetzt fehlschlagen kann, weil die Aktualisierung der materialisierten Ansicht fehlgeschlagen ist. Ihre Anwendung muss in der Lage sein, dieses Problem zu handhaben und den Benutzer darauf aufmerksam zu machen.

Option 3:Ändern Sie das Datenmodell

Wenn Sie einen Wert in Tabelle A haben, der von einem Grenzwert in Tabelle B abhängt, kann dies darauf hindeuten, dass der Grenzwert in B ein Attribut von Tabelle A sein sollte (statt oder zusätzlich zu einem Attribut von Tabelle B). Dies hängt natürlich von den Besonderheiten Ihres Datenmodells ab, ist aber oft eine Überlegung wert.