SQL 约束 (Constraints)


引言

--• NOT NULL
--• UNIQUE
--• PRIMARY KEY
--• FOREIGN KEY
--• CHECK
--• DEFAULT

 

1.SQL NOT NULL 约束

1.1、强制 "Id_P" 列和 "LastName" 列不接受 NULL 值(默认为NULL)

CREATE TABLE Persons
(
Id_P int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)

 

 

2.SQL UNIQUE 约束

2.1、在 "Persons" 表创建时在 "Id_P" 列创建 UNIQUE 约束

CREATE TABLE Persons
(
Id_P int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
UNIQUE (Id_P)
)

 

或者:

CREATE TABLE Persons
(
Id_P int NOT NULL UNIQUE,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)

 

2.2、如果需要命名 UNIQUE 约束,以及为多个列定义 UNIQUE 约束

CREATE TABLE Persons
(
Id_P int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CONSTRAINT UQ_PersonID UNIQUE (Id_P,LastName)
)

 

2.3、当表已被创建时,如需在 "P_Id" 列创建 UNIQUE 约束

ALTER TABLE Persons ADD UNIQUE (P_Id)

 

2.4、需命名 UNIQUE 约束,并定义多个列的 UNIQUE 约束

ALTER TABLE Person    
ADD CONSTRAINT UQ_PersonID UNIQUE (P_Id,LastName)

 

2.5、撤销 UNIQUE 约束

ALTER TABLE Persons
DROP CONSTRAINT UQ_PersonID

 

 

 

3.SQL PRIMARY KEY 约束

--主键必须包含唯一的值。
--主键列不能包含 NULL 值。
--每个表应该都一个主键,并且每个表只能有一个主键。

3.1、在 "Persons" 表创建时在 "Id_P" 列创建 PRIMARY KEY约束

--1
CREATE TABLE Persons
(
Id_P int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
PRIMARY KEY (Id_P)
)

--2
CREATE TABLE Persons
(
Id_P int NOT NULL PRIMARY KEY,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)

 

3.2、需要命名 PRIMARY KEY 约束,以及为多个列定义 PRIMARY KEY 约束

CREATE TABLE Persons
(
Id_P int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CONSTRAINT PK_PersonID PRIMARY KEY (Id_P,LastName)
)

 

3.3、在表已存在的情况下为 "Id_P" 列创建 PRIMARY KEY 约束

ALTER TABLE Persons
ADD PRIMARY KEY (Id_P)

 

3.4、需要命名 PRIMARY KEY 约束,以及为多个列定义 PRIMARY KEY 约束

ALTER TABLE Persons
ADD CONSTRAINT PK_PersonID PRIMARY KEY (Id_P,LastName)

 

3.5、撤销 PRIMARY KEY 约束

ALTER TABLE Persons
DROP CONSTRAINT PK_PersonID

 

 

 

4.SQL FOREIGN KEY 约束

--一个表中的 FOREIGN KEY 指向另一个表中的 PRIMARY KEY

4.1、在 "Orders" 表创建时为 "Id_P" 列创建 FOREIGN KEY

CREATE TABLE Orders
(
O_Id int NOT NULL PRIMARY KEY,
OrderNo int NOT NULL,
Id_P int FOREIGN KEY REFERENCES Persons(Id_P)
)

 

4.2、需要命名 FOREIGN KEY 约束,以及为多个列定义 FOREIGN KEY 约束

CREATE TABLE Orders
(
O_Id int NOT NULL,
OrderNo int NOT NULL,
Id_P int,
PRIMARY KEY (O_Id),
CONSTRAINT FK_PerOrders FOREIGN KEY (Id_P)
REFERENCES Persons(Id_P)
)

 

4.3、在 "Orders" 表已存在的情况下为 "Id_P" 列创建 FOREIGN KEY 约束

ALTER TABLE Orders
ADD FOREIGN KEY (Id_P)
REFERENCES Persons(Id_P)

 

4.4、需要命名 FOREIGN KEY 约束,以及为多个列定义 FOREIGN KEY 约束

ALTER TABLE Orders
ADD CONSTRAINT FK_PerOrders
FOREIGN KEY (Id_P)
REFERENCES Persons(Id_P)

 

4.5、撤销 FOREIGN KEY 约束

ALTER TABLE Orders
DROP CONSTRAINT FK_PerOrders

 

【高级应用】

-- 创建测试主表. ID 是主键.
-- 班级表.
CREATE TABLE test_main_class (
  id      INT   NOT NULL,
  value   VARCHAR(20),
  PRIMARY KEY(id)  
);


-- 创建测试子表. 
-- 学生表.
CREATE TABLE test_sub_student (
  id      INT  NOT NULL,
  main_id INT  DEFAULT 0,
  value   VARCHAR(10),
  PRIMARY KEY(id)  
);


-- 插入测试主表数据.
INSERT INTO test_main_class(id, value) VALUES (0, '暂无班级');
INSERT INTO test_main_class(id, value) VALUES (1, '2015级123班');
INSERT INTO test_main_class(id, value) VALUES (2, '2015级124班');


-- 插入测试子表数据.
INSERT INTO test_sub_student(id, main_id, value) VALUES (1, 1, '陌轩');
INSERT INTO test_sub_student(id, main_id, value) VALUES (2, 2, '思梦'); 

默认外键约束方式

ALTER TABLE test_sub_student ADD CONSTRAINT main_id_cons FOREIGN KEY (main_id) REFERENCES test_main_class; 

添加外键后,在删除数据(运行结果会提示错误,因为test_mian_class的数据已经给test_sub_student使用) 

DELETE test_main_class WHERE ID = 1;

 删除外键约束 

ALTER TABLE test_sub_student DROP CONSTRAINT main_id_cons;

 

 

DELETE CASCADE 方式

-- 创建外键(使用 ON DELETE CASCADE 选项,删除主表的时候,同时删除子表)
ALTER TABLE test_sub_student ADD CONSTRAINT main_id_cons
FOREIGN KEY (main_id) REFERENCES test_main_class ON DELETE CASCADE;

 

测试删除(删除成功后select查看2表运行结果)

DELETE test_main_class WHERE ID = 1;

测试完毕后,删除 外键约束

ALTER TABLE test_sub_student DROP CONSTRAINT main_id_cons;

 

 

UPDATE CASCADE方式

--更新主表的主键时候,同时更新子表外键
ALTER TABLE test_sub_student
ADD CONSTRAINT main_id_cons
FOREIGN KEY (main_id) REFERENCES test_main_class ON UPDATE CASCADE;

SET NULL方式

-- 创建外键(使用 ON DELETE SET NULL 选项,删除主表的时候,同时将子表的 main_id 设置为 NULL)
ALTER TABLE test_sub_student
ADD CONSTRAINT main_id_cons
FOREIGN KEY (main_id) REFERENCES test_main_class ON DELETE SET NULL;

 SET DEFAULT 方式

--首先测试 ON DELETE SET DEFAULT
ALTER TABLE test_sub_student
ADD CONSTRAINT fk_main_class
FOREIGN KEY (main_id)  REFERENCES  test_main_class ON DELETE SET DEFAULT;
SELECT
test_main_class.value AS "班级",
test_sub_student.value AS "学生"
FROM
test_main_class
JOIN test_sub_student
ON(test_main_class.id = test_sub_student.main_id);

--班级                   学生
-------------------- ----------
--2015级123班              陌轩
--2015级124班              思梦

DELETE FROM test_main_class WHERE ID = 1;

SELECT
test_main_class.value AS "班级",
test_sub_student.value AS "学生"
FROM
test_main_class
JOIN test_sub_student
ON(test_main_class.id = test_sub_student.main_id);

--班级                   学生
-------------------- ----------
--暂无班级               陌轩
--2015级124班              思梦

ON DELETE SET DEFAULT
指定如果试图删除某一行,
而该行的键被其他表的现有行中的外键所引用,
则组成被引用行中的外键的所有值将被设置为它们的默认值。
为了执行此约束,目标表的所有外键列必须具有默认定义。
如果某个列可为空值,并且未设置显式的默认值,则将使用 NULL 作为该列的隐式默认值。
因 ON DELETE SET DEFAULT 而设置的任何非空值在主表中必须有对应的值,才能维护外键约束的有效性。

--然后测试 ON UPDATE SET DEFAULT
--删除前面的外键约束.
ALTER TABLE test_sub_student DROP CONSTRAINT fk_main_class; 
-- 创建外键约束.
ALTER TABLE test_sub_student
ADD CONSTRAINT fk_main_class
FOREIGN KEY (main_id)  REFERENCES  test_main_class ON UPDATE SET DEFAULT;

UPDATE test_main_class SET ID = 20 WHERE ID = 2;


SELECT
test_main_class.value AS "班级",
test_sub_student.value AS "学生"
FROM
test_main_class
JOIN test_sub_student
ON(test_main_class.id = test_sub_student.main_id);
--班级                     学生
-------------------- ----------
--暂无班级                 陌轩
--暂无班级                 思梦

ON UPDATE SET DEFAULT
指定如果试图更新某一行,
而该行的键被其他表的现有行中的外键所引用,
则组成被引用行中的外键的所有值将被设置为它们的默认值。
为了执行此约束,目标表的所有外键列必须具有默认定义。
如果某个列可为空值,并且未设置显式的默认值,则将使用 NULL 作为该列的隐式默认值。
因 ON UPDATE SET DEFAULT 而设置的任何非空值在主表中必须有对应的值,才能维护外键约束的有效性。

 

 

5.SQL CHECK 约束

5.1、规定 "Id_P" 列必须只包含大于 0 的整数

CREATE TABLE Persons
(
Id_P int NOT NULL CHECK (Id_P>0),
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)

 

5.2、需要命名 CHECK 约束,以及为多个列定义 CHECK 约束

CREATE TABLE Persons
(
Id_P int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CONSTRAINT CK_Person CHECK (Id_P>0 AND City='Sandnes')
)

 

5.3、在表已存在的情况下为 "Id_P" 列创建 CHECK 约束

ALTER TABLE Persons
ADD CHECK (Id_P>0)

 

5.4、需要命名 CHECK 约束,以及为多个列定义 CHECK 约束

ALTER TABLE Persons
ADD CONSTRAINT CK_Person CHECK (Id_P>0 AND City='Sandnes')

 

5.5、撤销 CHECK 约束

ALTER TABLE Persons
DROP CONSTRAINT CK_Person

 

 

【备注:CHECK示例】

1.检查只能是男或者女
add const ck_sex check(sex in('男,女')),
add const ck_sex check(sex ='男' or sex ='女')


2.在一个范围中间
constraint ch_age check(sage>0 and sage<120),
add const ck_age check(age between 12 and 30)


3.长度大于某个值
add const ck_lenght check(len(lenght)>6)


4.数大于某个值
add const ck_number ckeck(number>1)


5.只能是8位字符,前两位是 0 ,3~4位为数字,第 5 位为下划线,6~8位为字母
alter table 表名
add constraint chkk check((字段 like '00[0-9][0-9]/_[a-z,A-Z][a-z,A-Z][a-z,A-Z]%' escape '/')and(len(字段)=8) )
或者是
alter table 表名
add constraint chkk check((字段 like '00[0-9][0-9][_][a-z,A-Z][a-z,A-Z][a-z,A-Z]%')and(len(字段)=8) )


6.电子邮箱要含有@符号
check(字段like '%@%')


7.SQL中用check约束一列的首字母为's'
check(col1 like 's%')


8.检查约束前3位和后8位均为数字字符:
check(col2 like '[0-9][0-9][0-9]%[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]')


9.如何建立检查身份证的约束,身份证是18位,最后一位还有可能是X
select 身份证号 from 表名
where len(身份证号) = 18 and (right(身份证号,17) like '[0-9]'or right(身份证号,17) like 'x')


10.如何设置区号由0-9之间的数字组成
CONSTRAINT quhao CHECK (quhao LIKE '[0-9][0-9][0-9]'
or quhao LIKE '[0-9][0-9][0-9][0-9]'or quhao LIKE '[0-9][0-9][0-9][0-9][0-9]'));
解释: 其中quhao LIKE '[0-9]...[0-9]'的号码由表示n位从0到9中的数组成。
quhao LIKE '[0-9][0-9][0-9]' 表示3位的区号,如北京010;quhao LIKE '[0-9][0-9][0-9][0-9]'表示4位的区号,如三门峡0398; quhao LIKE
'[0-9][0-9][0-9][0-9][0-9]'表示5位的区号,如香港00852

 

11.最后回复时间 TLastClickT 发贴时间 TTime
最后回复时间 必须晚于 发贴时间 并且小于等于当前时间 使用GetDate()函数获取当前时间
设计表
在TLastClickT上右击
选择约束,新建,填入
([TLastClickT] > [TTime] and [TLastClickT] < GetDate())
或者
TiastReply(回帖时间)大于Ttime(发帖时间)在创表的同时
创建表的时候应该还没有回帖吧,为什么要用默认值?
可以添加一个约束 alter table topic alter column add check(TlastReply is null or TlastReply > Ttime)

 

12.定义前八位为数字或者 -
一共是15位,为CHAR型
alter table 表名
add constraint chk check(字段 like'[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%'),
constraint chklen check(len(字段)=15)

 

13.如何限制varchar字段不允许出现单引号的检查约束 !!!
设表为TALBENAME,不能有引号的字段为FIELDNAME 则:
ALTER TABLE tablename ADD CONSTRAINT CK_fieldname CHECK (not fieldname like '%''%')

 

14.在表中的某列中通过检查约束,让其有某些固定的值
check(sid like 'bd[0-9][0-9][0-9][0-9][0-9][0-9]')
add const ck_num check(num like '[1][2] [4][_] [0-9][0-9] [0-9][a-z]')

 

15.如何限制varchar字段不允许出现字符串的检查约束 !!!
设表名为TABLENAME,VARCHAR类型的字段为VAR_FIELD.则有:
ALTER TABLE [dbo].[TABLENAME] ADD CONSTRAINT [CK_TABLENAME] CHECK (isnumeric([VAR_FIELD]) = 1)
这样,在VAR_FIELD只要出现字段一旦出现非数字内容就会报告错误。

 

16.电话号码的格式必须为xxxx-xxxxxxxx或手机号11位
alter 表名 add constraint ck_字段名 check (字段 like '[0-9][0-9][0-9][0-9]_[0-9]......' or len(字段)=11)

 

17.身份证号是18位且唯一的
alter 表名 add
constraint ck_字段名 check (len(字段名)=18 ),
constraint uq_字段名 unique(字段名)

 

 

6.SQL DEFAULT 约束

6.1、在 "Persons" 表创建时为 "City" 列创建 DEFAULT 约束

CREATE TABLE Persons
(
Id_P int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255) DEFAULT 'Sandnes'
)

通过使用类似 GETDATE() 这样的函数,DEFAULT 约束也可以用于插入系统值

CREATE TABLE Orders
(
Id_O int NOT NULL,
OrderNo int NOT NULL,
Id_P int,
OrderDate date DEFAULT GETDATE()
)

 

6.2、在表已存在的情况下为 "City" 列创建 DEFAULT 约束

alter table Persons 
add constraint DF_Persons  default ('SANDNES') for City

 

6.3、撤销 DEFAULT 约束

ALTER TABLE Persons
DROP CONSTRAINT DF_Persons

 

 

作者:陌轩君 
出处:http://www.cnblogs.com/yuan-jun/p/6505562.html
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM