La maggior parte dei sistemi di gestione di database limita i vincoli di controllo ad una singola riga, con accesso a costanti e funzioni deterministiche, ma non a dati in altre tabelle, o a dati invisibili alla transazione corrente a causa dell’isolamento della transazione.
Questi vincoli non sono veramente vincoli di controllo di tabella, ma piuttosto di riga. Poiché questi vincoli sono generalmente verificati solo quando una riga viene aggiornata direttamente (per ragioni di prestazioni) e spesso implementati come trigger impliciti INSERT
o UPDATE
, i vincoli di integrità potrebbero essere violati da azioni indirette se non fosse per queste limitazioni. Inoltre, le modifiche altrimenti valide di questi record sarebbero impedite dal vincolo CHECK
. Alcuni esempi di vincoli pericolosi includono:
CHECK ((select count(*) from invoices where invoices.customerId = customerId) < 1000)
CHECK (dateInserted = CURRENT_DATE)
CHECK (countItems = RAND())
I trigger definiti dall’utente possono essere usati per aggirare queste restrizioni. Anche se l’implementazione è simile, è semanticamente chiaro che i trigger saranno attivati solo quando la tabella viene direttamente modificata, e che è responsabilità del progettista gestire i cambiamenti indiretti e importanti in altre tabelle; i vincoli, d’altra parte, sono intesi per essere “veri in ogni momento” indipendentemente dalle azioni dell’utente o dalla mancanza di previsione del progettista.