1

如何在没有硬编码的情况下对列施加 CHECK 约束,使其可接受值的范围来自另一个表?

这是一个简化的示例:

OneManyTable
RoleID  TaskID
10      Val1
10      Val2
20      Val1
20      Val2


MetaDataTable
pkID    Class   Value
1       A       Val1
2       A       Val2
3       B       Val3
4       B       Val4

我想在 OneManyTable.TaskID 列上放置一个 CHECK 约束,以便可接受的值来自另一个表的列,即来自 MetadataTable.Value where MetadataTable.class='A'

我已经尝试创建格式的 CHECK 约束

TaskID in (Select Value FROM MetadataTable where class= 'A')

但这不受支持。

另一方面, ('Val1', 'Val2') 中的 TaskID 在 SQL2k8 中用作检查约束(不在 SQL2000 中!),但由于硬编码,它是不可接受的。

如何实现我想要的,无论是通过 CHECK 约束还是我不知道的其他一些花哨的机制?

PS。必须在数据库端,没有人向我建议的客户端检查。

4

2 回答 2

4

进入这可能不是一个好习惯,但您可以编写一个用户定义的函数,该函数接受您的 TaskID 作为参数,并根据 TaskID 是否在 MetaDataTable 中提供的范围内评估为真或假。

这将允许您获得您正在寻找的功能 - CHECK 约束实际上只是旨在限制列范围的简单函数,并且它们的行为是在设计时考虑到这一点的,所以这就是为什么你不能在 SQL Server 的检查约束中写入子查询。

但是,您可以在用户定义的函数中编写 SELECT 语句并从 CHECK 约束中调用它。

于 2010-07-08T05:13:48.323 回答
2

针对另一个表中的值的 CHECK 约束通常被设计为外键约束。这就是旨在链接值表的机制。

CHECK 约束实际上仅用于定义

  • 最小值或最大值
  • 范围
  • 给定一组值的枚举

所以我不认为你可以做你想做的事,因为这确实是你试图使用的错误功能。

于 2010-07-08T05:11:47.377 回答