我有以下表格:
CardsTable:
-------
CardID int
PersonID int
Number int
-----------------------
CardID PersonID Number
1 10 22
2 10 22
3 11 24
4 11 24
5 10 22
对于具有相同ID的所有Number field
, personID
应该是唯一的。
Following example is invalid:
CardID PersonID CardID
6 11 22
7 12 22
8 12 24
如何使用条件唯一约束来实现它?
答案 0 :(得分:1)
您可以使用具有用户定义函数的检查约束:
首先,创建函数:
CREATE FUNCTION dbo.CheckCards
(
@PersonId int,
@Number int
)
RETURNS bit
AS
BEGIN
IF EXISTS
(
SELECT 1
FROM CardsTable
WHERE PersonId = @PersonId
AND Number <> @Number
)
BEGIN
RETURN 1
END
RETURN 0
END
GO
现在,创建并填充样本表:
CREATE TABLE CardsTable
(
CardID int,
PersonID int,
Number int,
CONSTRAINT ck CHECK (dbo.CheckCards(PersonId, Number) = 0)
)
INSERT INTO CardsTable VALUES
(1, 10, 22),
(2, 10, 22),
(3, 11, 24),
(4, 11, 24),
(5, 10, 22)
然后测试检查约束:
BEGIN TRY
INSERT INTO CardsTable VALUES (3, 10, 24)
SELECT 'Success' As [Insert]
END TRY
BEGIN CATCH
SELECT 'Failed' As [Insert]
END CATCH
SELECT *
FROM CardsTable
结果:
Insert
Failed
CardID PersonID Number
1 10 22
2 10 22
3 11 24
4 11 24
5 10 22
答案 1 :(得分:0)
您应该在表格上实现“插入”和“更新”的触发器,如下所示:
Create trigger trigger_cardstable_insert on cardstable
after insert
as
Begin
set nocount on;
if (select count(c.personid) from cardstable c inner join inserted i on i.personid group by i.personid, c.number) > 1
Begin
Delete cardstable
From cardstable c inner join inserted i on i.cardid = c.cardid
End
End
对于更新,它会有所不同,您需要再添加一个条件:
Create trigger trigger_cardstable_update on cardstable
after update
as
Begin
set nocount on;
if update(number) and personid(select count(c.personid) from cardstable c inner join inserted i on i.personid group by i.personid, c.number) > 1
Begin
Delete cardstable
From cardstable c inner join inserted i on i.cardid = c.cardid
End
End