Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server SQL Server中基于祖父母的唯一约束_Sql Server - Fatal编程技术网

Sql server SQL Server中基于祖父母的唯一约束

Sql server SQL Server中基于祖父母的唯一约束,sql-server,Sql Server,我有以下表格结构: Grandparent - GrandParentId (PK) Parent - ParentId (PK), GrandParentId (FK) Child - ChildId (PK), ChildTypeId (FK), ParentId (FK) 我想要一个唯一的约束,即如果两个孩子有一个公共的祖父母ID,那么他们不能有相同的ChildTypeId。SQL Server是否可以这样做?您不能使用唯一约束,但可以使用调用UDF的检查约束 编写一个UDF,它接受一个

我有以下表格结构:

Grandparent - GrandParentId (PK)
Parent - ParentId (PK), GrandParentId (FK)
Child - ChildId (PK), ChildTypeId (FK), ParentId (FK)

我想要一个唯一的约束,即如果两个孩子有一个公共的
祖父母ID
,那么他们不能有相同的
ChildTypeId
。SQL Server是否可以这样做?

您不能使用唯一约束,但可以使用调用UDF的检查约束

编写一个UDF,它接受一个ChildId并查询Child和Parent的联接,以查看是否有另一个孩子具有相同的祖父母ID和ChildTypeId。如果存在,则返回true/false

然后在CHECK约束中,调用该函数,传递ChildId,并检查函数的结果是否为true/false


你也可以用触发器来完成,但我更喜欢约束。

为了加速其他人在这篇文章中的跌跌撞撞,下面是Tab Alleman建议的SQL示例:

CREATE FUNCTION Func_CousinsWithSameChildTypeId
(
    @childId uniqueidentifier,
    @parentId uniqueidentifier,
    @childTypeId uniqueidentifier
)
RETURNS bit
AS
BEGIN
    -- Declare the return variable here
    DECLARE @ResultVar bit

    SET @ResultVar = CASE 
        --assuming nullable - remove as necessary
        WHEN @parentId IS NOT NULL AND @childTypeId IS NOT NULL AND EXISTS(
            SELECT 1
            FROM dbo.Parents AS pAll
                INNER JOIN dbo.Children AS c ON c.ParentId = pAll.Id
            WHERE pAll.GrandParentId IN 
                (SELECT p1.GrandparentId
                 FROM dbo.Parents AS p1
                 WHERE p1.Id = @ParentId)
            AND c.Id <> @childId AND c.childTypeId = @childTypeId
        )
        THEN 1
        ELSE 0
    END

    -- Return the result of the function
    RETURN @ResultVar

END
GO
ALTER TABLE [dbo].[Children] WITH CHECK ADD CONSTRAINT [CheckCousinsChildTypeId] CHECK  (([dbo].[Func_CousinsWithSameChildTypeId]([Id],[ParentId],[ChildTypeId])=(0)))
GO

ALTER TABLE [dbo].[Children] CHECK CONSTRAINT [CheckCousinsChildTypeId]
GO