I den här artikeln kommer vi att prata om CHECK-begränsningar. Vi kommer att se hur du lägger till CHECK-begränsningar i SQL Server-tabellkolumner och diskuterar de fallgropar du kan stöta på när du använder den här typen av SQL Server-begränsningar.
Kontrollera grunderna för begränsningar
CHECK-begränsningar är helt enkelt villkorliga uttalanden (predikat som returnerar TRUE eller FALSE) som refererar till tabellkolumner för att upprätthålla dataintegriteten. När man infogar data i en kolumn eller flera kolumner i en enda rad, träder CHECK-begränsningarna i kraft. De utvärderar data som ska infogas. Om data inte uppfyller villkoret som anges i CHECK-begränsningen misslyckas infogningen.
Tänk på följande exempel:
Det krävs att du ställer in en begränsning för kolumnen Lön så att den endast lagrar positiva värden som inte överstiger 150 000 USD. Det villkorliga uttalandet kommer att se ut så här:(Lön>=0 och Lön <=150 000). När du försöker infoga negativa värden kommer predikatet att resultera i FALSK och infogningen misslyckas.
Det är möjligt att lägga till en CHECK-begränsning i en eller flera kolumner. Att lägga till en KONTROLL-begränsning med flera kolumner kan implementeras på tabellnivå.
Arbeta med CHECK-begränsningar
Hur man skapar CHECK-begränsningar i SSMS
I Objektutforskaren , navigera till en önskad tabell.
Högerklicka på Begränsningar mapp och sedan c klicka på Ny begränsning...
I den högra rutan i Kontrollera begränsningar i dialogrutan klickar du på Uttryck och klicka sedan på ellipsknappen.
Skriv in ett CHECK-begränsningsuttryck i textfältet i Check Constraint Expression dialog ruta. Till exempel, för att endast tillåta sjusiffriga postnummer i en postkolumn, kan uttrycket se ut så här:
I Table Designer avsnitt, kan du ställa in reglerna för att upprätthålla begränsningen.
KONCERA begränsning på SKAPA TABELL
Tänk på följande exempel:
Det krävs att man skapar en tabell som lagrar data om bankkunder och fyller den med testdata. Tabellen kommer att innehålla följande kolumner:Kund-ID, Förnamn, Efternamn, Status, Telefon, Stad, Stat och Postnummer.
När vi utvecklar tabellen måste vi ta hänsyn till följande fakta:
Det grundläggande ZIP-formatet består av fem numeriska siffror.
Det amerikanska standardtelefonnumret är tio siffror, till exempel (555) 555-1234
Tvåbokstavsförkortningar används för att representera USA:s politiska avdelningar för postadresser, databehandling, allmänna förkortningar och andra ändamål.
Uppgiften är att tillhandahålla datakonsistens för tabellen. Det krävs att förbjuda infogning av 12-siffriga telefonnummer och 6-siffriga zips etc. För att göra detta tillåter SQL Server oss att lägga till en eller flera CHECK-begränsningar för varje tabellkolumn.
I föregående avsnitt har vi undersökt det enda sättet att skapa en CHECK-begränsning i SSMS. Nu kommer vi att diskutera hur man skapar begränsningen med hjälp av T-SQL.
Följande skript visar hur man skapar en KONTROLL-begränsning i kolumnen Zip:
CREATE TABLE Customers ( Customer_Id tinyint NOT NULL, [First Name] varchar(50), [Last Name] varchar(50), Status varchar(50), Phone tinyint, Address varchar(50), State varchar(50), Zip tinyint, Email varchar(50), [Credit Limit] INT NULL, CONSTRAINT CK_Zip CHECK (Zip LIKE REPLICATE ('[0-9]', 5)) --Check Constraint Condition )
Låt oss nu se vad vi får när vi försöker infoga ett sexsiffrigt värde i kolumnen Zip:
INSERT INTO dbo.Customers (Customer_Id, [First Name], [Last Name], Status, Phone, Address, State, Zip, Email) SELECT 1, 'James', 'Madison', 'Mr', 555-555-1234, 'Madison street, 12', 'LA', 123456, NULL GO
Insättningen misslyckas och SQL Server visar följande förhindrande:
Än så länge har det gått bra.
CASE-uttryck i CHECK-begränsning
Anta att banken har en affärsregel för att sätta kreditgränsen för invånarna i delstaten Louisiana till under 150 000 USD. Vi kommer att implementera detta krav genom att lägga till en CHECK-begränsning i kolumnen Kreditgräns:
ALTER TABLE dbo.Customers ADD CONSTRAINT CK_Credit_Limit CHECK (State='LA' AND [Credit Limit] <= 150000) GO INSERT INTO Customers (Customer_Id, Name, Status, Phone, State, Zip, Email, [Credit Limit]) VALUES (1, 'James Black', 'Mr', 5558787, 'LA', 46853, '[email protected]', 120000); GO INSERT INTO Customers (Customer_Id, Name, Status, Phone, State, Zip, Email, [Credit Limit]) VALUES (2, 'Mark Spencer', 'Mr', 3332244, 'NY', 23487, '[email protected]', 200000); GO
När vi kör ovanstående sats får vi följande fel:
INSERT-satsen kom i konflikt med CHECK-begränsningen. Vad gick fel?
Låt oss titta närmare på frågan. Observera att CHECK-begränsningen endast tillåter 'LA'-värdena för kolumnen State. Samtidigt får värdena i kolumnen Kredit inte överstiga 150 000.
På liknande sätt skulle CHECK-begränsningen inte tillåta att skriva andra tillståndskoder i kolumnen.
Därför måste vi ändra villkoret. Enligt affärslogiken tillhandahåller banken 150 000 USD av kreditgränsen för invånare i Louisiana. Samtidigt kan detta värde variera för andra boende.
För att implementera det här fallet kommer vi att använda CASE-satsen inom CHECK-begränsningen:
ALTER TABLE dbo.Customers ADD CONSTRAINT CK_Credit_Limit CHECK (CASE WHEN State='LA' AND [Credit Limit] <= 150000 THEN 1 ELSE 0 END = 1) GO
Detta uttryck uppfyller helt affärslogiken.
NULL-värden i CHECK-begränsning
Banken delar in sina kunder i segment. Kolumnen Status innehåller data som avgör om en klient är VIP eller vanlig. Det maximala beloppet för kreditgränsen för vanliga kunder är 200 000 USD. VIP-medlemmarna kan dra på $500 000.
CHECK-begränsningen kan se ut som följer:
ALTER TABLE dbo.Customers ADD CONSTRAINT CK_Status_Credit_Limit CHECK (Status = 'VIP' OR Status = 'Regular') GO
Observera att CHECK-restriktionen tillåter att infoga NULLs i State-kolumnen (förutsatt att det inte finns någon NOT NULL-begränsning explicit definierad). CHECK-begränsningen utvärderar värdena och returnerar TRUE eller FALSE. Den utvärderar NULL som OKÄNT. Därför kommer NULL inte att orsaka fel. Detta strider mot predikat i WHERE-satser i SELECT- eller UPDATE-satser.
KONTROLL och NOCHECK
Då och då förändras affärslogiken. Det orsakar databasobjekt ändringar. Föreställ dig att ett land utökar postnummerbasen och lägger till sexsiffriga värden.
De gamla 5-siffriga värdena kommer inte längre att tilldelas områdena. De är dock fortfarande giltiga för befintliga. Därför måste CHECK-begränsningen ta hänsyn till befintlig data i det gamla formatet och validera data i det nya formatet.
NOCHECK-satsen löser det här problemet:
ALTER TABLE Customers WITH NOCHECK ADD CONSTRAINT CK_Zip_Code CHECK (Zip LIKE REPLICATE('[0-9]', 6)); GO
Följande infogning lyckades:
INSERT INTO Customers (Customer_Id, Name, Status, Phone, State, Zip, Email, [Credit Limit]) VALUES (102, 'Jake Harrison', 'VIP', 555-555-1234, 'NY', 123456, '[email protected]', 100000); GO
När du försöker infoga ett femsiffrigt zip-fil, skickar motorn felet:
DBCC CHECKCONSTRAINTS
SQL Server tillhandahåller DBCC CHECKCONSTRAINTS för att söka efter data som inte matchar begränsningar.
Om det finns ett databasintegritetsproblem, kör DBCC CHECKCONSTRAINTS för hela databasen för att säkerställa att det inte finns några problem.
Observera att det här kommandot påverkar prestandan. Därför bör den inte köras på schemalagd basis.
Det är möjligt att köra DBCC CHECKCONSTRAINTS för en enskild begränsning, en tabell eller hela databasen.
Jämfört med andra kontrollkommandon tar DBCC CHECKCONSTRAINTS avsevärd tid att slutföra och förbrukar systemresurser. Till skillnad från andra kommandon använder CHECKCONSTRAINTS inte en ögonblicksbild av databasen.
Slutsats
CHECK-begränsningar tillhandahåller mekanismen för att utvärdera data före infogning. CHECK-begränsningar kan referera till en enstaka kolumn eller flera tabellkolumner.
Restriktioner är helt enkelt predikat som resulterar i TRUE, FALSE eller OKÄNT. Om NULL infogas i en tabell överträds inte en begränsning.