如何在SQL Server中对计算字段设置外键约束?

10

表A有一个名为Computed1的计算字段。它是持久化的且不能为空。此外,它总是计算为char(50)表达式。它也是唯一的,并且在其上有唯一键约束。

表B有一个字段RefersToComputed1,应该引用有效的Computed1值。

试图在B的RefersToComputed1上创建一个外键约束,引用A的Computed1会导致以下错误:

Error SQL01268: .Net SqlClient Data Provider: Msg 1753, Level 16, State 0, Line 1 Column
'B.RefersToComputed1' is not the same length or scale as referencing column 'A.Computed1' in
foreign key 'FK_B_A'. Columns participating in a foreign key relationship must be defined with
the same length and scale.

问:为什么会出现这个错误?对于计算列的外键,是否需要特殊措施,如果需要,是什么措施?


摘要:

  • 具体问题来源于计算、基于字符的字段是varchar。因此,Computed1是varchar(50),而不是char(50)。
  • 最好在计算字段的表达式周围放置一个转换函数,以将其强制转换为特定类型。这个技巧来自Cade Roux。
3个回答

10

计算字段由char(M), char(N)等组成,这些加起来等于M+N+..=50,但计算字段本身是varchar(50)。将RefersToComputed1从char(50)更改为varchar(50)即可解决问题。

计算字段的外键不需要特殊处理(尽管可能需要在计算列上进行持久化)。


好的发现 - CHAR(50)将用空格填充到50个字符长度,而VARCHAR则不会 - 对于这些事情使用VARCHAR比CHAR更好! - marc_s
3
需要对其进行索引以创建外键,因此需要将其持久化。 - gbn
您还可以在计算列表达式中进行转换,以确保持久化的列是您认为的类型。这在字符串操作中是一个大问题。 - Cade Roux
@Cade:那是一个好建议。我已经在我的计算字段中添加了一个强制转换。 - Asaf R

1

RefersToComputed1 是类型为 char(50) 的主键吗?


@Lucero:这不是主键。关系是多对一的,因此在表B中可能会有几个相同值的RefersToComputed1。 - Asaf R
那么你到底想做什么?外键约束用于确保列只包含来自引用主键的条目,但在你的情况下没有主键。请解释一下。 - Lucero
2
你可以使用外键引用唯一索引,不一定非得是主键。 - marc_s
@marc_s,感谢提示。实际上我从未将它们用于除主键以外的任何事情,而且当您搜索外键时弹出的文档也没有什么帮助:http://msdn.microsoft.com/en-us/library/ms175464.aspx - Lucero

1

RefersToComputed1 的数据类型、长度和排序规则与 Computed1 完全相同吗?

再仔细检查一下...例如,您是否需要对 Computed1 进行最终的 CAST 或 COLLATE,以确保它符合您的预期?我这么说是因为错误提示表明这两个列是不同的。

编辑:char 和 varchar 不是相同的数据类型,因此您需要进行 CAST 转换。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接