国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > SQL Server > 正文

SQL Server中Check約束的學習教程

2020-07-25 12:48:22
字體:
來源:轉載
供稿:網友

0.什么是Check約束?

CHECK約束指在表的列中增加額外的限制條件。

注: CHECK約束不能在VIEW中定義。CHECK約束只能定義的列必須包含在所指定的表中。CHECK約束不能包含子查詢。

創建表時定義CHECK約束

1.1 語法:

CREATE TABLE table_name(  column1 datatype null/not null,  column2 datatype null/not null,  ...  CONSTRAINT constraint_name CHECK (column_name condition) [DISABLE]);

其中,DISABLE關鍵之是可選項。如果使用了DISABLE關鍵字,當CHECK約束被創建后,CHECK約束的限制條件不會生效。


1.2 示例1:數值范圍驗證

create table tb_supplier( supplier_id    number, supplier_name   varchar2(50), contact_name   varchar2(60), /*定義CHECK約束,該約束在字段supplier_id被插入或者更新時驗證,當條件不滿足時觸發。*/ CONSTRAINT check_tb_supplier_id CHECK (supplier_id BETWEEN 100 and 9999));

驗證:
在表中插入supplier_id滿足條件和不滿足條件兩種情況:

--supplier_id滿足check約束條件,此條記錄能夠成功插入insert into tb_supplier values(200, 'dlt','stk'); --supplier_id不滿足check約束條件,此條記錄能夠插入失敗,并提示相關錯誤如下insert into tb_supplier values(1, 'david louis tian','stk');

不滿足條件的錯誤提示:

Error report -SQL Error: ORA-02290: check constraint (502351838.CHECK_TB_SUPPLIER_ID) violated02290. 00000 - "check constraint (%s.%s) violated"*Cause:  The values being inserted do not satisfy the named check


1.3 示例2:強制插入列的字母為大寫

create table tb_products( product_id    number not null, product_name   varchar2(100) not null, supplier_id    number not null, /*定義CHECK約束check_tb_products,用途是限制插入的產品名稱必須為大寫字母*/ CONSTRAINT check_tb_products CHECK (product_name = UPPER(product_name)));

驗證:
在表中插入product_name滿足條件和不滿足條件兩種情況:

--product_name滿足check約束條件,此條記錄能夠成功插入insert into tb_products values(2, 'LENOVO','2');--product_name不滿足check約束條件,此條記錄能夠插入失敗,并提示相關錯誤如下insert into tb_products values(1, 'iPhone','1');

不滿足條件的錯誤提示:

SQL Error: ORA-02290: check constraint (502351838.CHECK_TB_PRODUCTS) violated02290. 00000 - "check constraint (%s.%s) violated"*Cause:  The values being inserted do not satisfy the named check

2. ALTER TABLE定義CHECK約束

2.1 語法

ALTER TABLE table_nameADD CONSTRAINT constraint_name CHECK (column_name condition) [DISABLE];

其中,DISABLE關鍵之是可選項。如果使用了DISABLE關鍵字,當CHECK約束被創建后,CHECK約束的限制條件不會生效。

2.2 示例準備

drop table tb_supplier;--創建實例表create table tb_supplier( supplier_id    number, supplier_name   varchar2(50), contact_name   varchar2(60));

2.3 創建CHECK約束

--創建check約束alter table tb_supplieradd constraint check_tb_suppliercheck (supplier_name IN ('IBM','LENOVO','Microsoft'));

2.4 驗證

--supplier_name滿足check約束條件,此條記錄能夠成功插入insert into tb_supplier values(1, 'IBM','US'); --supplier_name不滿足check約束條件,此條記錄能夠插入失敗,并提示相關錯誤如下insert into tb_supplier values(1, 'DELL','HO');

不滿足條件的錯誤提示:

SQL Error: ORA-02290: check constraint (502351838.CHECK_TB_SUPPLIER) violated02290. 00000 - "check constraint (%s.%s) violated"*Cause:  The values being inserted do not satisfy the named check

3. 啟用CHECK約束

3.1 語法

ALTER TABLE table_nameENABLE CONSTRAINT constraint_name;

 

3.2 示例

drop table tb_supplier;--重建表和CHECK約束create table tb_supplier( supplier_id    number, supplier_name   varchar2(50), contact_name   varchar2(60), /*定義CHECK約束,該約束盡在啟用后生效*/ CONSTRAINT check_tb_supplier_id CHECK (supplier_id BETWEEN 100 and 9999) DISABLE); --啟用約束ALTER TABLE tb_supplier ENABLE CONSTRAINT check_tb_supplier_id;

 
3.3使用Check約束提升性能

在SQL Server中,SQL語句的執行是依賴查詢優化器生成的執行計劃,而執行計劃的好壞直接關乎執行性能。

在查詢優化器生成執行計劃過程中,需要參考元數據來盡可能生成高效的執行計劃,因此元數據越多,則執行計劃更可能會高效。所謂需要參考的元數據主要包括:索引、表結構、統計信息等,但還有一些不是很被注意的元數據,其中包括本文闡述的Check約束。
圖1.簡單查詢
查詢優化器在生成執行計劃之前有一個階段叫做代數樹優化,比如說下面這個簡單查詢:

20151211155126523.png (414×248)

查詢優化器意識到1=2這個條件是永遠不相等的,因此不需要返回任何數據,因此也就沒有必要掃描表,從圖1執行計劃可以看出僅僅掃描常量后確定了1=2永遠為false后,就可完成查詢。

那么Check約束呢?

Check約束可以確保一列或多列的值符合表達式的約束。在某些時候,Check約束也可以為優化器提供信息,從而優化性能,比如看圖二的例子。

20151211155147674.png (470×262)

圖2.有Check約束的列提升查詢性能

圖2是一個簡單的例子,有時候在分區視圖中應用Check約束也會提升性能,測試代碼如下:

CREATE TABLE [dbo].[Test2007](  [ProductReviewID] [int] IDENTITY(1,1) NOT NULL,  [ReviewDate] [datetime] NOT NULL) ON [PRIMARY] GO ALTER TABLE [dbo].[Test2007] WITH CHECK ADD CONSTRAINT [CK_Test2007] CHECK (([ReviewDate]>='2007-01-01' AND [ReviewDate]'2007-12-31'))GO ALTER TABLE [dbo].[Test2007] CHECK CONSTRAINT [CK_Test2007]GO CREATE TABLE [dbo].[Test2008](  [ProductReviewID] [int] IDENTITY(1,1) NOT NULL,  [ReviewDate] [datetime] NOT NULL) ON [PRIMARY] GO ALTER TABLE [dbo].[Test2008] WITH CHECK ADD CONSTRAINT [CK_Test2008] CHECK (([ReviewDate]>='2008-01-01' AND [ProductReviewID]'2008-12-31'))GO ALTER TABLE [dbo].[Test2008] CHECK CONSTRAINT [CK_Test2008]GO INSERT INTO [Test2008] values('2008-05-06')INSERT INTO [Test2007] VALUES('2007-05-06') CREATE VIEW testPartitionViewASSELECT * FROM Test2007UNIONSELECT * FROM Test2008 SELECT * FROM testPartitionViewWHERE [ReviewDate]='2007-01-01' SELECT * FROM testPartitionViewWHERE [ReviewDate]='2008-01-01' SELECT * FROM testPartitionViewWHERE [ReviewDate]='2010-01-01'

我們針對Test2007和Test2008兩張表結構一模一樣的表做了一個分區視圖。并對日期列做了Check約束,限制每張表包含的數據都是特定一年內的數據。當我們對視圖進行查詢并給定不同的篩選條件時,可以看到結果如圖3所示。

20151211155256851.png (669×500)

圖3.不同的條件產生不同的執行計劃
由圖3可以看出,當篩選條件為2007年時,自動只掃描2007年的表,2008年的表也是同樣。而當查詢范圍超出了2007和2008年的Check約束后,查詢優化器自動判定結果為空,因此不做任何IO操作,從而提升了性能。
結論
在Check約束條件為簡單的情況下(指的是約束限制在單列且表達式中不包含函數),不僅可以約束數據完整性,在很多時候還能夠提供給查詢優化器信息從而提升性能。


4. 禁用CHECK約束

4.1 語法

ALTER TABLE table_nameDISABLE CONSTRAINT constraint_name;

4.2 示例

--禁用約束ALTER TABLE tb_supplier DISABLE CONSTRAINT check_tb_supplier_id;

 
5. 約束詳細信息查看
語句:

--查看約束的詳細信息selectconstraint_name,--約束名稱constraint_type,--約束類型table_name,--約束所在的表search_condition,--約束表達式status--是否啟用from user_constraints--[all_constraints|dba_constraints]where constraint_name='CHECK_TB_SUPPLIER_ID';

6. 刪除CHECK約束
6.1 語法

ALTER TABLE table_nameDROP CONSTRAINT constraint_name;

6.2 示例

ALTER TABLE tb_supplierDROP CONSTRAINT check_tb_supplier_id;

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 阳原县| 罗平县| 三河市| 绵阳市| 漠河县| 尼木县| 周至县| 平邑县| 阿坝| 宜章县| 徐闻县| 昭通市| 滨海县| 长乐市| 樟树市| 双鸭山市| 诸城市| 陵川县| 余庆县| 望都县| 东兰县| 多伦县| 米林县| 聂荣县| 吉隆县| 镇原县| 静乐县| 苍南县| 华阴市| 乳源| 寿阳县| 浑源县| 合阳县| 通城县| 广州市| 晋城| 曲周县| 宁阳县| 禹城市| 桂林市| 哈巴河县|