Necromancing.
Birisi buraya geldiğinde, benzersiz olmayan anahtarlar içeren bir tabloda sütun için yabancı bir anahtara ihtiyacı olduğunu varsayıyorum.
Sorun, bu sorun varsa, veritabanı şemasının denormalized olmasıdır.
Örneğin, odaları aynı odada izlemek için bir oda-uid birincil anahtarı, bir DateFrom ve bir DateTo alanı ve başka bir uid, RM_ApertureID ve RM_Status gibi bir yumuşak silme alanı, burada 99 'silinmiş' anlamına gelir ve <> 99 'aktif' anlamına gelir.
İlk odayı oluşturduğunuzda, RM_UID ve RM_ApertureID değerlerini RM_UID ile aynı değer olarak eklersiniz. Ardından, odayı bir tarihe sonlandırıp yeni bir tarih aralığıyla yeniden oluşturduğunuzda, RM_UID newid () olur ve önceki girişten RM_ApertureID değeri yeni RM_ApertureID olur.
Bu durumda, RM_ApertureID benzersiz olmayan bir alandır ve başka bir tabloda yabancı anahtar ayarlayamazsınız.
Benzersiz olmayan bir sütuna / dizine yabancı anahtar ayarlamanın bir yolu yoktur; örneğin, T_ZO_REM_AP_Raum_Reinigung'da (WHERE RM_UID aslında RM_ApertureID'dir).
Ancak geçersiz değerleri yasaklamak için yabancı bir anahtar ayarlamanız gerekir, aksi takdirde veri çöpü daha sonra değil, daha erken sonuçtur ...
Şimdi bu durumda yapabilecekleriniz (tüm uygulamayı yeniden yazmanın kısa bir yolu), anahtarın varlığını kontrol eden bir skaler fonksiyon ile bir CHECK kısıtlaması ekliyor:
IF EXISTS (SELECT * FROM sys.check_constraints WHERE object_id = OBJECT_ID(N'[dbo].[Check_RM_ApertureIDisValid_T_ZO_REM_AP_Raum_Reinigung]') AND parent_object_id = OBJECT_ID(N'[dbo].[T_ZO_REM_AP_Raum_Reinigung]'))
ALTER TABLE dbo.T_ZO_REM_AP_Raum_Reinigung DROP CONSTRAINT [Check_RM_ApertureIDisValid_T_ZO_REM_AP_Raum_Reinigung]
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fu_Constaint_ValidRmApertureId]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
DROP FUNCTION [dbo].[fu_Constaint_ValidRmApertureId]
GO
CREATE FUNCTION [dbo].[fu_Constaint_ValidRmApertureId](
@in_RM_ApertureID uniqueidentifier
,@in_DatumVon AS datetime
,@in_DatumBis AS datetime
,@in_Status AS integer
)
RETURNS bit
AS
BEGIN
DECLARE @bNoCheckForThisCustomer AS bit
DECLARE @bIsInvalidValue AS bit
SET @bNoCheckForThisCustomer = 'false'
SET @bIsInvalidValue = 'false'
IF @in_Status = 99
RETURN 'false'
IF @in_DatumVon > @in_DatumBis
BEGIN
RETURN 'true'
END
IF @bNoCheckForThisCustomer = 'true'
RETURN @bIsInvalidValue
IF NOT EXISTS
(
SELECT
T_Raum.RM_UID
,T_Raum.RM_Status
,T_Raum.RM_DatumVon
,T_Raum.RM_DatumBis
,T_Raum.RM_ApertureID
FROM T_Raum
WHERE (1=1)
AND T_Raum.RM_ApertureID = @in_RM_ApertureID
AND @in_DatumVon >= T_Raum.RM_DatumVon
AND @in_DatumBis <= T_Raum.RM_DatumBis
AND T_Raum.RM_Status <> 99
)
SET @bIsInvalidValue = 'true' -- IF !
RETURN @bIsInvalidValue
END
GO
IF EXISTS (SELECT * FROM sys.check_constraints WHERE object_id = OBJECT_ID(N'[dbo].[Check_RM_ApertureIDisValid_T_ZO_REM_AP_Raum_Reinigung]') AND parent_object_id = OBJECT_ID(N'[dbo].[T_ZO_REM_AP_Raum_Reinigung]'))
ALTER TABLE dbo.T_ZO_REM_AP_Raum_Reinigung DROP CONSTRAINT [Check_RM_ApertureIDisValid_T_ZO_REM_AP_Raum_Reinigung]
GO
-- ALTER TABLE dbo.T_AP_Kontakte WITH CHECK ADD CONSTRAINT [Check_RM_ApertureIDisValid_T_ZO_REM_AP_Raum_Reinigung]
ALTER TABLE dbo.T_ZO_REM_AP_Raum_Reinigung WITH NOCHECK ADD CONSTRAINT [Check_RM_ApertureIDisValid_T_ZO_REM_AP_Raum_Reinigung]
CHECK
(
NOT
(
dbo.fu_Constaint_ValidRmApertureId(ZO_RMREM_RM_UID, ZO_RMREM_GueltigVon, ZO_RMREM_GueltigBis, ZO_RMREM_Status) = 1
)
)
GO
IF EXISTS (SELECT * FROM sys.check_constraints WHERE object_id = OBJECT_ID(N'[dbo].[Check_RM_ApertureIDisValid_T_ZO_REM_AP_Raum_Reinigung]') AND parent_object_id = OBJECT_ID(N'[dbo].[T_ZO_REM_AP_Raum_Reinigung]'))
ALTER TABLE dbo.T_ZO_REM_AP_Raum_Reinigung CHECK CONSTRAINT [Check_RM_ApertureIDisValid_T_ZO_REM_AP_Raum_Reinigung]
GO
table1.ID
?