zoukankan      html  css  js  c++  java
  • Ms SQL Server 约束和规则

    一、SQL约束

     约束定义关于列中允许值的规则,是强制完整性的标准机制。 

    使用约束优先于使用触发器、规则和默认值。查询优化器也使用约束定义生成高性能的查询执行计划。

    1:类型
    约束的类型一共分三种
    域约束: 涉及一个或多个列,(限制某一列的数据大于0)
    实体约束: 相同的值不能存在于其他的行中
    引用完整性约束: 一个表中的一个列与某个表中的另一个列的值匹配
    2:命名
    约束是可以命名的 一般这样命名:
    pk_customer_***
    pk代表主键 customer代表主键所在的表后面是你自己定义的(要确保整个名称的唯一性)
    3:主键约束
    主键约束:一般就是id, 一个表中最多有一个主键
    例子1
    use accounting
    create table employee
    (

    id int identity not null,
    firstname varchar(20) not null
    )
    例子2
    use accounting
    alter table employee
    add constraint pk_employeeid
    primary key (id)

    4:外键约束
    外键约束用在确保数据完整性和两个表之间的关系上
    先看例子
    create table orders
    (
    id int identity not null primary key,
    customerid int not null foreign key references customer(id),
    orderdate smalldatetime not null,
    eid int not null
    )
    注意:这个表的外键必须是另一个表的主键!
    在现有表上添加外键
    alter table orders
    add constraint fk_employee_creator_order
    foreign key (eid) references employee(employeeid)
    使用表自引用
    表内至少要有一行数据才可以这么做
    alter table employee
    add constraint fk_employee_has_manager
    foreign key (managerid) references employee(employeeid)
    创建表的时候做表自引用 就可以忽略 foreign key 语句
    表自引用的外键列 必须允许为null 要不是不允许插入的(避免对最初行的需要)

    一个表与另一个表有约束,这个表是不能被删除的
    级联操作
    先看例子
    create table orderdetails
    (
    orderid int not null ,
    id int not null ,
    description varchar(123) not null,
    --设置主键
    constraint pkOrderdetails primary key (orderid,id),
    --设置外键,级联操作
    constraint fkOrderContainsDetails
    foreign key (orderid)
    references orders(orderid)
    on update no action
    on delete cacade
    )

    on delete cacade 当删除父记录时 同时删除该记录
    也就是当删除orders表中的一条记录,
    与之相关的orderdetails表中的记录也将被删除
    级联的深度是没有限制的,但是每个外键都必须设置on delete cacade
    no action是可选的

    5:unique约束
    unique约束与主键约束类似,同样也是要求指定的列有唯一的值
    但是一个表中可以有多个unique约束的列,同时这个列允许存在null值。(最多有一个null值)
    看例子:
    create table shippers
    (
    id int indentity not null primery key,
    zip varchar(10) not null ,
    phoneno varchar(14) not null unique

    )
    例子二:
    alter table employee
    add constraint ak_employeeSSN
    unique(ssn)

    6:check约束
    check不局限于一个特定的列,可以约束一个列,也可以通过某个列来约束另一个列
    定义check约束使用的规则与where子句中的基本一样
    下面我写几个
    between 1 and 12
    like '[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
    in ('ups','fed ex','usps')
    price >=0
    shipdate >= orderdate
    看例子:
    alter table customers
    add constraint cn_customerDateinsystem
    check
    (dateinsystem <= getdate())
    getdate()函数得到当前时间,上面这个例子的意思是dateinsystem列的数据不能大于当前时间
    现在如果给这个列插入一个明天的时间,就会出错

    7:default约束
    如果插入的新行在定义了默认值的列上没有给出值,那么这个列上的数据就是定义的默认值
    默认值只在insert语句中使用
    如果插入的记录给出了这个列的值,那么该列的数据就是插入的数据
    如果没有给出值,那么该列的数据总是默认值

    8:禁用约束
    在创建约束之前,数据库中已经有一些不符合规矩的数据存在。
    创建约束之后,又想加入一些不符合规矩的数据。
    这些时候就要禁用约束。primary key unique约束 这对孪生约束是不能禁用的
    对一个已经存在数据的表加一个约束:
    alter table customers
    add constraint cn_customerPhoneNo
    check
    (phone like '([0-9][0-9][0-9])[0-9][0-9][0-9][0-9][0-9][0-9]')
    如果表内有不符合这个约束的记录,sqlserver就会报错
    如果这样写,就不会报错了
    alter table customers
    with no check
    add constraint cn_customerPhoneNo
    check
    (phone like '([0-9][0-9][0-9])[0-9][0-9][0-9][0-9][0-9][0-9]')
    如果需要把一些不符合规矩的数据加入到表中怎么办

    这时候就需要临时禁用现有的约束:
    alter table customers
    nocheck
    constraint cn_customerPhoneNo
    --允许不带套插入,此处的名称是前面定义的
    insert into customer (phone) values (123456)
    --开始不带套插入!
    alter table customers
    check
    constraint cn_customerPhoneNo
    --下次插入要带套

     

    9. FOREIGN KEY约束标识表之间的关系。

       
    一个表的外键指向另一个表的候选键。当外键值没有候选键时,外键可防止操作保留带外键值的行。在下例中,order_part 表建立一个外键引用前面定义的part_sample表。通常情况下,order_part在order表上也有一个外键,下面只不过是一个简单示例。
    CREATE TABLE order_part
    (
    order_nmbr int,
    part_nmbr int
    FOREIGN KEY REFERENCES part_sample(part_nmbr) ON DELETE NO ACTION,
    qty_ordered int
    )
    如果一个外键值没有候选键,则不能插入带该值(NULL除外)的行。如果尝试删除现有外键指向的行,ON DELETE子句将控制所采取的操作。
    ON DELETE子句有两个选项:
    A、NO ACTION指定删除因错误而失败。
    B、CASCADE 指定还将删除包含指向已删除行的外键的所有行。
    如果尝试更新现有外键指向的候选键值,ON UPDATE 子句将定义所采取的操作。它也支持NO ACTION和CASCADE选项。

    10、列约束和表约束

     
    约束可以是列约束或表约束:
    列约束被指定为列定义的一部分,并且仅适用于那个列(前面的示例中的约束就是列约束)。
    表约束的声明与列的定义无关,可以适用于表中一个以上的列。
    当一个约束中必须包含一个以上的列时,必须使用表约束。
    例如,如果一个表的主键内有两个或两个以上的列,则必须使用表约束将这两列加入主键内。假设有一个表记录工厂内的一台计算机上所发生的事件。假定有几类事件可以同时发生,但不能有两个同时发生的事件属于同一类型。这一点可以通过将type列和time列加入双列主键内来强制执行。
    CREATE TABLE factory_process
    (
    event_type int,
    event_time datetime,
    event_site char(50),
    event_desc char(1024),
    CONSTRAINT event_key PRIMARY KEY(event_type,event_time)
    )



    二、规则

     
    规则是一个向后兼容的功能,用于执行一些与CHECK约束相同的功能。CHECK约束是用来限制列值的首选标准方法。CHECK约束比规则更简明,一个列只能应用一个规则,但是却可以应用多个CHECK约束。CHECK约束作为CREATE TABLE 语句的一部分进行指定,而规则以单独的对象创建,然后绑定到列上。   
    下例创建一个规则,执行与前面主题中的CHECK约束示例相同的功能。SQL Srver2005 首选的方法是 CHECK 约束。
    CREATE RULE id_chk AS @id BETWEEN 0 and 10000
    GO
    CREATE TABLE cust_sample
    (
    cust_id int
    PRIMARY KEY,
    cust_name char(50),
    cust_address char(50),
    cust_credit_limit money,
    )
    GO
    sp_bindrule id_chk,'cust_sample.cust_id'
    GO


    再看例子:
    Create rule SalaryRule
    as @salary >0;
    sp_bindrule 'SalaryRule' , 'Employee.Salary'
    第一句定义了一个规则叫SalaryRule
    进行比较的事物是一个变量
    这个变量的值是所检查的列的值
    第二句把规则绑定到某个表的一个列上

    规则和ckeck约束很相似,
    但是规则只作用在一个列上
    一个规则可以绑定在多个列上,但是它不会意识到其他列的存在
    check可以定义column1>=column2

    取消规则
    exec sp_unbindrule 'Employee.Salary'

    删除规则
    Drop rule SalaryRule

    1:默认值


    默认值与default约束类似(有区别的,但是我说不清楚)
    先看例子:
    create default salarydefault
    as 0;
    exec sp_binddefault
    'salarydefault' , 'employee.salary';
    取消默认值:
    exec sp_unbinddefault 'employee.salary'
    删除默认值:
    drop default 'salarydefault'

    外记:

    在Create Table 语句的属性清单后,加上外部码说明子句,格式为:
    FOREIGN KEY <属性名表1> REFERENCES <表名>(<属性名表2>)
    eno char(4) CONSTRAINT PK_employee PRIMARY KEY,
    dno char(4)CONSTRAINT FK_employee FOREIGN KEY REFERENCES department(dno);
    ALTER TABLE语句来更新与属性或表有关的各种约束。如:
    ALTER TABLE employee DROP CONSTRAINT FK_employee;
    ALER TABLE Salary ADD CONSTRAINT RightSalary CHECK(Insure+Fund<Rest);

  • 相关阅读:
    【读书笔记】iOS-UDID
    【读书笔记】iOS-优化内存
    【读书笔记】iOS-处理内存警告
    【读书笔记】iOS-方法声明
    【读书笔记】iOS-属性
    【读书笔记】iOS-强类型与弱类型
    【读书笔记】iOS-Objective-C编程
    【读书笔记】iOS-Interface Builder
    【读书笔记】iOS-开发者证书
    【读书笔记】iOS-成为一名开发者
  • 原文地址:https://www.cnblogs.com/sczw-maqing/p/3253102.html
Copyright © 2011-2022 走看看