De meeste database management systemen beperken check constraints tot een enkele rij, met toegang tot constanten en deterministische functies, maar niet tot gegevens in andere tabellen, of tot gegevens die onzichtbaar zijn voor de huidige transactie vanwege transactie-isolatie.
Dergelijke constraints zijn niet echt tabel check constraints, maar eerder rij check constraints. Omdat deze constraints in het algemeen alleen worden geverifieerd wanneer een rij direct wordt bijgewerkt (om prestatieredenen) en vaak worden geïmplementeerd als impliciete INSERT
of UPDATE
triggers, zouden integriteitsrestricties kunnen worden geschonden door indirecte actie, ware het niet voor deze beperkingen. Bovendien zouden anderszins geldige wijzigingen aan deze records dan worden verhinderd door de CHECK
constraint. Enkele voorbeelden van gevaarlijke constraints zijn:
CHECK ((select count(*) from invoices where invoices.customerId = customerId) < 1000)
CHECK (dateInserted = CURRENT_DATE)
CHECK (countItems = RAND())
User-defined triggers kunnen worden gebruikt om deze beperkingen te omzeilen. Hoewel de implementatie vergelijkbaar is, is het semantisch duidelijk dat triggers alleen worden geactiveerd wanneer de tabel direct wordt gewijzigd, en dat het de verantwoordelijkheid van de ontwerper is om indirecte, belangrijke wijzigingen in andere tabellen te verwerken; constraints daarentegen zijn bedoeld om “altijd waar” te zijn, ongeacht de acties van de gebruiker of het gebrek aan vooruitziendheid van de ontwerper.