2013-05-01 21 views
6

Üç tablo var:MS SQL Server çapraz tablo kısıtlaması

1) Uygulamaları (AppId, adı)
2) Ekran (ScreenId, adı)
3) İlişkisi (AppId, ScreenId)

Şimdi ilgili tabloya bazı kısıtlamalar uygulamak istiyorum: Aynı ekran birden fazla uygulamaya atanabilir, ancak aynı uygulamaya sahip aynı ada sahip iki ekran olamaz.

Screen.Name'i ilişkisel tabloya ekleyebileceğimi ve sonra AppId ve Screen.Name üzerinde PK oluşturabildiğimi biliyorum, ancak Screen.Name değişebileceğinden böyle bir çözüm istemiyorum.

Böyle bir kısıtlamaya ulaşmak için hangi ek seçeneklere sahibim?

cevap

8

Sen Relation ve Screen tablolar dayalı bir indexed view oluşturmak ve orada benzersiz kısıtlama uygulayabilirsiniz.

create view DRI_UniqueScreens 
with SCHEMABINDING 
as 
    select r.AppId,s.Name 
    from 
     [Schema].Relation r 
     inner join 
     [Schema].Screen s 
     on 
      r.ScreenId = s.ScreenId 
GO 
CREATE UNIQUE CLUSTERED INDEX IX_DRI_UniqueScreens 
    on DRI_UniqueScreens (AppId,Name) 
+0

Böyle bir şey olup olmadığını merak ettim. :) Tetikleyiciden çok daha iyi. :) – Jonathan

+0

Bu yöntem ekran adını değiştirirken verileri "doğrulayacaktır" ya da yalnızca görünüme erişirken verileri kontrol edecek mi? –

+2

@AlexDn - Evet, bu, alttaki tablolarda değişiklik yapıldığında kısıtlamayı zorlar. Bağlandığım sayfaya giderseniz, dizinlenmiş görünümlerde çok fazla kısıtlamanın olduğunu fark edeceksiniz. Bu kısıtlamaların çoğu vardır * çünkü * temel tablolardaki her işlem için gerekli bakım etkinliğinin verimli bir şekilde gerçekleşmesine izin verirler. –

0

Bu harika bir çözüm değil, değiştirdiğiniz öğelerin yalnızca ölçütlerinizi karşıladığını ve geri alınmadıklarını geri almak için ekranları ve ilişki tablolarını tetiklemek için tetikleyiciler ekleyebilirsiniz.

CREATE TRIGGER trgScreen ON Screen FOR INSERT, UPDATE 
AS 
BEGIN 
    IF EXISTS (SELECT r.AppID, s.Name FROM Screen s 
       INNER JOIN Relation r ON s.ScreenID = r.ScreenID 
       GROUP BY r.AppID, s.Name 
       HAVING count(*) > 1) 
     ROLLBACK TRANSACTION 
END 

CREATE TRIGGER trgRelation ON Relation FOR INSERT, UPDATE 
AS 
BEGIN 
    IF EXISTS (SELECT r.AppID, s.Name FROM Screen s 
       INNER JOIN Relation r ON s.ScreenID = r.ScreenID 
       GROUP BY r.AppID, s.Name 
       HAVING count(*) > 1) 
     ROLLBACK TRANSACTION 
END 
+0

Evet, tetikleyiciler çalışacak, ancak tetikleyicileri olabildiğince engellemeye çalışıyorum. –