复杂的检查约束?
Posted
技术标签:
【中文标题】复杂的检查约束?【英文标题】:Complex Check Constraint? 【发布时间】:2014-02-24 21:45:58 【问题描述】:我有一个客户表,它通过中间的 CustomerAddress 表链接到地址表。这意味着一个客户可以有很多地址,一个地址可以有很多客户。 (这是必要的,因为我们将配偶和子女视为单独的客户,每个人都可以有送货、工作、账单和其他地址)。
我希望客户能够指定首选地址。
我的想法是在客户表中创建一个链接到 CustomerAddress 记录的新列。
我的问题是 - 如何确保所选的首选地址是客户地址之一?
我的想法是在 customers.preferredAddress 字段上设置一个检查约束,检查给定的 CustomerAddress 以查看该记录的客户 ID 是否与正在更新的客户匹配。
这可能吗?我只使用过检查约束来检查简单的东西,比如 (Value > 0) 等。
感谢您的帮助
【问题讨论】:
为什么在客户桌上?客户地址记录上的新列是“首选地址”和一个简单的 y/n(或位)来定义是或否(或 null 表示否)怎么样?如果它在 customeraddress 表中,则强制执行它是客户地址之一的关系。 但是我怎样才能阻止一位客户拥有多个首选地址? 【参考方案1】:编写一个用于验证地址所有权的 UDF,然后从检查约束中引用该 UDF。
CREATE FUNCTION dbo.fnIsAddressOwner (
@CustomerId int,
@AddressId int
)
RETURNS tinyint
AS
BEGIN
DECLARE @Result tinyint
IF EXISTS(SELECT * FROM CustomerAddresses WHERE CustomerId=@CustomerId and AddressId=@AddressId)
SET @Result= 1
ELSE
SET @Result= 0
RETURN @Result
END
CREATE TABLE Customers (
CustomerId int,
PreferredAddressId int,
CONSTRAINT ckPreferredAddressId CHECK (
dbo.fnIsAddressOwner(CustomerId, PreferredAddressId) = 1)
)
)
【讨论】:
如果检查约束对您不起作用,那么您也可以在触发器中执行检查。如果验证失败,则回滚事务。 当然,上面没有任何内容阻止UPDATE CustomerAddresses set CustomerId = <new value> where CustomerId = <old value>
,现在违反了“约束”。以上是关于复杂的检查约束?的主要内容,如果未能解决你的问题,请参考以下文章
如果我有 IBOutlet 进行约束,复杂 UIView 的布局会有所不同