【问题标题】:Check Constraint Referencing Unique Column on another Table检查约束引用另一个表上的唯一列
【发布时间】: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


【解决方案1】:

首先,像 GordonLinoff cmets 一样,更好的方法是将 TitleID 包含在 Customer 表中。如果您无法更改 Customer 表的布局,下面是一个选项。 foreign key 绝对比使用动态 T-SQL 使 check 约束保持最新更好。

我无法使用外键引用 title.label 列,因为它是 不是主键。

外键可以引用任何候选键。它不必引用主键。

要告诉数据库有关候选键的信息,您可以创建唯一索引:

create table title (
    id int primary key, 
    label varchar(50));
create table customer (
    id int primary key, 
    title varchar(50));
create unique index ux_title_label on title(label);
alter table customer add constraint fk_customer_title 
    foreign key (title) references title(label);

告诉数据库有关候选键的另一种方法是唯一约束:

alter table title add constraint uc_title_label unique (label);

【讨论】:

  • 每天都有新的东西。谢谢,听起来很完美;我试试看。
  • 只是好奇,与标题(标签)的唯一约束而不是唯一索引有什么区别吗? (可能是 NULL?)
  • @jarlh see msdn,除 FILLFACTOR 之外可用于唯一索引的索引创建选项不适用于唯一约束
猜你喜欢
  • 1970-01-01
  • 2021-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-10
  • 2020-12-03
相关资源
最近更新 更多