问题描述
我正在使用SQL Server2012。已在表上定义了外键约束。外键引用复合主键。当一列为 00000而另一列为空时,fk约束不起作用。父表不包含 00000。两个fk列均具有 varchar
数据类型。
I am using SQL Server 2012. I have defined a foreign key constraint on a table. The foreign key references composite primary key. The fk constraint does not work when one column has '00000' and other column is null. The parent table does not contain '00000'. Both of the fk columns have varchar
data type.
下面是示例:
INSERT INTO XYZ
([BUSINESS_PARTNER_ID]
,[INDUSTRY_TYPE_CDE]
,[INDUSTRY_SUBTYPE_CDE])
VALUES
(1,
Null
'00000')
GO
行业类型和行业子类型列是从另一个表中引用的。
以下是脚本:
The industry type and industry sub type column is referenced from another table.Below is the script:
ALTER TABLE [nfs].[xyz] WITH NOCHECK
ADD CONSTRAINT [FK_BPMAIN__ITCDE_ISTCDE]
FOREIGN KEY([INDUSTRY_TYPE_CDE], [INDUSTRY_SUBTYPE_CDE])
REFERENCES [nfs].[abc] ([INDUSTRY_TYPE_CDE], [INDUSTRY_SUBTYPE_CDE])
GO
ALTER TABLE [nfs].[xyz]
CHECK CONSTRAINT [FK_BPMAIN__ITCDE_ISTCDE]
GO
SQL Server插入时未给出任何错误。它将值插入子表中。根据我的理解,fk列可以为null或应包含父表中存在的值。
SQL Server does not give any error on insertion. It inserts the value in the child table. According to my understanding, the fk columns can be null or should contain values that exist in the parent table.
推荐答案
首先,我们有实用原因。使用索引维护和检查外键。为了使索引可用,我们需要知道索引内所有列的(要求)值。如果我们在(a,b)
上有一个索引/ pk,而我们的外键值是(NULL,1)
,我们无法在索引中进行 seek 以确定是否存在任何 b
值为1的行。
First, we have the practical reasons. Foreign keys are maintained and checked using indexes. In order for an index to be usable, we need to know the (sought for) values of all columns within the index. If we have an index/pk on (a,b)
and we have a foreign key value of (NULL,1)
, we cannot seek within the index in order to determine whether there is any row with a b
value of 1. This would make the foreign key "expensive" to maintain.
但是第二,我们需要考虑一致性。对于单列的情况,这是相当没有争议的-如果FK列中有一个值,则在引用的列中需要有一个匹配的值。否则,如果FK列为 NULL
,则不检查约束。
But secondly, we need to consider consistency. For the single column case, its fairly uncontroversial - if you have a value in the FK column, then there needs to be a matching value in the referenced column. Otherwise, if the FK column is NULL
then the constraint isn't checked.
但是,我们如何扩展这个到多列?上面的规则是什么 ?没有明显的解释,而是多个解释。上面的规则是如果 all 列均为非NULL,则检查约束还是如果 any 列非NULL,则检查约束?当仅考虑单个列时,这些规则是相同的。
But, how do we extend this to multiple columns? What is the rule above? There's not a single obvious interpretation, but instead multiple ones. Is the above rule "if all columns are non-NULL, then the constraint is checked" or "if any columns are non-NULL, then the constraint is checked"? These rules are identical when only a single column is under consideration.
您期望该规则是第二个规则,而实际上是第一条。明确:
You expected the rule to be the second one, when it is in fact the first. This is explicitly documented:
这篇关于子表中的外键约束允许插入父表中不存在的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!