La plupart des systèmes de gestion de base de données restreignent les contraintes de contrôle à une seule ligne, avec un accès aux constantes et aux fonctions déterministes, mais pas aux données des autres tables, ou aux données invisibles à la transaction actuelle en raison de l’isolation de la transaction.
Ces contraintes ne sont pas vraiment des contraintes de contrôle de table mais plutôt des contraintes de contrôle de ligne. Parce que ces contraintes ne sont généralement vérifiées que lorsqu’une ligne est directement mise à jour (pour des raisons de performance,) et souvent implémentées comme des déclencheurs implicites INSERT
ou UPDATE
, les contraintes d’intégrité pourraient être violées par une action indirecte s’il n’y avait pas ces limitations. De plus, des modifications autrement valides de ces enregistrements seraient alors empêchées par la contrainte CHECK
. Voici quelques exemples de contraintes dangereuses :
CHECK ((select count(*) from invoices where invoices.customerId = customerId) < 1000)
CHECK (dateInserted = CURRENT_DATE)
CHECK (countItems = RAND())
Des déclencheurs définis par l’utilisateur peuvent être utilisés pour contourner ces restrictions. Bien que similaires dans leur mise en œuvre, il est sémantiquement clair que les déclencheurs ne seront déclenchés que lorsque la table est directement modifiée, et qu’il incombe au concepteur de gérer les changements indirects et importants dans d’autres tables ; les contraintes, en revanche, sont destinées à être « vraies à tout moment », quelles que soient les actions de l’utilisateur ou le manque de prévoyance du concepteur.