是否在不使用约束更新列的SQL更新语句上检查外键约束?

时间:2011-09-27 18:26:48

标签: sql-server performance foreign-keys

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

假设我有几个包含以下列的表:

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约束是否会使用上面的update语句进行查找/检查? (甚至认为更新不会改变该列的值?)

3 个答案:

答案 0 :(得分: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 :(得分:3)

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

答案 2 :(得分:1)

有一种情况是FK不存在会阻止对其他列的更新,即使FK没有更改,也就是当FK创建WITH NOCHECK并因此在创建时没有检查。每本在线书籍:

  

如果您不想验证新的CHECK或FOREIGN KEY约束   针对现有数据,使用WITH NOCHECK。我们不建议这样做   这是罕见的情况。新约束将在中进行评估   所有以后的数据更新。任何被抑制的约束违规   通过WITH NOCHECK添加约束可能会导致将来更新   如果他们用不符合的数据更新行,则会失败   约束