Necromancing。
我假设有人在这里登陆时,他需要一个外键列入包含非唯一键的表中。
问题是,如果你有这个问题,数据库模式是非规范化的。
例如,您将一个房间保存在一个表格中,其中包含room-uid主键,DateFrom和DateTo字段,以及另一个uid,这里是RM_ApertureID以跟踪同一个房间,以及软删除字段,如RM_Status,其中99表示“已删除”,而<> 99表示“有效”。
因此,当您创建第一个房间时,将RM_UID和RM_ApertureID作为与RM_UID相同的值插入。 然后,当您将房间终止到某个日期并重新建立新日期范围时,RM_UID为newid(),并且来自先前条目的RM_ApertureID变为新的RM_ApertureID。
所以,如果是这样的话,RM_ApertureID是一个非唯一的字段,所以你不能在另一个表中设置一个外键。
而且没有办法将外键设置为非唯一的列/索引,例如,在T_ZO_REM_AP_Raum_Reinigung(WHERE RM_UID实际上是RM_ApertureID)。
但禁止无效的值,你需要设置一个外键,否则,数据垃圾是结果宜早不宜迟...
现在你可以在这种情况下做什么(短rewritting整个应用程序的)插入一个CHECK约束,用标量函数检查密钥是否存在:
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'? – zerkms
这是明确的,如果你的AnothidID不是主键它应该是一个ForeignKey,所以作为一个ForeignKey,你的table2应该指向同一个表(可能的table3) –