使用约束检查 sql 唯一值
我遇到的情况是,一个表具有三列 ID、值和状态。对于一个不同的 ID,应该只有一种值为 1 的状态,并且应该允许 ID 具有多于一种值为 0 的状态。唯一键将防止 ID 具有多于一种状态(0 或 1)。
有没有办法解决这个问题,也许使用约束?
谢谢
I have a situation where a table has three columns ID, Value and status. For a distinct ID there should be only one status with value 1 and it should be allowed for ID to have more then one status with value 0. Unique key would prevent ID of having more then one status (0 or 1).
Is there a way to solve this, maybe using constraints?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您可以创建一个索引视图,以保持
ID
对于[Status] = 1
保持唯一的约束。在 SQL Server 2008 中,您可以使用唯一的筛选索引。
You can create an indexed view that will uphold your constraint of keeping
ID
unique for[Status] = 1
.In SQL Server 2008 you could use a unique filtered index instead.
如果表可能有重复的
ID
值,则检查约束不适用于您的情况。我认为唯一的方法是使用触发器。如果您正在寻找示例,那么我可以发布一个。但总而言之,使用触发器来测试插入/更新的 ID 的状态是否为 1,并且在同一 ID 中重复。编辑:您始终可以对
ID
和Value
使用唯一约束。我想这会给你你正在寻找的东西。If the table can have duplicate
ID
values, then a check constraint wouldn't work for your situation. I think the only way would be to use a trigger. If you are looking for an example then I can post one. But in summary, use a trigger to test if the inserted/updated ID has a status of 1 that is duplicated across the same ID.EDIT: You could always use a unique constraint on
ID
andValue
. I'm thinking that will give you what you are looking for.您可以将其放入插入/更新触发器中进行检查以确保仅存在一个值为 1 的组合;如果不满足您的条件,您可以抛出一个可捕获的错误并强制操作回滚。
You could put this into an insert/ update trigger to check to make sure only one combination exists with the 1 value; if your condition is not met, you could throw a trappable error and force the operation to roll back.
如果您可以使用 NULL 而不是 0 来表示零状态,那么您可以在该对上使用 UNIQUE 约束,并且它应该可以工作。由于 NULL 不是实际值 (NULL != NULL),因此具有多个 null 的行不应发生冲突。
If you can use NULL instead of 0 for a zero-status, then you can use a UNIQUE constraint on the pair and it should work. Since NULL is not an actual value (NULL != NULL), then rows with multiple nulls should not conflict.
恕我直言,这基本上是一个标准化问题。名为“id”的列并不唯一地寻址一行,因此它永远不可能是 PK。至少需要一个新的(代理)键(元素)。约束本身不能表示为“行内”的表达式,因此必须用 FK 来表示。
所以它分为两个表:
一个 PK=id,FK REFERENCING Two.sid
两个 PK= 代理键,FK id REFERENCING one.id
原始有效负载“值”也存在于此。
“一位变量”消失了,因为它可以用 EXISTS 来表示。 (表一有效地指向保存令牌的行)
[我希望 Postgres 规则系统可用于使用上述两表模型来模拟 OP 的预期行为。但这将是一个丑陋的黑客......]
编辑/更新:
Postgres 支持部分/条件索引。 (不知道ms-sql)
IMHO, this basically is a normalisation problem. The column named "id" does not uniquely address a row, so it can never be a PK. At least a new (surrogate) key(element) is needed. The constraint itself cannot be expressed as an expression "within the row", so it has to be expressed in terms of a FK.
So it breaks down into two tables:
One with PK=id, and a FK REFERENCING two.sid
Two with PK= surrogate key, and FK id REFERENCING one.id
The original payload "value" also lives here.
The "one bit variable" disappears, because it can be expressed in terms of EXISTS. (effectively table one points to the row that holds the token)
[I expect the Postgres rule system could be used to use the above two-tables-model to emulate the intended behaviour of the OP. But that would be an ugly hack...]
EDIT/UPDATE:
Postgres supports partial/conditional indices. (don't know about ms-sql)
我想出了一个解决方案
首先创建一个函数
其次在表中创建一个约束
这样一个ID可以具有单一状态(1)和尽可能多的状态(0)。
I came up with a solution
First create a function
Second create a constraint in table
In this way one ID could have single status (1) and as many as possible status (0).