Ada*_*son 8 sql database sql-server sql-server-2005 constraints
DBMS: MS Sql Server 2005,标准版
我想创建一个表约束,使得只有一个记录在表的子集中具有特定值(其中行在特定列中共享一个值).这可能吗?
示例: 我在myTable中有一个非唯一外键(fk1)的记录,以及一个名为isPrimary的位列,用于标记我们的应用程序应该使用这个特殊逻辑.
在摘要中,它看起来像这样:
myTable
-------------
pk1 (int, not null)
name (varchar(50), null)
fk1 (int, not null)
isPrimary (bit, not null)
Run Code Online (Sandbox Code Playgroud)
对于fk1的每个唯一值,我想确保将isPrimary标志设置为1的唯一一条记录.
数据示例:这应该是合法的:
pk1 name fk1 isPrimary
---- ----- ----- ----------
1 Bill 111 1
2 Tom 111 0
3 Dick 222 1
4 Harry 222 0
Run Code Online (Sandbox Code Playgroud)
但这不应该是(超过一个fk = 111):
pk1 name fk1 isPrimary
---- ----- ----- ----------
1 Bill 111 1
2 Tom 111 1
3 Dick 222 1
4 Harry 222 0
Run Code Online (Sandbox Code Playgroud)
这也不应该(没有fk = 222):
pk1 name fk1 isPrimary
---- ----- ----- ----------
1 Bill 111 1
2 Tom 111 0
3 Dick 222 0
4 Harry 222 0
Run Code Online (Sandbox Code Playgroud)
有没有办法用表约束来做到这一点?
更新 我现在已经接受了Martin Smith的回答,尽管我将在即将发布的版本中推动JohnFx的重构,因为它是最好的长期解决方案.但是我想根据Raze2dust的答案发布我更新的UDF,以防未来读者认为更适合他们的需求.
CREATE FUNCTION [dbo].[OneIsPrimaryPerFK1](@fk1 INT, @dummyIsPrimary BIT)
RETURNS INT
AS
BEGIN
DECLARE @retval INT;
DECLARE @primarySum INT;
SET @retval = 0;
DECLARE @TempTable TABLE (
fk1 INT,
PrimarySum INT)
INSERT INTO @TempTable
SELECT fk1, SUM(CAST(isPrimary AS INT)) AS PrimarySum
FROM FacAdmin
WHERE fk1 = @fk1
GROUP BY fk1;
SELECT @primarySum = PrimarySum FROM @TempTable;
IF(@primarySum=1)
BEGIN
SET @retval = 1
END
RETURN @retval
END;
Run Code Online (Sandbox Code Playgroud)
变化:
自从我严重破坏第一个问题以来,开始了一个新的答案.
听起来你可以通过重新思考一下你的表设计来解决这个问题,以避免让你暴力成为实施业务规则的约束.
如何从MyTable中删除IsPrimary列并将PrimaryPersonID列添加到引用主要人员的另一个表中?
这样,结构本身就会强制执行1,并且FK表中只有1个条目是每个人的主要条目.
SQL 2005不提供将Where子句应用于SQL 2008等唯一索引的功能.但是,有几种方法可以解决SQL 2005中的问题:
在快照隔离或多行更新下,在检查约束中使用 UDF 可能会失败。
假设所有 fk1 和 pk1 值当前(并将始终)为正值,您可以使用以下定义创建一个计算列
CASE WHEN isPrimary = 1 THEN fk1 ELSE -pk1 END
Run Code Online (Sandbox Code Playgroud)
然后为其添加唯一约束。或者如果这个假设不能成立那么也许
CASE WHEN isPrimary = 0 THEN 1.0/pk1 ELSE fk1 END
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3924 次 |
| 最近记录: |