• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    SQL Server中Check约束的学习教程

    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) violated
    02290. 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) 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 语法

    ALTER TABLE table_name
    ADD 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_supplier
    add constraint check_tb_supplier
    check (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) violated
    02290. 00000 - "check constraint (%s.%s) violated"
    *Cause:  The values being inserted do not satisfy the named check
    
    

    3. 启用CHECK约束

    3.1 语法

    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语句的执行是依赖查询优化器生成的执行计划,而执行计划的好坏直接关乎执行性能。

    在查询优化器生成执行计划过程中,需要参考元数据来尽可能生成高效的执行计划,因此元数据越多,则执行计划更可能会高效。所谓需要参考的元数据主要包括:索引、表结构、统计信息等,但还有一些不是很被注意的元数据,其中包括本文阐述的Check约束。
    图1.简单查询
    查询优化器在生成执行计划之前有一个阶段叫做代数树优化,比如说下面这个简单查询:

    查询优化器意识到1=2这个条件是永远不相等的,因此不需要返回任何数据,因此也就没有必要扫描表,从图1执行计划可以看出仅仅扫描常量后确定了1=2永远为false后,就可完成查询。

    那么Check约束呢?

    Check约束可以确保一列或多列的值符合表达式的约束。在某些时候,Check约束也可以为优化器提供信息,从而优化性能,比如看图二的例子。

    图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 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'
    
    

    我们针对Test2007和Test2008两张表结构一模一样的表做了一个分区视图。并对日期列做了Check约束,限制每张表包含的数据都是特定一年内的数据。当我们对视图进行查询并给定不同的筛选条件时,可以看到结果如图3所示。

    图3.不同的条件产生不同的执行计划
    由图3可以看出,当筛选条件为2007年时,自动只扫描2007年的表,2008年的表也是同样。而当查询范围超出了2007和2008年的Check约束后,查询优化器自动判定结果为空,因此不做任何IO操作,从而提升了性能。
    结论
    在Check约束条件为简单的情况下(指的是约束限制在单列且表达式中不包含函数),不仅可以约束数据完整性,在很多时候还能够提供给查询优化器信息从而提升性能。


    4. 禁用CHECK约束

    4.1 语法

    ALTER TABLE table_name
    DISABLE CONSTRAINT constraint_name;
    
    

    4.2 示例

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

     
    5. 约束详细信息查看
    语句:

    --查看约束的详细信息
    select
    constraint_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_name
    DROP CONSTRAINT constraint_name;
    

    6.2 示例

    ALTER TABLE tb_supplier
    DROP CONSTRAINT check_tb_supplier_id;
    
    

    上一篇:详解SQL中drop、delete和truncate的异同
    下一篇:SQL LOADER错误小结
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    SQL Server中Check约束的学习教程 SQL,Server,中,Check,约束,的,