Nekromantie.
Ich gehe davon aus, dass jemand, der hier landet, einen Fremdschlüssel benötigt, um in einer Tabelle zu spalten, die nicht eindeutige Schlüssel enthält.
Das Problem ist, dass das Datenbankschema denormalisiert wird, wenn Sie dieses Problem haben.
Sie behalten beispielsweise Räume in einer Tabelle mit einem Primärschlüssel für die Raum-UID, einem DateFrom- und einem DateTo-Feld sowie einer anderen UID, hier RM_ApertureID, um denselben Raum zu verfolgen, und einem Soft-Delete-Feld wie RM_Status. Dabei bedeutet 99 "gelöscht" und <> 99 "aktiv".
Wenn Sie also den ersten Raum erstellen, fügen Sie RM_UID und RM_ApertureID als denselben Wert wie RM_UID ein. Wenn Sie dann den Raum auf ein Datum beenden und ihn mit einem neuen Datumsbereich wiederherstellen, ist RM_UID newid (), und die RM_ApertureID aus dem vorherigen Eintrag wird zur neuen RM_ApertureID.
In diesem Fall ist RM_ApertureID ein nicht eindeutiges Feld, sodass Sie keinen Fremdschlüssel in einer anderen Tabelle festlegen können.
Und es gibt keine Möglichkeit, einen Fremdschlüssel auf eine nicht eindeutige Spalte / einen nicht eindeutigen Index zu setzen, z. B. in T_ZO_REM_AP_Raum_Reinigung (WHERE RM_UID ist tatsächlich RM_ApertureID).
Um ungültige Werte zu verhindern, müssen Sie einen Fremdschlüssel festlegen. Andernfalls ist Datenmüll eher früher als später die Folge ...
In diesem Fall können Sie nun (ohne die gesamte Anwendung neu zu schreiben) eine CHECK-Einschränkung einfügen, wobei eine Skalarfunktion das Vorhandensein des Schlüssels überprüft:
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
?