2011-09-27 62 views
5

外键约束是否在没有使用约束更新列的SQL更新语句上检查? (在MS SQL Server)外键约束是否在没有用约束更新列的SQL更新语句上检查?

说我有一个以下列的情侣对表:

OrderItems 

    - OrderItemID 
    - OrderItemTypeID (FK to a OrderItemTypeID column on another table called OrderItemTypes) 
    - ItemName 

如果我只是更新

update [dbo].[OrderItems] 
set [ItemName] = 'Product 3' 
where [OrderItemID] = 2508 

请问FK约束做它的查找/与检查上面的更新声明? (甚至认为更新不会更改该列的值?)

+0

虽然这是一个有效的问题,但我想知道这可能是多么相关 –

+0

如果未检查FK,那么在更新语句中不包括FK列会有性能优势。 –

回答

8

不,不检查外键。通过检查两个不同更新的执行计划,这很容易看出。

create table a (
    id int primary key 
) 

create table b (
    id int, 
    fkid int 
) 

alter table b add foreign key (fkid) references a(id) 

insert into a values (1) 
insert into a values (2) 

insert into b values (5,1) -- Seek on table a's PK 

enter image description here

update b set id = 6 where id = 5 -- No seek on table a's PK 

enter image description here

update b set fkid = 2 where id = 6 -- Seek on table a's PK 

enter image description here

drop table b 
drop table a 
+1

+1个很好的例子。 – 2011-09-28 00:40:45

3

否。由于SQL更新未更新包含约束的列,因此SQL Server在此情况下检查的是什么?这类似于问,“如果我只做更新,插入触发器会被触发吗?”答案是否定的。

+0

你确定知道吗?还是仅仅是直觉?如果它执行更新检查 – JNK

+0

@JNK,它不会让我感到惊讶 - 它会检查什么?该列未被更新,并且没有值检查。那么会得到什么检查? –

+0

+1一个简单的测试显示你是正确的。可以通过检查更新FK列的执行计划进行检查,也可以通过执行计划进行检查。 –

1

有当FK不存在会阻止更新到其他列的情况下,即使FK没有更改,也就是FK创建时使用NOCHECK,因此在创建时不检查。每联机丛书:

如果你不想验证新的CHECK或外键约束 对现有的数据,使用WITH NOCHECK。我们不建议这样做,除非在极少数情况下。新约束将在 以后的所有数据更新中进行评估。当添加约束时,通过WITH NOCHECK抑制 的任何约束违规可能会导致未来更新 在更新行时使用不符合 约束的数据。