SQL Server 的約束
SQL Server的約束有五種,分別如下:
-
check
-
default
-
foreign key
-
primary key
-
unique
創建方式
1. 創建表時創建
如下腳本給出創建表是創建約束的樣例
CREATE TABLE constraintTest(
id INT PRIMARY KEY
,name VARCHAR(50) UNIQUE
,age INT CHECK(age>0 AND age<150)
,sex BIT DEFAULT(0)
);
CREATE TABLE foreignTest(id INT FOREIGN KEY REFERENCES constraintTest(id)
ON UPDATE CASCADE
ON DELETE CASCADE);
2. 後期增加
創建表後,如果需要增加約束,可以通過ALTER TABLE tableName ADD CONSTRAINT constraintName constraint創建,創建樣例如下:
CREATE TABLE constraintTest1(
id INT not null
,name VARCHAR(50)
,age INT
,sex BIT
);
--增加主鍵
ALTER TABLE constraintTest1 ADD CONSTRAINT pk_test PRIMARY KEY(id);
--增加唯一約束
ALTER TABLE constraintTest1 ADD CONSTRAINT uq_test UNIQUE(name);
--增加check約束
ALTER TABLE constraintTest1 ADD CONSTRAINT ck_test CHECK(age>0 AND age<200);
--增加默認值
ALTER TABLE constraintTest1 ADD CONSTRAINT df_test DEFAULT(0) FOR sex;
CREATE TABLE foreignTest1(id INT);
--增加外鍵
ALTER TABLE foreignTest1 ADD CONSTRAINT fk_test FOREIGN KEY(id)
REFERENCES constraintTest1(id)
ON DELETE CASCADE
ON UPDATE CASCADE;
查看約束信息
sp_helpconstraint 可以幫助查看錶上的約束信息
exec sp_helpconstraint constraintTest
exec sp_helpconstraint foreignTest
也可以通過動態視圖來查看約束信息
--查看主鍵和unique約束信息
SELECT * FROM sys.key_constraints
WHERE parent_object_id IN (OBJECT_ID('constraintTest',N'U'));
--查看check 約束信息
SELECT * FROM sys.check_constraints
WHERE parent_object_id IN (OBJECT_ID('constraintTest',N'U'));
--查看默認值信息
SELECT * FROM sys.default_constraints
WHERE parent_object_id IN (OBJECT_ID('constraintTest',N'U'));
--查看外鍵信息
SELECT * FROM sys.foreign_keys
WHERE parent_object_id IN (OBJECT_ID('foreignTest',N'U'));
--查看外鍵列
SELECT fkc.*,c.name columnName FROM sys.foreign_key_columns fkc
LEFT JOIN sys.columns c ON fkc.constraint_column_id=c.column_id
AND fkc.parent_object_id=c.[object_id]
WHERE parent_object_id IN (OBJECT_ID('foreignTest',N'U'));
SELECT * FROM sys.sysconstraints;
禁用/啓用約束
從sp_helpconstraint查看的結果可以看到
status_enabled 狀態只有外鍵約束和check約束纔有值,nocheck也僅僅只能改變這兩個約束的狀態,對其他約束沒有影響。上面顯示,check和外鍵約束都是開啓的,下面使用nocheck關閉這兩個約束
ALTER TABLE constraintTest NOCHECK CONSTRAINT ALL;
ALTER TABLE foreignTest NOCHECK CONSTRAINT ALL;
此時,我們再查看約束狀態,可以發現狀態變爲disabled,其他約束的狀態沒有改變
爲測試約束禁用情況,我們向表中插入一些值
INSERT INTO constraintTest(id,age,sex) VALUES (1,300,NULL);
因爲表中id列值已經有1存在,再插入1,違反唯一性約束,報錯。把第一列值改爲2,再執行插入
可以看到,由於name值沒有指定值,默認爲Null,而表中Name列NULL值已經存在,違反unique約束報錯
刪除約束。
最後,我們將插入值再改寫如下,發現插入成功
INSERT INTO constraintTest(id,name,age) VALUES (2,'test',300);
查看錶中數據
可以看到,age=300不在原約束大於0,小於200 的範圍內。同時sex沒有指定值,給了默認值0
我們在向foreignTest表的id中插入值3(該值在主鍵表不存在,如上)
INSERT INTO foreignTest(id) VALUES(3);
可以成功插入。
至此,我們確定nocheck 隻影響check約束和外鍵約束,而對主鍵、unique、默認值不起作用
啓用約束
ALTER TABLE constraintTest CHECK CONSTRAINT ALL;
ALTER TABLE foreignTest CHECK CONSTRAINT ALL;
開啓約束時,並沒有報錯,顯然,無論是check約束,還是外鍵約束,對已有的數據不起作用,只對啓用後的數據變更起作用。
如果喜歡,可以搜索關注 MSSQLServer 公衆號,將有更多精彩內容分享: