【发布时间】:2015-02-20 11:38:58
【问题描述】:
我想限制一个列中可以输入的可用值,但我想使用的值在另一个表中,该表不是该表的主键;该表的主键未包含在我的表中。
例如,假设我创建了一个客户报告表(列:Id、Name、Title),它引用了现有的客户标题表(列:Id、Label)两个表的主键都是 Id。我希望客户表以文字形式显示客户的标题,而不是与客户关联的 title.Id。我知道客户标题列应该只包含标题表中的值。我无法更改titles 表的结构。
以下是我考虑过但我不太喜欢的三个选项:
1.我不能用外键引用title.label列,因为它不是主键。
2.在使用标题标签更新客户表之前,我可以创建一个检查约束并制作一个动态脚本以使用标题表中的值对其进行更新,但这感觉非常手摇。
DECLARE @TableName VARCHAR(50) = 'Customers'
DECLARE @FieldName VARCHAR(50) = 'Title'
DECLARE @SQL VARCHAR(MAX) = ''
SELECT @SQL = @SQL + '
OR ' + @FieldName + ' = ''' + Label + ''''
FROM dbo.Titles
ORDER BY Label
SELECT @SQL = 'ALTER TABLE dbo.' + @TableName + ' DROP CONSTRAINT chk_Customer' + @FieldName + '
ALTER TABLE dbo.' + @TableName + ' ADD CONSTRAINT chk_Customer_' + @FieldName + ' CHECK
(' + SUBSTRING(@SQL,6,LEN(@SQL)) + ')'
PRINT @SQL
3. 我完全可以不考虑约束列,但我宁愿在可能的情况下添加约束,以尽可能降低所有内容并提高查询性能。
所以,问题是这样的:是否有一种内置方法可以通过引用另一表来引用一列(以限制或枚举值),而不必以某种方式编写值;某些东西一旦创建就会始终保持最新,就像外键关系一样,但无需引用主键。
【问题讨论】:
-
将
TitleId放入Customers表中,并在需要时使用join获取字符串值。不要开始使用对非主键的外键引用,除非你有很好的理由——在这种情况下尝试保存连接并不是“很好的理由”。 -
我宁愿也这样做并保持所有关系,但该表被如此多的报告使用,因为改变事情将是一场噩梦(而且我不是唯一一个谁写报告)。我已经与报告作者交谈过,他们更愿意将所需的所有信息放在一个非常索引的表中,至少对于他们认为像这样微不足道的信息。
标签: sql sql-server-2008 foreign-keys constraints check-constraints