2016-05-11 3 views
1

Ich habe die folgende Tabellenstruktur:Unique-Einschränkung basiert auf Großeltern in SQL Server

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

Ich möchte eine eindeutige Einschränkung sagen, dass zwei Kinder können nicht die gleiche ChildTypeId haben, wenn sie eine gemeinsame GrandParentId haben. Ist das mit SQL Server möglich?

Antwort

1

Sie können dies nicht mit einer UNIQUE-Einschränkung tun, aber Sie können es mit einer CHECK-Integritätsbedingung ausführen, die eine UDF aufruft.

Schreiben Sie eine UDF, die eine ChildId akzeptiert und einen JOIN von Child und Parent abfragt, um festzustellen, ob es noch ein Kind mit derselben GrandParentID und ChildTypeId gibt. Wenn dies der Fall ist, gebe wahr/falsch zurück.

Rufen Sie dann in der CHECK-Integritätsregel diese Funktion auf, übergeben Sie die ChildId, und überprüfen Sie, ob das Ergebnis der Funktion wahr/falsch ist.

Sie können es auch mit einem TRIGGER tun, aber ich bevorzuge Einschränkungen.

0

andere zu beschleunigen auf diesen Beitrag stolpern, hier ist ein SQL-Beispiel dafür, was Tab Alleman ist darauf hindeutet:

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 

dann mit so etwas wie

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 
die Prüf-Integritäts hinzufügen
Verwandte Themen