如何为每个组添加一个字段?

时间:2017-03-11 14:22:54

标签: sql-server sql-server-2014

我有以下表格:

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

如何使用条件唯一约束来实现它?

2 个答案:

答案 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