欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SQL Server中Check約束的學(xué)習(xí)教程

 更新時(shí)間:2015年12月11日 15:55:55   作者:宋沄劍  
這篇文章主要介紹了SQL Server中Check約束的學(xué)習(xí)教程,包括對(duì)啟用Check約束來(lái)提升性能的介紹,需要的朋友可以參考下

0.什么是Check約束?

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

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

創(chuàng)建表時(shí)定義CHECK約束

1.1 語(yǔ)法:

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

其中,DISABLE關(guān)鍵之是可選項(xiàng)。如果使用了DISABLE關(guān)鍵字,當(dāng)CHECK約束被創(chuàng)建后,CHECK約束的限制條件不會(huì)生效。


1.2 示例1:數(shù)值范圍驗(yàn)證

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

驗(yàn)證:
在表中插入supplier_id滿(mǎn)足條件和不滿(mǎn)足條件兩種情況:

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

不滿(mǎn)足條件的錯(cuò)誤提示:

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


1.3 示例2:強(qiáng)制插入列的字母為大寫(xiě)

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

驗(yàn)證:
在表中插入product_name滿(mǎn)足條件和不滿(mǎn)足條件兩種情況:

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

不滿(mǎn)足條件的錯(cuò)誤提示:

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

2. ALTER TABLE定義CHECK約束

2.1 語(yǔ)法

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

其中,DISABLE關(guān)鍵之是可選項(xiàng)。如果使用了DISABLE關(guān)鍵字,當(dāng)CHECK約束被創(chuàng)建后,CHECK約束的限制條件不會(huì)生效。

2.2 示例準(zhǔn)備

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

2.3 創(chuàng)建CHECK約束

--創(chuàng)建check約束
alter table tb_supplier
add constraint check_tb_supplier
check (supplier_name IN ('IBM','LENOVO','Microsoft'));

2.4 驗(yàn)證

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

不滿(mǎn)足條件的錯(cuò)誤提示:

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

3. 啟用CHECK約束

3.1 語(yǔ)法

ALTER TABLE table_name
ENABLE 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語(yǔ)句的執(zhí)行是依賴(lài)查詢(xún)優(yōu)化器生成的執(zhí)行計(jì)劃,而執(zhí)行計(jì)劃的好壞直接關(guān)乎執(zhí)行性能。

在查詢(xún)優(yōu)化器生成執(zhí)行計(jì)劃過(guò)程中,需要參考元數(shù)據(jù)來(lái)盡可能生成高效的執(zhí)行計(jì)劃,因此元數(shù)據(jù)越多,則執(zhí)行計(jì)劃更可能會(huì)高效。所謂需要參考的元數(shù)據(jù)主要包括:索引、表結(jié)構(gòu)、統(tǒng)計(jì)信息等,但還有一些不是很被注意的元數(shù)據(jù),其中包括本文闡述的Check約束。
圖1.簡(jiǎn)單查詢(xún)
查詢(xún)優(yōu)化器在生成執(zhí)行計(jì)劃之前有一個(gè)階段叫做代數(shù)樹(shù)優(yōu)化,比如說(shuō)下面這個(gè)簡(jiǎn)單查詢(xún):

20151211155126523.png (414×248)

查詢(xún)優(yōu)化器意識(shí)到1=2這個(gè)條件是永遠(yuǎn)不相等的,因此不需要返回任何數(shù)據(jù),因此也就沒(méi)有必要掃描表,從圖1執(zhí)行計(jì)劃可以看出僅僅掃描常量后確定了1=2永遠(yuǎn)為false后,就可完成查詢(xún)。

那么Check約束呢?

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

20151211155147674.png (470×262)

圖2.有Check約束的列提升查詢(xún)性能

圖2是一個(gè)簡(jiǎn)單的例子,有時(shí)候在分區(qū)視圖中應(yīng)用Check約束也會(huì)提升性能,測(cè)試代碼如下:

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 testPartitionView
AS
SELECT * FROM Test2007
UNION
SELECT * FROM Test2008
 
SELECT * FROM testPartitionView
WHERE [ReviewDate]='2007-01-01'
 
SELECT * FROM testPartitionView
WHERE [ReviewDate]='2008-01-01'
 
SELECT * FROM testPartitionView
WHERE [ReviewDate]='2010-01-01'

我們針對(duì)Test2007和Test2008兩張表結(jié)構(gòu)一模一樣的表做了一個(gè)分區(qū)視圖。并對(duì)日期列做了Check約束,限制每張表包含的數(shù)據(jù)都是特定一年內(nèi)的數(shù)據(jù)。當(dāng)我們對(duì)視圖進(jìn)行查詢(xún)并給定不同的篩選條件時(shí),可以看到結(jié)果如圖3所示。

20151211155256851.png (669×500)

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


4. 禁用CHECK約束

4.1 語(yǔ)法

ALTER TABLE table_name
DISABLE CONSTRAINT constraint_name;

4.2 示例

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

 
5. 約束詳細(xì)信息查看
語(yǔ)句:

--查看約束的詳細(xì)信息
select
constraint_name,--約束名稱(chēng)
constraint_type,--約束類(lèi)型
table_name,--約束所在的表
search_condition,--約束表達(dá)式
status--是否啟用
from user_constraints--[all_constraints|dba_constraints]
where constraint_name='CHECK_TB_SUPPLIER_ID';

6. 刪除CHECK約束
6.1 語(yǔ)法

ALTER TABLE table_name
DROP CONSTRAINT constraint_name;

6.2 示例

ALTER TABLE tb_supplier
DROP CONSTRAINT check_tb_supplier_id;

相關(guān)文章

  • 詳解安裝sql2012出現(xiàn)錯(cuò)誤could not open key...解決辦法

    詳解安裝sql2012出現(xiàn)錯(cuò)誤could not open key...解決辦法

    這篇文章主要介紹了詳解安裝sql2012出現(xiàn)錯(cuò)誤could not open key...解決辦法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • 如何快速刪掉SQL Server登錄時(shí)登錄名下拉列表框中的選項(xiàng)

    如何快速刪掉SQL Server登錄時(shí)登錄名下拉列表框中的選項(xiàng)

    本文給大家分享如何快速刪掉SQL Server登錄時(shí)登錄名下拉列表框中的選項(xiàng),包括問(wèn)題原因分析和解決方案,非常不錯(cuò),需要的朋友參考下吧
    2016-11-11
  • SQL SERVER 分組求和sql語(yǔ)句

    SQL SERVER 分組求和sql語(yǔ)句

    這篇文章主要介紹了SQL SERVER 分組求和sql語(yǔ)句,需要的朋友可以參考下
    2017-01-01
  • SQL優(yōu)化基礎(chǔ) 使用索引(一個(gè)小例子)

    SQL優(yōu)化基礎(chǔ) 使用索引(一個(gè)小例子)

    一年多沒(méi)寫(xiě),偶爾會(huì)有沖動(dòng)寫(xiě)幾句,每次都欲寫(xiě)又止,有時(shí)候?qū)懗鰜?lái)就是個(gè)記錄,沒(méi)有其他想法,能對(duì)別人有用也算額外的功勞
    2012-01-01
  • SQL Server 2008 清空刪除日志文件(瞬間縮小日志到幾M)

    SQL Server 2008 清空刪除日志文件(瞬間縮小日志到幾M)

    sql 在使用中每次查詢(xún)都會(huì)生成日志,但是如果你長(zhǎng)久不去清理,可能整個(gè)硬都堆滿(mǎn)哦,筆者就遇到這樣的情況,直接網(wǎng)站后臺(tái)都進(jìn)不去了。下面我們一起來(lái)學(xué)習(xí)一下如何清理這個(gè)日志吧
    2018-10-10
  • SQL Server索引的原理深入解析

    SQL Server索引的原理深入解析

    實(shí)際上,您可以把索引理解為一種特殊的目錄,下面這篇文章主要給大家介紹了關(guān)于SQL Server索引原理的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-07-07
  • 深入淺出解析mssql在高頻,高并發(fā)訪(fǎng)問(wèn)時(shí)鍵查找死鎖問(wèn)題

    深入淺出解析mssql在高頻,高并發(fā)訪(fǎng)問(wèn)時(shí)鍵查找死鎖問(wèn)題

    SQL Server死鎖使我們經(jīng)常遇到的問(wèn)題,數(shù)據(jù)庫(kù)操作的死鎖是不可避免的,本文并不打算討論死鎖如何產(chǎn)生,重點(diǎn)在于解決死鎖。希望對(duì)您學(xué)習(xí)SQL Server死鎖方面能有所幫助。
    2014-08-08
  • sql語(yǔ)句中單引號(hào),雙引號(hào)的處理方法

    sql語(yǔ)句中單引號(hào),雙引號(hào)的處理方法

    關(guān)于Insert字符串 很多同學(xué)都在(單引號(hào),雙引號(hào))這個(gè)方面發(fā)生了問(wèn)題,其實(shí)主要是因?yàn)閿?shù)據(jù)類(lèi)型和變量在作怪。
    2013-03-03
  • SQL Server數(shù)據(jù)庫(kù)中批量導(dǎo)入數(shù)據(jù)的四種方法總結(jié)

    SQL Server數(shù)據(jù)庫(kù)中批量導(dǎo)入數(shù)據(jù)的四種方法總結(jié)

    數(shù)據(jù)導(dǎo)入一直是項(xiàng)目人員比較頭疼的問(wèn)題。其實(shí),在SQL Server中集成了很多成批導(dǎo)入數(shù)據(jù)的方法,接下來(lái)為大家介紹下常用的四種批量導(dǎo)入數(shù)據(jù)的方法,感興趣的各位可以參考下哈
    2013-03-03
  • SQL Server實(shí)現(xiàn)跨庫(kù)跨服務(wù)器訪(fǎng)問(wèn)的方法

    SQL Server實(shí)現(xiàn)跨庫(kù)跨服務(wù)器訪(fǎng)問(wèn)的方法

    這篇文章主要給大家介紹了關(guān)于SQL Server實(shí)現(xiàn)跨庫(kù)跨服務(wù)器訪(fǎng)問(wèn)的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用SQL Server具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06

最新評(píng)論