问题:
我想在映射表(n:n)上添加唯一约束
我希望可以插入新值,但前提是TEST_FK_UID,TEST_DateFrom和TEST_DateTo不等于已存在的条目。
问题是状态字段
状态1表示有效..
状态!= 1表示不活动/已删除..
。
。
因此,当然可以插入具有相同FK,DateFrom和DateTo,IF的新条目 - 并且仅当 - 现有条目的状态(所有现有条目,因为您可以插入,删除,插入,删除,插入,删除,等)是!= 1
这是我到目前为止所做的:
CREATE TABLE dbo._________Test
(
TEST_UID uniqueidentifier NOT NULL
,TEST_FK_UID uniqueidentifier NOT NULL
,TEST_DateFrom DateTime NOT NULL
,TEST_DateTo DateTime NOT NULL
,TEST_Status int NOT NULL
,UNIQUE(TEST_FK_UID, TEST_DateFrom, TEST_DateTo, TEST_Status)
);
答案 0 :(得分:3)
你做不到。但是,您可以创建唯一的索引。它的功能类似,我期待你足够好。
CREATE UNIQUE INDEX MyIndex
ON _________Test
( TEST_FK_UID
, TEST_DateFrom
, TEST_DateTo )
WHERE TEST_Status = 1
唯一索引和唯一约束之间最重要的区别是,您无法在另一个引用唯一索引的表中创建外键。 编辑:as Martin指出,事实并非如此,外键可以引用未经过滤的唯一索引。
答案 1 :(得分:0)
在INSERT,UPDATE操作上使用而不是触发器.. 并使用INSERTED表中的值检查现有值(在触发器的情况下创建) 如果INSERTED表中的状态为1,如果它是唯一的,则执行插入操作或仅使用某些消息中止..
答案 2 :(得分:0)
这很可能,就像这样 (基本功劳归于:https://stackoverflow.com/users/103075):
<小时/> 修改:
请注意以下这一行:
AND ZO_RMMIO_UID != @in_ZO_RMMIO_UID
(ZO_RMMIO_UID是n:n映射表的唯一主键)
这很重要,因为检查约束似乎与onAfterInsert触发器类似。
如果缺少这一行,它也会自行检查,这导致函数总是返回true ...
IF EXISTS (SELECT * FROM sys.check_constraints WHERE object_id = OBJECT_ID(N'[dbo].[CheckNoDuplicate_T_ZO_AP_Raum_AP_Ref_Mietobjekt]') AND parent_object_id = OBJECT_ID(N'[dbo].[T_ZO_AP_Raum_AP_Ref_Mietobjekt]'))
ALTER TABLE [dbo].[T_ZO_AP_Raum_AP_Ref_Mietobjekt] DROP CONSTRAINT [CheckNoDuplicate_T_ZO_AP_Raum_AP_Ref_Mietobjekt]
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fu_InsertCheck_IsDuplicate_T_ZO_AP_Raum_AP_Ref_Mietobjekt]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
DROP FUNCTION [dbo].[fu_InsertCheck_IsDuplicate_T_ZO_AP_Raum_AP_Ref_Mietobjekt]
GO
-- ========================================================================
-- Author: Me
-- Create date: 09.08.2010
-- Last modified: 09.08.2010
-- Description: Conditionally check if row is a duplicate
-- ========================================================================
-- PRE: UID, Valid RM_UID, Valid MIO_UID,
-- Valid datetime-from for db usr language, valid datetime-to for db usr language
-- POST: True/False
CREATE FUNCTION [dbo].[fu_InsertCheck_IsDuplicate_T_ZO_AP_Raum_AP_Ref_Mietobjekt](@in_ZO_RMMIO_UID uniqueidentifier, @in_ZO_RMMIO_RM_UID AS uniqueidentifier, @in_ZO_RMMIO_MIO_UID as uniqueidentifier, @in_ZO_RMMIO_DatumVon AS datetime, @in_ZO_RMMIO_DatumBis AS datetime)
RETURNS bit
AS
BEGIN
DECLARE @bIsDuplicate AS bit
SET @bIsDuplicate = 'false'
DECLARE @bNoCheckForThisCustomer AS bit
SET @bNoCheckForThisCustomer = 'false'
IF @bNoCheckForThisCustomer = 'true'
RETURN @bIsDuplicate
IF EXISTS
(
SELECT
ZO_RMMIO_UID
,ZO_RMMIO_RM_UID
,ZO_RMMIO_MIO_UID
FROM T_ZO_AP_Raum_AP_Ref_Mietobjekt
WHERE ZO_RMMIO_Status = 1
AND ZO_RMMIO_UID != @in_ZO_RMMIO_UID
AND ZO_RMMIO_RM_UID = @in_ZO_RMMIO_RM_UID
AND ZO_RMMIO_MIO_UID = @in_ZO_RMMIO_MIO_UID
AND ZO_RMMIO_DatumVon = @in_ZO_RMMIO_DatumVon
AND ZO_RMMIO_DatumBis = @in_ZO_RMMIO_DatumBis
)
SET @bIsDuplicate = 'true'
RETURN @bIsDuplicate
END
GO
ALTER TABLE [dbo].[T_ZO_AP_Raum_AP_Ref_Mietobjekt] WITH NOCHECK ADD CONSTRAINT [CheckNoDuplicate_T_ZO_AP_Raum_AP_Ref_Mietobjekt]
CHECK
(
NOT
(
dbo.fu_InsertCheck_IsDuplicate_T_ZO_AP_Raum_AP_Ref_Mietobjekt(ZO_RMMIO_UID, ZO_RMMIO_RM_UID, ZO_RMMIO_MIO_UID, ZO_RMMIO_DatumVon, ZO_RMMIO_DatumBis) = 1
)
)
GO
ALTER TABLE [dbo].[T_ZO_AP_Raum_AP_Ref_Mietobjekt] CHECK CONSTRAINT [CheckNoDuplicate_T_ZO_AP_Raum_AP_Ref_Mietobjekt]
GO
这是一个测试用例:
CREATE TABLE [dbo].[T_ZO_AP_Raum_AP_Ref_Mietobjekt](
[ZO_RMMIO_UID] [uniqueidentifier] NOT NULL, -- <== PRIMARY KEY
[ZO_RMMIO_RM_UID] [uniqueidentifier] NOT NULL,
[ZO_RMMIO_MIO_UID] [uniqueidentifier] NOT NULL,
[ZO_RMMIO_DatumVon] [datetime] NOT NULL,
[ZO_RMMIO_DatumBis] [datetime] NOT NULL,
[ZO_RMMIO_Status] [int] NOT NULL,
[ZO_RMMIO_Bemerkung] [text] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
/*
DELETE FROM T_ZO_AP_Raum_AP_Ref_Mietobjekt
WHERE ZO_RMMIO_Status = 1
AND ZO_RMMIO_RM_UID = '2007B6F5-9010-4979-AB39-00057DA353C0'
AND ZO_RMMIO_MIO_UID = 'FFA177E9-971E-4500-805D-00116F708E7B'
*/
INSERT INTO T_ZO_AP_Raum_AP_Ref_Mietobjekt
(
ZO_RMMIO_UID
,ZO_RMMIO_RM_UID
,ZO_RMMIO_MIO_UID
,ZO_RMMIO_DatumVon
,ZO_RMMIO_DatumBis
,ZO_RMMIO_Status
,ZO_RMMIO_Bemerkung
)
VALUES
(
NEWID() --<ZO_RMMIO_UID, uniqueidentifier,>
,'2007B6F5-9010-4979-AB39-00057DA353C0' --<ZO_RMMIO_RM_UID, uniqueidentifier,>
,'FFA177E9-971E-4500-805D-00116F708E7B' --<ZO_RMMIO_MIO_UID, uniqueidentifier,>
,'01.01.2012' --<ZO_RMMIO_DatumVon, datetime,>
,'31.12.2999' --<ZO_RMMIO_DatumBis, datetime,>
,1 --<ZO_RMMIO_Status, int,>
,NULL--<ZO_RMMIO_Bemerkung, text,>
)
GO
INSERT INTO T_ZO_AP_Raum_AP_Ref_Mietobjekt
(
ZO_RMMIO_UID
,ZO_RMMIO_RM_UID
,ZO_RMMIO_MIO_UID
,ZO_RMMIO_DatumVon
,ZO_RMMIO_DatumBis
,ZO_RMMIO_Status
,ZO_RMMIO_Bemerkung
)
VALUES
(
NEWID() --<ZO_RMMIO_UID, uniqueidentifier,>
,'2007B6F5-9010-4979-AB39-00057DA353C0' --<ZO_RMMIO_RM_UID, uniqueidentifier,>
,'FFA177E9-971E-4500-805D-00116F708E7B' --<ZO_RMMIO_MIO_UID, uniqueidentifier,>
,'01.01.2012' --<ZO_RMMIO_DatumVon, datetime,>
,'31.12.2999' --<ZO_RMMIO_DatumBis, datetime,>
,1 --<ZO_RMMIO_Status, int,>
,NULL--<ZO_RMMIO_Bemerkung, text,>
)
GO
SELECT [ZO_RMMIO_UID]
,[ZO_RMMIO_RM_UID]
,[ZO_RMMIO_MIO_UID]
,[ZO_RMMIO_DatumVon]
,[ZO_RMMIO_DatumBis]
,[ZO_RMMIO_Status]
,[ZO_RMMIO_Bemerkung]
FROM [T_ZO_AP_Raum_AP_Ref_Mietobjekt]