SQL Server 的約束

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 公衆號,將有更多精彩內容分享:

                                                                 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章