检查约束 - 如果另一列为真,则仅允许一列为真
Posted
技术标签:
【中文标题】检查约束 - 如果另一列为真,则仅允许一列为真【英文标题】:Check Constraint – only allow one column to be true if another column is true 【发布时间】:2013-03-10 23:40:29 【问题描述】:以如下表为例:
CREATE TABLE [dbo].[tbl_Example](
[PageID] [int] IDENTITY(1,1) NOT NULL,
[RequireLogin] [bit] NOT NULL,
[RequireAdmin] [bit] NOT NULL,
[HideIfLoggedIn] [bit] NOT NULL
)
如何重写上述内容以包含如下检查约束:
如果[RequireLogin]
为False,则强制[RequireAdmin]
为False(即仅当@987654325 时[RequireAdmin]
为True @ 是 True,同时允许 [RequireLogin]
是 True 和 [RequireAdmin]
是 False
如果[RequireLogin]
为False,则仅允许[HideIfLoggedIn]
为True
【问题讨论】:
(1) [RequireAdmin] 【参考方案1】:您通常会在检查中执行嵌套的 case 语句,以使该类型的逻辑正常工作。请记住,支票中的案例必须仍然是评估,因此它会采用以下形式
CHECK (case when <exp> then 1 end = 1).
查看您的确切要求,但这似乎也可以工作并且可能更容易阅读:
CREATE TABLE [dbo].[tbl_Example]
(
[PageID] [int] IDENTITY(1,1) NOT NULL,
[RequireLogin] [bit] NOT NULL,
[RequireAdmin] [bit] NOT NULL,
[HideIfLoggedIn] [bit] NOT NULL
)
ALTER TABLE [dbo].[tbl_Example] ADD CONSTRAINT
[RequireAdmin] CHECK
((RequireAdmin = RequireLogin) OR
(RequireLogin=1));
ALTER TABLE [dbo].[tbl_Example] ADD CONSTRAINT
[HideIfLoggedIn] CHECK
((RequireLogin=1 AND HideIfLoggedIn=0) OR
(RequireLogin=0 AND HideIfLoggedIn=1) OR
(RequireLogin=0 AND HideIfLoggedIn=0))
【讨论】:
不得不将最后一个更改为((RequireLogin=1 AND HideIfLoggedIn=0) OR (RequireLogin=0 AND HideIfLoggedIn=1) OR (RequireLogin=0 AND HideIfLoggedIn=0))
- 但是,效果很好 - 干杯
很好,组合的布尔逻辑总是很容易倒退。【参考方案2】:
如果我的代数正确:
alter table dbo.Example
add constraint RequireAdmin_RequireLogin_ck
check ( not ( RequireAdmin = 'true' and RequireLogin = 'false' ) ) ;
alter table dbo.Example
add constraint HideIfLoggedIn_RequireLogin_ck
check ( not ( HideIfLoggedIn = 'true' and RequireLogin = 'true' ) ) ;
请注意,这些检查约束是在表级别而不是列级别定义的,因为它们引用了多个列,所以必须这样做。由于这个原因,RThomas 的回答不是有效的 Transact-SQL!
【讨论】:
我推荐两件事:(1) 尽量不要使用NOT
来强制执行约束 - 它只是颠倒了你必须在精神上处理事情的方式 (2) 使用 0 和 1 而不是布尔样式的字符串用于 BIT 比较的文字。
我不同意你的观点,亚伦。首先,组织政策通常表示为否定的(例如,“不允许员工在工作时间浏览 ebay”),因此使用相同的措辞创建约束可以提供更好的阅读理解。其次,这些是布尔值——它们只是一个位字段,因为 MSSQL 没有布尔数据类型。使用“true”更适合阅读理解,因为它明确地向读者传达了“true”。相比之下,0 和 1 要求读者记住 0 在这种特定语言中是代表真还是假。
好吧,做你想做的,当然。我可以从 16 年的 SQL Server 经验告诉你,我提到的两件事将让大多数用户感到困惑,无论他们对你有多大意义。
很好地将约束添加为更改表 - 我最初没有想到这一点。谢谢。以上是关于检查约束 - 如果另一列为真,则仅允许一列为真的主要内容,如果未能解决你的问题,请参考以下文章