Sql server SQL Server-检查值来自另一个表的列上的约束
如何在列上设置检查约束,使其可接受值的范围来自另一个表,而无需硬编码 下面是一个简化的示例:Sql server SQL Server-检查值来自另一个表的列上的约束,sql-server,restrict,check-constraints,Sql Server,Restrict,Check Constraints,如何在列上设置检查约束,使其可接受值的范围来自另一个表,而无需硬编码 下面是一个简化的示例: 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
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列设置一个检查约束,以便可接受的值来自另一个表的列,即MetadataTable.Value,其中MetadataTable.class='a'
我已经尝试创建格式的检查约束
TaskID in (Select Value FROM MetadataTable where class= 'A')
但这是不受支持的
另一方面,'Val1','Val2')中的TaskID在SQL2k8中用作检查约束(不在SQL2000中!),但由于硬编码,它是不可接受的
如何实现我想要的,无论是通过检查约束还是其他我不知道的奇特机制
PS.必须位于数据库端,没有任何人向我建议的客户端检查。针对另一个表中的值的检查约束通常设计为外键约束。这是一种机制,设计用于链接表上的值 检查约束实际上只是为了定义
- 最小值或最大值
- 范围
- 给定值集的枚举
因此,我认为您无法执行您试图执行的操作,因为这确实是您尝试使用的错误功能。针对另一个表中的值的检查约束通常被设计为外键约束。这是一种机制,设计用于链接表上的值 检查约束实际上只是为了定义
- 最小值或最大值
- 范围
- 给定值集的枚举
所以我不认为你能做你想做的事情,因为这确实是你试图使用的错误功能。这可能不是一个好的实践,但您可以编写一个用户定义的函数,该函数接受您的TaskID作为参数,并根据TaskID是否在MetaDataTable中提供的范围内对其求值为true或false 这将允许您获得所需的功能—检查约束实际上只是用于限制列范围的简单函数,它们的行为就是基于此而设计的,因此,在SQL server中不能在检查约束内编写子查询
但是,您可以在用户定义的函数中编写SELECT语句,并从CHECK约束调用它。这可能不是一个好的实践,但您可以编写一个用户定义的函数,该函数接受您的TaskID作为参数,并根据TaskID是否在MetaDataTable中提供的范围内对其求值为true或false 这将允许您获得所需的功能—检查约束实际上只是用于限制列范围的简单函数,它们的行为就是基于此而设计的,因此,在SQL server中不能在检查约束内编写子查询
但是,您可以在用户定义的函数中编写SELECT语句,并从CHECK约束调用它。因此,我编写了我的udf,并创建了dbo.udfValidateTaskIDRange(TaskID)=1形式的约束。谢谢你让我走上正轨,满分。但不确定你的“不是一个好的实践评论”;如果所有的参考数据都在一个表中,这是一个很好的实践:-)总比什么都不使用并让错误潜入你的表要好。我们很少使用这种结构,它对我们很有效。@Joedotnot是的,如果使用得当,这种技术真的很有用-只是它也很容易被滥用/误用,这就是为什么我写道,这可能不是一个好习惯。只要你仔细考虑如何设计你的udf,那么你的状态就会很好。所以我写了我的udf,并创建了dbo.udfValidateTaskIDRange(TaskID)=1形式的约束。谢谢你让我走上正轨,满分。但不确定你的“不是一个好的实践评论”;如果所有的参考数据都在一个表中,这是一个很好的实践:-)总比什么都不使用并让错误潜入你的表要好。我们很少使用这种结构,它对我们很有效。@Joedotnot是的,如果使用得当,这种技术真的很有用-只是它也很容易被滥用/误用,这就是为什么我写道,这可能不是一个好习惯。只要你仔细考虑如何设计你的自定义项,那么你的状态就会很好。