我有以下表结构:
Grandparent - GrandParentId (PK)
Parent - ParentId (PK), GrandParentId (FK)
Child - ChildId (PK), ChildTypeId (FK), ParentId (FK)
我想要一个独特的约束,如果他们有一个共同的ChildTypeId
,那么两个孩子就不能拥有相同的GrandParentId
。这可能与SQL Server一起使用吗?
答案 0 :(得分:1)
你不能用UNIQUE约束来做,但你可以用调用UDF的CHECK约束来做。
编写一个接收ChildId的UDF并查询Child和Parent的JOIN,以查看是否有另一个具有相同GrandParentID和ChildTypeId的子项。如果有,则返回true / false。
然后在CHECK约束中,调用该函数,传递ChildId,并检查函数的结果是否为true / false。
您也可以使用TRIGGER,但我更喜欢约束。
答案 1 :(得分:0)
加速其他人在这篇文章上磕磕绊绊,这是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