扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
来源: 2007年05月09日
关键字:T-SQL SQL Server 约束 Tim Chapman
所有优秀的DBA和开发者都应该拥有在数据库中逻辑定义约束的能力,也应该拥有使用TSQL代码定义约束的能力。这篇文章向我们介绍了如何用TSQL定义约束,并探讨了如何使用TSQL的不同方式来定义这些约束。
约束的类型
我主要关注四种类型的约束:主关键字约束、外键约束、唯一性约束和检查约束。下面对每一种类型都进行了简单描述。
主关键字约束
在一个给定的表中,这种约束主要用来确保该表中每一条记录的某一列或者多列集合都只有唯一的值。这样,你就可以通过在表中唯一的定义记录来确保数据的完整性了。
一个表中只能定义一个主关键字,并且主关键字所包含的那些列不能是空值。主关键字可以在创建表的时候定义,也可以在创建表之后再添加定义。
下面的脚本是在创建表的时候在一列上定义了主关键字约束:
IF OBJECT_ID('SalesHistory')>0
DROP TABLE SalesHistory;
GO
CREATE TABLE [dbo].[SalesHistory](
[SaleID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
[Product] [char](150) NULL,
[SaleDate] [datetime] NULL,
[SalePrice] [money] NULL
)
GO
下面的脚本也是在表创建的时候定义了主关键字约束。但是这种方法为该约束进行了命名,并且在必要的时候还可以在多列上创建约束:
IF OBJECT_ID('SalesHistory')>0
DROP TABLE SalesHistory;
GO
CREATE TABLE [dbo].[SalesHistory](
[SaleID] [int] IDENTITY(1,1) NOT NULL,
[Product] [char](150) NULL,
[SaleDate] [datetime] NULL,
[SalePrice] [money] NULL,
CONSTRAINT pk_SaleID PRIMARY KEY (SaleID)
)
GO
下面的脚本是在表创建后再对该表创建主关键字约束:
IF OBJECT_ID('SalesHistory')>0
DROP TABLE SalesHistory;
GO
CREATE TABLE [dbo].[SalesHistory](
[SaleID] [int] IDENTITY(1,1) NOT NULL,
[Product] [char](150) NULL,
[SaleDate] [datetime] NULL,
[SalePrice] [money] NULL
)
GO
ALTER TABLE SalesHistory
ADD CONSTRAINT pk_SaleID PRIMARY KEY (SaleID)
GO
外键约束
这个约束主要是用来在一个表中限制它的某些列的值与另一个表的某些列的值的关联关系。在两个表之间的连接需要使用一个“查找表”,这个表中包括接受值的列表;这个列表必须包括唯一约束或者主关键字约束。在两个表之间建立约束之后,在外键表中对约束域中的所有数据进行修改都会引起效验,以确保数据更新或者插入的时候被约束在查找表中。
Listing A中的脚本创建了一个ProductTypes表和一个SalesHistory表,其中,ProductTypes表将作为查找表,SalesHistory表将引用ProductTypes表中的ProductID列的值。如果现在没有在表中对约束进行定义,那么这时候,我们就应该返回并对它添加约束。你能根据Listing B中的脚本来操作。
先前的脚本包括WITH NOCHECK语句。我使用这条语句,是为了在添加约束的时候不去考虑表中现有的值是否符合约束条件。这样的话,表中已有的任何记录如果违反了新增加的约束的话,都将被忽略,使用WITH NOCHECK可以方便创建约束。这时候约束只能应用在新输入到SalesHistory表中的记录上。
唯一性约束
唯一性约束保证一列或者多列集合中的值是唯一的。唯一性约束与主关键字约束有些相似,因为它们都对一列或者多列集合提供唯一性保证。主关键字约束在定义的时候自动就有了唯一性约束。
这两种约束有两个区别:(1)在每个表中只能有一个主关键字约束,但是在每个表中可以有多个唯一性约束;(2)主关键字约束不允许有空值,然而唯一性约束允许有空值(虽然它允许在每个域只有一个空值)。
下面的脚本是在创建表的时候对表的SaleID列创建了一个唯一性约束:
IF OBJECT_ID('SalesHistory')>0
DROP TABLE SalesHistory;
GO
CREATE TABLE [dbo].[SalesHistory](
[SaleID] [int] NOT NULL UNIQUE,
[Product] [char](150) NULL,
[SaleDate] [datetime] NULL,
[SalePrice] [money] NULL
)
GO
下面的脚本也是在表创建的时候创建了一个唯一性约束,但是,它还给约束进行了命名,如果有必要也可以用这种方式在多列上定义唯一性约束:
IF OBJECT_ID('SalesHistory')>0
DROP TABLE SalesHistory;
GO
CREATE TABLE [dbo].[SalesHistory](
[SaleID] [int] NOT NULL,
[Product] [char](150) NULL,
[SaleDate] [datetime] NULL,
[SalePrice] [money] NULL,
CONSTRAINT uc_SaleID UNIQUE (SaleID)
)
GO
下面的脚本是在SalesHistory表创建后,通过改变表来创建唯一性约束:
IF OBJECT_ID('SalesHistory')>0
DROP TABLE SalesHistory;
GO
CREATE TABLE [dbo].[SalesHistory](
[SaleID] [int] NOT NULL,
[Product] [char](150) NULL,
[SaleDate] [datetime] NULL,
[SalePrice] [money] NULL
)
GO
ALTER TABLE SalesHistory
ADD CONSTRAINT uc_SaleID UNIQUE(SaleID)
GO
Check约束
这种约束在一列上对值的范围,或者域进行了限制。检查约束检查可接受的值与定义在约束中的逻辑表达式是否一样。这种约束与外键约束类似,因为它们都在表的指定行中对一列或者多列集合的可接受的值进行管理。你可以在列中或者表中创建检查约束。在单列上的检查约束允许对那些列有唯一确定的值,然而,表的检查约束能根据其它域中的列对确定的列中的值进行限制。
下面的脚本对SalesHistory表中的SalePrice列创建了一个检查约束,这个约束限制SalePrice的值必须大于4。任何企图在SalePrice列中输入的值如果小于4的话,都会报错。
IF OBJECT_ID('SalesHistory')>0
DROP TABLE SalesHistory;
GO
CREATE TABLE [dbo].[SalesHistory](
[SaleID] [int] NOT NULL,
[Product] [char](150) NULL,
[SaleDate] [datetime] NULL,
[SalePrice] [money] NULL CHECK (SalePrice > 4)
)
GO
Listing C中的脚本在SalesHistory表中创建了一个检查约束,这个约束限制了SalePrice的值必须大于10,同时Product列中的值必须有Computer。这不是一个非常实用的约束,但是它告诉我们如何对一个表的多列设置约束。Listing D与Listing C中的脚本一样有效,但是它是在表创建之后再定义约束的。
责任编辑:德东
IF OBJECT_ID('SalesHistory')>0
DROP TABLE SalesHistory;
GO
IF OBJECT_ID('ProductTypes')>0
DROP TABLE ProductTypes;
GO
CREATE TABLE ProductTypes
(
ProductID SMALLINT,
ProductDescription VARCHAR(255),
CONSTRAINT pk_ProductID PRIMARY KEY (ProductID)
)
GO
CREATE TABLE [dbo].[SalesHistory](
[SaleID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
[ProductID] SMALLINT NULL,
[SaleDate] [datetime] NULL,
[SalePrice] [money] NULL--,
CONSTRAINT fk_SalesHistoryProductID FOREIGN KEY (ProductID) REFERENCES ProductTypes(ProductID)
)
GO
ALTER TABLE SalesHistory WITH NOCHECK
ADD CONSTRAINT fk_SalesHistoryProductID FOREIGN KEY (ProductID) REFERENCES ProductTypes(ProductID)
IF OBJECT_ID('SalesHistory')>0
DROP TABLE SalesHistory;
GO
CREATE TABLE [dbo].[SalesHistory](
[SaleID] [int] NOT NULL,
[Product] [char](150) NULL,
[SaleDate] [datetime] NULL,
[SalePrice] [money] NULL,
CONSTRAINT chk_ProductSalePrice CHECK (SalePrice>10 AND Product='Computer')
)
GO
ALTER TABLE SalesHistoryADD CONSTRAINT chk_ProductSalePrice CHECK (SalePrice>10 AND Product='Computer')
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。