sql >> Databáze >  >> RDS >> Sqlserver

ZKONTROLUJTE Omezení na serveru SQL Server

V tomto článku budeme hovořit o omezeních CHECK. Uvidíme, jak přidat omezení CHECK do sloupců tabulky SQL Server a prodiskutujeme úskalí, se kterými se můžete setkat při používání tohoto typu omezení SQL Server.

ZKONTROLUJTE základy omezení

Omezení CHECK jsou jednoduše podmíněné příkazy (predikáty, které vracejí hodnotu TRUE nebo FALSE), které odkazují na sloupce tabulky pro zachování integrity dat. Když vložíte data do sloupce nebo několika sloupců v jednom řádku, začnou fungovat omezení CHECK. Vyhodnocují data, která mají být vložena. V případě, že data nesplňují podmínku uvedenou v podmínce CHECK, vložení se nezdaří.

Zvažte následující příklad:

Je nutné nastavit omezení pro sloupec Plat tak, aby ukládal pouze kladné hodnoty nepřesahující 150 000 USD. Podmíněné prohlášení bude vypadat následovně:(Plat>=0 a Plat <=150 000). Při pokusu o vložení záporných hodnot bude výsledkem predikátu FALSE a vložení se nezdaří.

Je možné přidat omezení CHECK k jednomu nebo více sloupcům. Přidání vícesloupcového omezení CHECK lze implementovat na úrovni tabulky.

Práce s omezeními CHECK

Jak vytvořit omezení CHECK v SSMS

  1. V Průzkumníku objektů , přejděte na požadovanou tabulku.

  2. Klikněte pravým tlačítkem na Omezení složku a poté c klikněte na Nové omezení…

  3. V pravém podokně Kontrola omezení dialogovém okně klikněte na Výraz a poté klikněte na tlačítko se třemi tečkami.

  1. Zadejte výraz omezení CHECK do textového pole Kontrola výrazu omezení dialogové okno. Chcete-li například povolit pouze sedmimístná PSČ ve sloupci PSČ, výraz může vypadat takto:

V Návrháři tabulek části, můžete nastavit pravidla pro vynucení omezení.

ZKONTROLUJTE omezení na CREATE TABLE

Zvažte následující příklad:

Je nutné vytvořit tabulku, která ukládá údaje o zákaznících bank, a naplnit ji testovacími údaji. Tabulka bude obsahovat následující sloupce:Číslo zákazníka, Křestní jméno, Příjmení, Stav, Telefon, Město, Stát a PSČ.

Při vývoji tabulky musíme vzít v úvahu následující skutečnosti:

  1. Základní formát ZIP se skládá z pěti číslic.

  2. Standardní americké telefonní číslo má deset číslic, například (555) 555-1234

  3. Dvoupísmenné zkratky se používají k označení politických rozdělení Spojených států pro poštovní adresy, zpracování dat, obecné zkratky a další účely.

Úkolem je zajistit konzistenci dat pro tabulku. Je požadováno zakázat vkládání 12místných telefonních čísel a 6místných zipů atd. Za tímto účelem nám SQL Server umožňuje přidat jedno nebo více omezení CHECK pro každý sloupec tabulky.

V předchozí části jsme zkoumali jeden způsob vytvoření omezení CHECK v SSMS. Nyní probereme, jak vytvořit omezení pomocí T-SQL.

Následující skript ukazuje, jak vytvořit omezení CHECK ve sloupci 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
)

Nyní se podívejme, co dostaneme, když se pokusíme vložit 6místnou hodnotu do sloupce 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

Vložení se nezdaří a SQL Server zobrazí následující prevenci:

Zatím vše v pořádku.

Výraz CASE v podmínce CHECK

Předpokládejme, že banka má obchodní pravidlo, které nastavuje úvěrový limit pro obyvatele státu Louisiana pod 150 000 USD. Tento požadavek implementujeme přidáním omezení CHECK do sloupce Credit Limit:

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

Při provádění výše uvedeného příkazu se zobrazí následující chyba:

Příkaz INSERT byl v konfliktu s podmínkou CHECK. Co se pokazilo?

Pojďme se na dotaz podívat blíže. Všimněte si, že omezení CHECK povoluje pouze hodnoty „LA“ pro sloupec State. Hodnoty ve sloupci Kredit zároveň nesmí překročit 150 000.

Podobně omezení CHECK neumožní zapsat do sloupce jiné stavové kódy.

Potřebujeme tedy upravit podmínku. Podle obchodní logiky banka poskytuje obyvatelům Louisiany 150 000 USD z úvěrového limitu. Zároveň se tato hodnota může lišit pro ostatní obyvatele.

K implementaci tohoto případu použijeme klauzuli CASE uvnitř omezení CHECK:

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

Tento výraz zcela odpovídá obchodní logice.

hodnoty NULL v podmínce CHECK

Banka rozděluje své zákazníky do segmentů. Sloupec Stav obsahuje údaje, které určují, zda je klient VIP nebo běžný. Maximální výše úvěrového limitu pro stálé zákazníky je 200 000 USD. VIP mohou čerpat 500 000 $.

Omezení CHECK může vypadat následovně:

ALTER TABLE dbo.Customers
ADD CONSTRAINT CK_Status_Credit_Limit
CHECK (Status = 'VIP' OR Status = 'Regular')
GO

Všimněte si, že omezení CHECK umožňuje vkládání hodnot NULL do sloupce State (za předpokladu, že není explicitně definováno omezení NOT NULL). Omezení CHECK vyhodnotí hodnoty a vrátí hodnotu TRUE nebo FALSE. Hodnotí NULL jako NEZNÁMÝ. Hodnoty NULL tedy nezpůsobí chyby. To je v rozporu s predikáty v klauzulích WHERE v příkazech SELECT nebo UPDATE.

CHECK a NOCHECK

Obchodní logika se čas od času mění. Způsobuje úpravy databázových objektů. Představte si, že země rozšiřuje základ PSČ a přidává 6místné hodnoty.

Staré 5místné hodnoty již nebudou přiřazovány oblastem. Stále však platí pro ty stávající. Omezení CHECK tedy musí brát v úvahu existující data ve starém formátu a ověřovat data v novém formátu.

Klauzule NOCHECK řeší tento problém:

ALTER TABLE Customers WITH NOCHECK
ADD CONSTRAINT CK_Zip_Code
CHECK (Zip LIKE REPLICATE('[0-9]', 6));
GO

Následující vložení bylo úspěšné:

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

Při pokusu o vložení pětimístného zipu motor zobrazí chybu:

DBCC CHECKCONSTRAINTS

SQL Server poskytuje DBCC CHECKCONSTRAINTS pro vyhledávání dat, která neodpovídají omezením.

Pokud dojde k problému s integritou databáze, spusťte DBCC CHECKCONSTRAINTS pro celou databázi, abyste se ujistili, že neexistují žádné problémy.

Všimněte si, že tento příkaz ovlivňuje výkon. Proto by neměl být spuštěn podle plánu.

Je možné spustit DBCC CHECKCONSTRAINTS pro jedno omezení, tabulku nebo celou databázi.

Ve srovnání s jinými kontrolními příkazy trvá dokončení DBCC CHECKCONSTRAINTS značnou dobu a spotřebovává systémové prostředky. Na rozdíl od jiných příkazů CHECKCONSTRAINTS nepoužívá snímek databáze.

Závěr

Omezení CHECK poskytují mechanismus pro vyhodnocení dat před vložením. Omezení CHECK mohou odkazovat na jeden sloupec nebo více sloupců tabulky.

Omezení jsou jednoduše predikáty, jejichž výsledkem je TRUE, FALSE nebo UNKNOWN. V případě, že je do tabulky vložena hodnota NULL, omezení není porušeno.


  1. HROMADNÉ VLOŽENÍ v MYSQL

  2. MariaDB JSON_QUERY() vysvětleno

  3. Jak převést desítkové na šestnáctkové pomocí TO_CHAR() v Oracle

  4. Jakou funkci maskování dat bych měl použít?