微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

sql – 一组记录中的唯一约束,其中某些值相同

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)

对于fk1的每个唯一值,我想确保将isPrimary标志设置为1的唯一一条记录.

数据示例:
这应该是合法的:

pk1     name     fk1    isPrimary
----    -----    -----  ----------
1       Bill     111    1
2       Tom      111    0
3       Dick     222    1
4       Harry    222    0

但这不应该是(超过一个fk = 111):

pk1     name     fk1    isPrimary
----    -----    -----  ----------
1       Bill     111    1
2       Tom      111    1
3       Dick     222    1
4       Harry    222    0

这也不应该(没有fk = 222):

pk1     name     fk1    isPrimary
----    -----    -----  ----------
1       Bill     111    1
2       Tom      111    0
3       Dick     222    0
4       Harry    222    0

有没有办法用表约束来做到这一点?

UPDATE
我现在已经接受了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;

变化:

>使用@tempTable而不是

根据udf的要求,tempTable(在内存中,写入磁盘)
>传递@ fk1作为参数,这样我就可以在一个中选择唯一性
一组fk1值.
>棘手也必须通过isPrimary,即使它不是
必要的逻辑
功能,否则sql2005
优化器不会运行检查
isPrimary时的约束
更新.

解决方法

在检查约束中使用UDF可能会在 snapshot isolationmultirow updates下失败.

假设您的所有fk1和pk1值当前(并且将始终为)为正,您可以使用以下定义创建计算列

CASE WHEN isPrimary = 1 THEN fk1 ELSE -pk1 END

然后添加一个唯一的约束.或者,如果不能做出那个假设那么可能

CASE WHEN isPrimary = 0 THEN 1.0/pk1 ELSE fk1 END

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐