5. 实施数据完整性
本章主题 l 什么是数据完整性 l 数据完整性的实施形式 l 活用约束 l CHECK约束 l PRIMARY KEY 约束 l UNIQUE约束 l 关系链和FOREIGN KEY约束 l 活用默认值 l 活用规则 l 完整性的检查次序
让我们努力掌握这一章的精彩内容吧!!
|
与我的学生共勉:“去做”是一个人最优秀的品质,也是在勤奋、勇敢、守纪、热情之外,一个人最重要的素质。
丁保国
5.1. 什么是数据完整性
数据完整性(Data Integrity):代表数据的正确性、一致性与可靠性,实施数据完整性的目的在于确保数据的质量。
举2个例说明:身份证号不可重复、工资最低不能超过1500
表格 5‑1 数据完整性类型
数据完整性的类型 |
实施此数据完整性的可用方法 |
实体完整性 (Entity Integrity) |
索引 PRIMARY KEY约束 UNIQUE约束 IDENTITY属性 |
域完整性 (Domain Integrity) |
DEFAULT定义 FOREIGH KEY约束 CHECK约束 NOT NULL定义 规则 |
引用完整性 (Referential Integrity) |
FOREIGH KEY约束 CHECK约束 存储过程 触发器 |
用户定义完整性 (User-Defined Integrity) |
CREATE TABLE命令语句中所有字段与表级的约束 存储过程 触发器 |
实体完整性
l 实体完整性:要求表中每一条数据记录都是一个唯一的实体,也就是每一条数据记录必须拥有一个唯一标识。
l 说白了:要求所有数据记录至少必须有一个字段的内容绝对不能发生重复的情况。
域完整性
l 域完整性:要求存入字段中的数据值必须符合特定的条件,以及决定字段是否允许接受NULL。
引用完整性
l 引用完整性:指当添加、修改或删除数据记录时,表间的关联性不可破坏。
用户定义完整性
l 泛指其他所有不属于前3种完整性的业务规则
l 该种业务规则无法利用前3种完整性来完成。
5.2. 数据完整性的实施形式
两种实施形式:
l 声明式数据完整性:是将数据所需符合的条件融入到对象定义中。
ü 特点1:通过直接针对表和字段定义声明的约束,可使声明式数据完整性成为数据库定义的一部分。
ü 特点2:可使用约束、默认值与规则实施声明式数据完整性。
l 程序化数据完整性:通过编写的程序代码来完成
ü 建议较复杂的业务逻辑采用程序化数据完整性
ü 程序化数据完整性可通过相关的程序语言及工具在客户端或服务器端实施
ü SQL Server可使用存储过程和触发器实施程序化数据完整性。
5.3. 活用约束
l 约束(Constraints):最主要的功能是确保存入到字段中的数据符合我们的要求,并确实维护表间的关联性连接。
l 约束以字段为处理对象
l 如果约束的处理对象是某单一字段,称为“列约束”
l 如果约束的处理对象涉及多个字段,称为“表约束”
l 若要更改表现有的约束定义,只能使用“企业管理器”实现。
l 数据库中各个约束的名称绝对不能相同。
约束种类:CHECK、PRIMARY KEY、UNIQUE、FOREIGN KEY
5.4. CHECK约束
CHECK约束:只有符合特定条件和格式的数据才能存入字段中。
l 可以同时在一个字段应用多个CHECK约束
l 当执行INSERT或UPDATE命令时,CHECK约束便会进行检验。
l 自动编号字段、timestamp、uniqueidentifier数据类型字段不能应用 CHECK约束
ü 选中或不选中复选框“创建中检查现存数据”
表示SQL Server在将表的结构保存之前,会先检查表中所有的数据记录是否符合您指定的CHECK约束
ü 选中或不选中复选框“对INSERT和UPDATE强制约束”
表示当执行INSERT或UPDATE命令时,便会应用CHECK约束,以便检查添加或修改后字段中的数据是否符合指定的条件。
ü 选中或不选中复选框“对复制强制约束”
当将表复制到其他的数据库,表的结构定义和数据记录会从原先所在的数据库复制到目标数据库,此时如果不禁用在此表中的CHECK约束,很可能导致数据无法写入目标数据库
新建表时创建CHECK约束
l 使用企业管理器
注意:在操作过程中,并不要指定是“列级约束”还是“表级约束”,是根据该约束逻辑表达式自动确定。
l 使用CREATE TABLE命令
/* 档案名称:Demo61.sql */
CREATE TABLE DemoTable1
(
MemberNo smallint NOT NULL
CONSTRAINT MemberNoChk
CHECK (MemberNo BETWEEN 1 AND 10000),
name varchar(20) NOT NULL,
address varchar(60) NOT NULL
)
/* 档案名称:Demo62.sql ,并未指定约束名称,将由SQL Server自动指派*/
CREATE TABLE DemoTable2
(
MemberNo smallint NOT NULL
CHECK (MemberNo BETWEEN 1 AND 10000),
name varchar(20) NOT NULL,
address varchar(60) NOT NULL
)
/* 档案名称:Demo63.sql */
CREATE TABLE DemoTable3
(
MemberNo smallint NOT NULL,
name varchar(20) NOT NULL,
address varchar(60) NOT NULL,
CONSTRAINT ChkMemberNo ---表级约束
CHECK (MemberNo BETWEEN 1 AND 10000)
)
/* 档案名称:Demo64.sql ,并未指定约束名称,将由SQL Server自动指派*/
CREATE TABLE DemoTable4
(
MemberNo smallint NOT NULL,
name varchar(20) NOT NULL,
address varchar(60) NOT NULL,
CHECK (MemberNo BETWEEN 1 AND 10000)
)
/* 档案名称:Demo65.sql */
CREATE TABLE DemoTable5
(
Id char(10) NOT NULL
CONSTRAINT IdChk
CHECK (Id LIKE '[A-Z][1-2][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'),
JobId char(6) NOT NULL
CONSTRAINT JobIdChk
CHECK (JobId LIKE 'T1C[0-9][0-9][0-9]'),
Name varchar(20) NOT NULL,
Sex char(1) NOT NULL
CONSTRAINT SexChk
CHECK (sex IN ('M','F')),
Birthday datetime NOT NULL
CONSTRAINT AgeChk
CHECK (DATEDIFF(year,Birthday,getdate()) >= 18 ),
Phone char(13) NOT NULL
CONSTRAINT PhoneChk
CHECK (Phone LIKE '([0-9][0-9])[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]' OR
Phone LIKE '([0-9][0-9])[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]' OR
Phone LIKE '([0-9][0-9][0-9])[0-9][0-9][0-9]-[0-9][0-9][0-9]'),
Address varchar(60) NOT NULL,
BloodType varchar(3) NOT NULL
CONSTRAINT BloodTypeChk
CHECK (BloodType IN ('A','B','AB','O','RH+','RH-')),
Hire_Salary money NOT NULL
CONSTRAINT Hire_SalaryChk
CHECK (Hire_Salary >= 15000 AND Hire_Salary <= 100000),
Cur_Salary money NOT NULL
CONSTRAINT Cur_SalaryChk
CHECK (Cur_Salary BETWEEN 15000 AND 200000),
CONSTRAINT SalaryChk
CHECK (Cur_Salary >= Hire_Salary)
)
更改现存CHECK约束的定义
l 更改使用“企业管理器”来实施
修改CHECK约束有以下:
ü CHECK约束的逻辑表达式
ü CHECK约束的名称
ü 选中或不选中复选框“创建中检查现存数据”
ü 选中或不选中复选框“对INSERT和UPDATE强制约束”
ü 选中或不选中复选框“对复制强制约束”
l 程序方式只能更改“是否要在执行INSERT或UPDATE命令时强制约束”
特别提醒:如果一定要用程序方式来更改CHECK约束,只能先删除约束,再新建。
/* 档案名称: Demo66.sql ,将表DemoTable5中名称为PhoneChk的CHECK约束设置成不检查添加或修改后的数据*/
ALTER TABLE DemoTable5
NOCHECK CONSTRAINT
PhoneChk
/* 档案名称: Demo67.sql ,设置CHECK约束PhoneChk会检查或修改后的数据*/
ALTER TABLE DemoTable5
CHECK CONSTRAINT
PhoneChk
/* 档案名称: Demo68.sql ,将表DemoTable5中的3个CHECK约束设置成不检查添加或修改后的数据*/
ALTER TABLE DemoTable5
NOCHECK CONSTRAINT
Hire_SalaryChk, Cur_SalaryChk, SalaryChk
/* 档案名称: Demo69.sql ,将表DemoTable5中所有CHECK约束设置成会检查或修改后的数据*/
ALTER TABLE DemoTable5
CHECK CONSTRAINT
ALL
为表添加CHECK约束
l 使用企业管理器
l 使用ALTER TABLE命令
/* 档案名称: Demo610.sql 为表新建一department字段的同时为其它指定CHECK约束 */
ALTER TABLE DemoTable5
ADD
Department varchar(16) NULL
CONSTRAINT DepartmentChk
CHECK (Department IN ('资讯部','人事部','会计部','业务部'))
如果加入WITH NOCHECK,则不会用新加入的CHECK约束检查现有数据是否符合指定条件
/* 档案名称: Demo611.sql ,为表添加一个表级的CHECK约束*/
ALTER TABLE DemoTable5
WITH CHECK ADD
CONSTRAINT AvgChk --表级约束
CHECK ((Cur_Salary + Hire_Salary)/2 >= 20000)
特别提醒:表级的CHECK约束不一定要涉及多个字段,它也可用来确保某单一字段的内容符合指定条件。
示例:下面的操作中,创建一个表并为它加入字段和CHECK约束:
/* 档案名称: Demo612.sql */
CREATE TABLE DemoTable6
(
Id char(10) NOT NULL
CONSTRAINT ChkId
CHECK (Id LIKE '[A-Z][1-2][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'),
Name varchar(20) NOT NULL
)
/* 档案名称: Demo613.sql ,为表添加数个字段,其中两个字段拥有CHECK约束*/
ALTER TABLE DemoTable6
ADD
Sex char(1) NOT NULL DEFAULT 'F'
CONSTRAINT ChkSex
CHECK (sex IN ('M','F')),
Birthday datetime NOT NULL DEFAULT '1981/1/1'
CONSTRAINT ChkAge
CHECK (DATEDIFF(year,Birthday,getdate()) >= 18 ),
Phone char(13) NULL,
Address varchar(60) NULL,
BloodType varchar(3) NULL DEFAULT 'B',
Hire_Salary money NOT NULL DEFAULT 15000,
Cur_Salary money NOT NULL DEFAULT 15000
/* 档案名称: Demo614.sql ,为表添加数个CHECK约束*/
ALTER TABLE DemoTable6
WITH CHECK ADD
CONSTRAINT ChkBloodType
CHECK (BloodType IN ('A','B','AB','O','RH+','RH-')),
CONSTRAINT ChkHire_Salary
CHECK (Hire_Salary >= 15000 AND Hire_Salary <= 100000),
CONSTRAINT ChkCur_Salary
CHECK (Cur_Salary BETWEEN 15000 AND 200000),
CONSTRAINT ChkSalary
CHECK (Cur_Salary >= Hire_Salary)
删除CHECK约束
Ø 使用企业管理器
Ø 使用ALTER TABLE命令
/* 档案名称: Demo615.sql */
ALTER TABLE DemoTable5
DROP
CONSTRAINT AgeChk
/* 档案名称: Demo616.sql 一次可以删除多个CHECK约束 */
ALTER TABLE DemoTable5
DROP
CONSTRAINT BloodTypeChk, PhoneChk, SexChk
5.5. PRIMARY KEY约束
PRIMARY KEY约束可以将某单一字段或多个字段的组合定义为主键,并保证值绝对是唯一且不可以重复。
一旦成功地将单一字段或多个字段的组合定义为主键之后,当您添加或修改数据时,若发生在主键的源字段添加或修改后的值与其他现存的数据发生重复的情形,SQL Server将会通知这项操作违反唯一性,从而取消这项添加或修改操作。
一个名词:被定义为主键的单一字段或多个字段称之为主键的源字段。
注意:
l 每一个表最多只能拥有一个PRIMARY KEY约束。
l 主键的源字段不允许接受NULL值。
l 事实上,建立主键后,SQL Server会自动创建一个唯一索引。
新建表时创建PRIMARY KEY约束
Ø 使用企业管理器
Ø 使用CREATE TABLE命令
/* 档案名称: Demo617.sql 约束的名称由SQL Server自动指定 */
CREATE TABLE DemoTable7
(
Id char(10) PRIMARY KEY,
Name varchar(16)
)
/* 档案名称: Demo618.sql */
CREATE TABLE DemoTable8
(
Id char(10) CONSTRAINT PK_Id PRIMARY KEY, --指定了约束名称为PK_Id
Name varchar(16)
)
/* 档案名称: Demo619.sql */
CREATE TABLE DemoTable9
(
MemberNo int IDENTITY(5,5) NOT NULL
CONSTRAINT PK_MemberNO PRIMARY KEY,
--将自动编号字段定义为主键
Name varchar(16) NOT NULL
)
/* 档案名称: Demo620.sql */
CREATE TABLE DemoTable10
(
Au_id varchar(11) NOT NULL,
Title_id varchar(6) NOT NULL,
Au_ord tinyint NULL,
Royaltyper int NULL,
CONSTRAINT PK_Au_Id_Title_Id --指定两个字段的组合为主键
PRIMARY KEY (Au_id, Title_id)
)
/* 档案名称: Demo621.sql ,将字段JobNo定义为主键并为之定义一个CHECK约束 * /
CREATE TABLE DemoTable11
(
JobNo smallint NOT NULL
CONSTRAINT PK_JobNo --PRIMARY KEY约束
PRIMARY KEY
CONSTRAINT JobNo_Chk --CHECK约束
CHECK (JobNo BETWEEN 1 AND 10000),
name varchar(20) NOT NULL,
address varchar(60) NOT NULL
)
更改现存PRIMARY KEY约束的定义
Ø 使用企业管理器
特别提醒:如果要以程序控制方式更改现存PRIMARY KEY约束,必须先删除后创建。
为现存表创建PRIMARY KEY约束
Ø 使用企业管理器
Ø 使用ALTER TABLE命令
/* 档案名称: Demo624.sql */
ALTER TABLE DemoTable
ADD
Id int IDENTITY(1,1) NOT NULL
CONSTRAINT PK_Id PRIMARY KEY,
--增加字段的同时,创建PRIMARY KEY
Name varchar(20) NULL
/* 档案名称: Demo625.sql ,为表创建一个主键*/
ALTER TABLE Employee
ADD
CONSTRAINT PK_Emp_Id
PRIMARY KEY (Emp_Id)
/* 档案名称: Demo626.sql */
ALTER TABLE titleauthor
ADD
CONSTRAINT PK_au_id_title_id
PRIMARY KEY (au_id, title_id) --组合字段为PRIMARY KEY
删除PRIMARY KEY约束
Ø 使用企业管理器
Ø 使用ALTER TABLE命令
/* 档案名称: Demo627.sql */
ALTER TABLE titleauthor
DROP
CONSTRAINT PK_au_id_title_id
5.6. UNIQUE约束
UNIQUE约束与PRIMARY KEY约束几乎完全一样,差别主要是:
l 一个表最多只能拥有一个PRIMARY KEY,而可拥有多个UNIQUE约束。
l 被PRIMARY KEY约束定义为主键的一或多个字段是不允许接受NULL值
l 应用UNIQUE约束的一个或多个字段则允许接受NULL值,但是如果在两行中出现组合后的结果为NULL的情况,则视为重复。
一旦创建UNIQUE约束,则SQL Server后自动创建一个唯一索引。
另外,UNIQUE约束还能被一个FOREIGN KEY 约束引用。(这部分在讲到FOREIGN KEY 约束会讲到)
新建表时创建UNIQUE约束
Ø 使用企业管理器
n “表和索引属性”按钮,切换至“索引/键”选项卡。
n 请务必选中“创建UNIQUE”,并确认单选按键“约束”已被选中。
Ø 使用CREATE TABLE命令(方法与PRIMARY KEY约束极其相似)
/* 档案名称: Demo628.sql 约束的名称由SQL Server自动指定*/
CREATE TABLE DemoTable14
(
Id char(10) NOT NULL PRIMARY KEY,
JobId char(6) NOT NULL UNIQUE,
Name varchar(16)
)
/* 档案名称: Demo629.sql */
CREATE TABLE DemoTable15
(
Id char(10) NOT NULL
CONSTRAINT PK_Id_DemoTable15 PRIMARY KEY,
--指定了约束名称
JobId char(6) NOT NULL
CONSTRAINT UQ_JobId_DemoTable15 UNIQUE,
--指定了约束名称
Name varchar(16)
)
/* 档案名称: Demo630.sql */
CREATE TABLE DemoTable16
(
Id int IDENTITY(10,10) NOT NULL
CONSTRAINT PK_Id_DemoTable16
PRIMARY KEY CLUSTERED, --PRIMARY KEY约束
JobId char(6) NOT NULL
CONSTRAINT UQ_JobId_DemoTable16 UNIQUE, --UNIQUE约束
LicenseNo char(6) NOT NULL
CONSTRAINT UQ_LicenseNo_DemoTable16 UNIQUE,
--UNIQUE约束
Name varchar(16) NULL,
Phone char(11) NULL,
CellularPhone int NULL,
CONSTRAINT UQ_Name_Phone_DemoTable16
UNIQUE (Name, Phone), --UNIQUE约束,组合字段
CONSTRAINT UQ_Name_CellularPhone_DemoTable16
UNIQUE (Name, CellularPhone) --UNIQUE约束,组合字段
)
更改现存UNIQUE约束的定义
Ø 使用企业管理器
特别提醒:如果要以程序控制方式更改现存UNIQUE约束,必须先删除后创建。
为现存表创建UNIQUE约束
Ø 使用企业管理器
Ø 使用ALTER TABLE命令
/* 档案名称: Demo634.sql */
ALTER TABLE DemoTable20
ADD
MemberNo int IDENTITY(1,1) NOT NULL
CONSTRAINT UQ_MemberNo_DemoTable20 UNIQUE,
Name varchar(20) NULL
/* 档案名称: Demo635.sql */
ALTER TABLE DemoTable21
ADD
Id uniqueidentifier NOT NULL DEFAULT NEWID()
CONSTRAINT UQ_Id_DemoTable21 UNIQUE,
Name varchar(20) NULL,
Birthday datetime NULL,
CONSTRAINT UQ_Name_Birthday_DemoTable21
UNIQUE (Name, Birthday)
/* 档案名称: Demo636.sql */
ALTER TABLE DemoTable22
ADD
CONSTRAINT UQ_Id_DemoTable22
UNIQUE (Id)
/* 档案名称: Demo637.sql */
ALTER TABLE DemoTable23
ADD
CONSTRAINT UQ_au_id_title_id_DemoTable23
UNIQUE (au_id, title_id)
/* 档案名称: Demo638.sql */
CREATE TABLE DemoTable24
(
Id char(10) NOT NULL
CONSTRAINT PK_Id_DemoTable24
PRIMARY KEY CLUSTERED,
LicenseNo char(6) NOT NULL,
Address varchar(60) NULL
)
ALTER TABLE DemoTable24
ADD
MemberNo int IDENTITY(10,10) NOT NULL
CONSTRAINT UQ_MemberNo_DemoTable24 UNIQUE,
Name varchar(20) NULL,
Birthday datetime NULL,
CONSTRAINT UQ_Name_Birthday_DemoTable24
UNIQUE (Name, Birthday),
CONSTRAINT UQ_LicenseNo_DemoTable24
UNIQUE (LicenseNo)
删除UNIQUE约束
Ø 使用企业管理器
Ø 使用ALTER TABLE命令
特别提醒:SQL Server不允许使用企业管理器或DROP INDEX命令直接删除UNIQUE约束的唯一索引,事实上不需要这样做,因为当将UNIQUE约束删除时,UNIQUE约束的唯一索引会自动一并删除。
/* 档案名称: Demo639.sql */
ALTER TABLE DemoTable24
DROP
CONSTRAINT UQ_LicenseNo_DemoTable24
5.7. 关系键与FOREIGN KEY约束
SQL Server是一个关系型数据库管理系统,也就是说它能够利用表间的关系来管理数据。
链接表的实质做法:基于父表的共同字段的主键(Primary key)和子表共同字段的外键来创建关系(Foreign key)。其中父表的主键使用PRIMARY KEY约束定义,子表的外键由FOREIGN KEY约束定义。
FOREIGN KEY约束的功能已呼之欲出。
FOREIGN KEY约束最主要的用途:将表的某单一字段或多个字段的组合定义为外键,并决定该外键要链接到哪一个表的主键,以及维护关联表间的引用完整性。
特别提醒:FOREIGN KEY约束不一定要将外键链接到其他表的主键,也可链接到其他表的UNIQUE约束所应用的字段,这意味着,父表除了其主键与子残冬腊月的外键创建关系之外,还可通过其UNIQUE约束的字段与子表的外键创建关系。
注意:
Ø 外键的源字段内容可以是重复的,而且允许接受NULL值
Ø 一个表可以拥有多个FOREIGN KEY约束。一个表最多可拥有253个FOREIGN KEY约束。
Ø FOREIGN KEY约束所指定的字段数目和数据类型,必须与其链接到的PRIMARY KEY或UNIQUE约束所指定的字段数目和数据类型完全相同。
Ø FOREIGN KEY约束并不会自动创建索引!!!最好自行创建索引以提高查询效率(在索引一章要谈到)
Ø
创建FOREIGN KEY约束
必须有一个认识:所谓创建FOREIGN KEY约束,其实就是在创建表间的关系。
Ø 使用数据库关系图创建FOREIGN KEY约束
Ø 以程序方式创建FOREIGN KEY约束
在CREATE TABLE或ALTER TABLE命令中加入下面一段参数:
[CONSTRAINT 约束名称]
[FOREIGN KEY ]
REFERENCES 父表名称(父表主键或UNIQUE约束的字段名列表)
/* 档案名称: Demo641.sql */
CREATE TABLE Customers
(
CustomerID nchar(5) NOT NULL PRIMARY KEY,
CompanyName nvarchar(40) NOT NULL ,
ContactName nvarchar(30) NULL ,
)
CREATE TABLE Orders
(
OrderID int IDENTITY(1, 1) NOT NULL ,
CustomerID nchar(5) NULL
CONSTRAINT FK_Orders_Customers
FOREIGN KEY
REFERENCES Customers(CustomerID),
OrderDate datetime NULL ,
)
/* 档案名称: Demo642.sql */
CREATE TABLE Customers
(
CustomerID nchar(5) NOT NULL PRIMARYKEY,
CompanyName nvarchar(40) NOT NULL ,
ContactName nvarchar(30) NULL ,
)
CREATE TABLE Orders
(
OrderID int IDENTITY(1, 1) NOT NULL ,
CustomerID nchar(5) NULL,
OrderDate datetime NULL ,
)
ALTER TABLE Orders
ADD
CONSTRAINT FK_Orders_Customers
FOREIGNKEY (CustomerID)
REFERENCES Customers(CustomerID)
/* 档案名称: Demo643.sql */
ALTER TABLE Orders
ADD
CONSTRAINT FK_Orders_Customers
FOREIGNKEY (CustomerID)
REFERENCES Customers(CustomerID),
CONSTRAINT FK_Orders_Employees
FOREIGNKEY (EmployeeID)
REFERENCES Employees(EmployeeID),
CONSTRAINT FK_Orders_Shippers
FOREIGNKEY (ShipVia)
REFERENCES Shippers (ShipperID)
/* 档案名称: Demo644.sql */
ALTER TABLE ChildTable
ADD
CONSTRAINT FK_ChildTable_Sales
FOREIGNKEY (stor_id, ord_num, title_id)
REFERENCES Sales(stor_id, ord_num, title_id)
更改FOREIGN KEY约束的定义
Ø 使用数据库关系图修改FOREIGN KEY约束
编辑数据库关系图,右键点击“关系链接的关系线”,查看“属性”。
特别提醒:无法以程序控制方式编辑编辑青关系,除非先将原有的FOREIGN KEY约束删除,再新建一个符合目前所需的FOREIGN KEY约束。
删除FOREIGN KEY约束
Ø 使用数据库关系图删除FOREIGN KEY约束
从关系图中,选中“关系链接的关系线”,从右键快捷菜单中选择“从数据库中删除关系”。
下面的范例先创建各个彼此相关联的表,然后再使用ALTER TABLE命令删除它们之间的关系(让我们好好欣赏一下这段精彩的历程吧!!):
/* 档案名称: Demo645.sql 创建表*/
CREATE TABLE authors
(
au_id char(6) NOT NULL PRIMARY KEY,
au_name varchar (20) NOT NULL
)
CREATE TABLE titles
(
title_id char(6) NOT NULL PRIMARY KEY,
title varchar(80) NOT NULL,
pub_id char(4) NOT NULL,
)
CREATE TABLE publishers
(
pub_id char(4) NOT NULL PRIMARY KEY,
pub_name varchar(40) NULL
)
CREATE TABLE titleauthor
(
au_id char(6) NOT NULL,
title_id char(6) NOT NULL,
au_ord tinyint NULL,
royaltyper int NULL,
PRIMARY KEY (au_id, title_id)
)
/* 档案名称: Demo646.sql 将表publishers与title链接起来 */
ALTER TABLE titles ADD
CONSTRAINT FK_titles_publishers
FOREIGN KEY (pub_id)
REFERENCES publishers (pub_id)
/* 档案名称: Demo647.sql 将titleauthor与authors、title链接起来*/
ALTER TABLE titleauthor
ADD
CONSTRAINT FK_titleauthor_authors
FOREIGN KEY (au_id)
REFERENCES authors (au_id),
CONSTRAINT FK_titleauthor_titles
FOREIGN KEY (title_id)
REFERENCES titles (title_id)
/* 档案名称: Demo648.sql 删除表publishers与title的链接*/
ALTER TABLE titles
DROP CONSTRAINT FK_titles_publishers
/* 档案名称: Demo649.sql 删除 titleautho与rauthors、title的链接起来*/
ALTER TABLE titleauthor
DROP
CONSTRAINT FK_titleauthor_authors,FK_titleauthor_titles
5.8. 活用默认值
让我们看一看这个顺序:
Ø 如果您为此字段定义默认值(Default),默认值将成为此字段的内容。
Ø 如果您并未给此字段定义默认值,而且此字段允许接受NULL值,则NULL值将成为该字段的内容。
Ø 如果您并未给此字段定义默认值,而且此字段不允许接受NULL值,将会出现错误!
一个例子:
地址字段,如果目前输入时无法确定该输入什么内容,与其让用户随便输入一个数据值,不如由系统以默认值的方式给字段指派一个数据,如“目前未知”。
SQL Server提供了两种方式给字段定义默认值:
Ø DEFAULT定义
Ø DEFAULT对象
但不能犯下面两个错误:
Ø 默认值的数据类型必须与字段的数据类型相同
Ø 字段的默认值不可与CHECK约束或规则相违背
DEFAULT定义
即默认值可以成为表结构定义的一部分。在定义表结构或修改表结构的同时,一并定义字段的默认值。
Ø 企业管理器
Ø SQL语句
/* 档案名称: Demo650.sql */
CREATE TABLE DemoTable25
(
Id uniqueidentifier NOT NULL DEFAULT newid()PRIMARY KEY,
Name varchar(16) NOT NULL,
Phone varchar(11) NOT NULL,
Birthday datetime NOT NULL
)
/* 档案名称: Demo651.sql */
ALTER TABLE DemoTable25
ADD
Address varchar(60) NOT NULL DEFAULT '台湾省台北市',
Income money NOT NULL DEFAULT 10000,
DEFAULT '姓名未知' FOR Name, --为原有的3个字段定义默认值
DEFAULT getdate() FOR Birthday,
DEFAULT '电话未知' FOR Phone
DEFAULT对象
DEFAULT对象是一个独立存在的数据库对象。什么是独立存在的?
最大的好处:
只需创建一次,就可以被同一数据库中所有表的不同字段共享。
Ø 企业管理器
删除字段的默认值
直接将默认值文本框中的内容删除即可。
5.9. 活用规则
规则(Rules)与CHECK约束的用途完全相同,都是用来设置只有特定条件和的数据才能存入字段中。
与CHECK约束的最大不同:
规则是一个独立的数据库对象。
最大的好处:
只需创建一次,就可以被同一数据库中所有表的不同字段共享。
一点建议:由于CHECK约束符合ANSI SQL标准,比较之下,还是建议最好采用CHECK约束。
规则的逻辑表达式一定要包含一个变量(前面有一个@符号),将该规则绑定到某个字段后,将来用户写入该字段中的数据值将会自动存入该变量中。
特别提醒:将规则绑定到字段时,SQL Server并不会立即检查字段中的现有数据是否符合规则所制定的条件,只有当修改字段内容或添加数据记录时,才会使用该规则进行检验。。
5.10. 完整性的检查次序
Ø 应用默认值
Ø 检查是否允许存放NULL值
Ø CHECK约束
Ø FOREIGN KEY约束
Ø PRIMARY KEY与UNIQUE约束
Ø 触发器
第5章 结束 |