/*--------------------------------------------------------------------------------------
t-mac 编写整理
---学习总结使用
--MSDN笔记
----------------------------------------------------------------------------------------*/
约束分2种:一种是行级约束,只对一行定义约束;
还有一种是表级约束,可以对多列定义同一个约束.如:对组合列定义主键
-----------------------------check约束--------------------------
--1.可将多个check约束用于单个列,也可以使用表级约束一个check约束用于多列.
--2.check约束不接受结算结果为FALSE的值,这样三值逻辑中的unknown就是可以接受的.
列子:假设对 int 列 MyColumn 应用一个约束,指定 MyColumn 只能包含值 10(即 MyColumn = 10)。
如果将值 NULL 插入到 MyColumn,数据库引擎将插入 NULL 且不返回错误。
--3.check约束特殊性
a.如果刚创建的表没有任何行,则此表的任何 CHECK 约束都视为有效.
<textarea cols="67" rows="15" name="code" class="c-sharp"> CREATE TABLE CheckTbl (col1 int, col2 int); GO CREATE FUNCTION CheckFnctn() RETURNS int AS BEGIN DECLARE @retval int SELECT @retval = COUNT(*) FROM CheckTbl RETURN @retval END; GO ALTER TABLE CheckTbl ADD CONSTRAINT chkRowCount CHECK (dbo.CheckFnctn() >= 1 ); GO </textarea>
--这里的表级约束使用函数CheckFnctn() 规定表必须至少含有一行,但是表中无任何行,所以此约束不成立这个时候.
b.执行 DELETE 语句时不验证 CHECK 约束
<textarea cols="57" rows="5" name="code" class="c-sharp"> INSERT INTO CheckTbl VALUES (10, 10) GO DELETE CheckTbl WHERE col1 = 10;</textarea>
--这里插入一行记录 然后删除 本来删除表没有记录 但是DELETE 语句也会成功。
----------------------Primary Key约束和Unique约束-------------------------------------
--共同点:1.可保证数据的唯一性
2.都可以被外表的Foreign Key引用
--不同点:1.一个表只能有一个 PRIMARY KEY 约束,但是可以有多个unique约束
2.PRIMARY KEY 约束中的列不能接受空值,Unique约束可以接受NULL值
--关于Unique约束可以被外表引用为外键
----sc表中的ID引用了s表的id列
create table s(id int unique,b int)
create table sc (c int primary key,id int references s(id),d int)
----------------------Foreign Key约束----------------------------------------------
--外键 (FK) 是用于建立和加强两个表数据之间的链接的一列或多列
--可以通过主键控制另外一个表的外键 ,也可以用另外一个表的外键控制主表的主键
<textarea cols="74" rows="15" name="code" class="c-sharp"> --建立有外键关系的2个表 create table tb1(a int primary key,b int) create table tb2(c int primary key,a int references tb1(a),d int) insert tb1 select 1,2 union select 2,3 insert tb2 select 1,1,3 union select 2,1,4 union select 3,2,4 --试图删除,更新主表Tb1中的记录,结果被外表限制住了 delete tb1 where a=1 --false update tb1 set a=4 where a=1 --false --这个时候给tb2表的a列加上级联更新和删除 alter table tb2 add foreign key(a) references tb1(a) on delete cascade alter table tb2 add foreign key(a) references tb1(a) on update cascade delete tb1 where a=1 --success update tb1 set a=3 where a=2 --success </textarea>
PS:不能为具有 INSTEAD OF触发器的表指定级联操作。为表定义级联操作后,就不能向该表添加 INSTEAD OF触发器
这里顺便替下级联操作和触发器的触发顺序
1.首先执行由原始DELETE或 UPDATE直接导致的所有级联引用操作。
2.当完成原始级联引用操作后,无论是否更新了任何行,都将激发原始表上的 AFTER触发器。
3.然后激发级联引用操作链中表上的AFTER触发器,但只有已更新或删除了表中的一行或多行时才激发。
4.如果任何原始级联引用操作集生成任何错误,则产生错误,不激发AFTER触发器,并且回滚DELETE或UPDATE。
5.AFTER触发器可执行DELETE UPDATE语句以启动其它级联引用操作链。