De flesta databashanteringssystem begränsar kontrollbegränsningar till en enda rad, med tillgång till konstanter och deterministiska funktioner, men inte till data i andra tabeller eller till data som är osynliga för den aktuella transaktionen på grund av transaktionsisolering.
Sådana begränsningar är egentligen inte tabellkontrollbegränsningar utan snarare radkontrollbegränsningar. Eftersom dessa begränsningar i allmänhet bara verifieras när en rad uppdateras direkt (av prestandaskäl) och ofta implementeras som implicita INSERT
eller UPDATE
utlösare, skulle integritetsbegränsningar kunna kränkas genom indirekta åtgärder om det inte vore för dessa begränsningar. Dessutom skulle annars giltiga ändringar av dessa poster förhindras av begränsningen CHECK
. Några exempel på farliga begränsningar är:
CHECK ((select count(*) from invoices where invoices.customerId = customerId) < 1000)
CHECK (dateInserted = CURRENT_DATE)
CHECK (countItems = RAND())
Användardefinierade triggers kan användas för att kringgå dessa begränsningar. Även om de liknar varandra i genomförandet är det semantiskt klart att triggers endast utlöses när tabellen ändras direkt, och att det är konstruktörens ansvar att hantera indirekta, viktiga ändringar i andra tabeller; begränsningar å andra sidan är avsedda att vara ”sanna hela tiden” oavsett användarens handlingar eller konstruktörens brist på förutseende.