使用复合主键在表上插入选择

时间:2012-05-28 11:41:02

标签: sql-server tsql

如果您有一个包含两个主键的表:

CREATE TABLE [AttributeMap](
[intParentAttributeId] [bigint] NOT NULL,
[intChildAttributeId] [bigint] NOT NULL,
    [datCreatedDate] [datetime] NOT NULL
  CONSTRAINT [PK_AttributeMap] PRIMARY KEY CLUSTERED 
 ( 
   [intParentAttributeId] ASC,
    [intChildAttributeId] ASC
 )

如果要插入/ select语句以向表中添加数据,如何限制数据以确保它不会违反这两个键?

因此,如果您将其插入上表:

INSERT INTO [AttributeMap] VALUES (1, 1, getdate())
INSERT INTO [AttributeMap] VALUES (1, 2, getdate())
INSERT INTO [AttributeMap] VALUES (1, 3, getdate())
INSERT INTO [AttributeMap] VALUES (2, 1, getdate())

如何在不违反密钥的情况下运行此查询?

declare table @temp (intParent int, intChild int)
insert into @temp (1, 1)
insert into @temp (1, 2)
insert into @temp (4, 4)
insert into @temp (5, 5)

 insert into AttributeMap (intParentAttributeId, intChildAttributeId, datCreatedDate)
  select intParent, intChild, getDate()
 from @temp

因此,AttributeMap最终应该有两个新行,值为4,4,“date”和5,5“date”。有意义吗?

干杯, 马特

2 个答案:

答案 0 :(得分:3)

EXCEPT

  

返回EXCEPT操作数左侧的查询中的任何不同值,这些值也不是从右侧查询返回的。

试试这个:

insert into AttributeMap (intParentAttributeId, intChildAttributeId, datCreatedDate)
Select temp.intParent, temp.intChild, getDate()
FROM 
(select intParent, intChild
from @temp 
EXCEPT 
select intParentAttributeId, intChildAttributeId
from AttributeMap) as temp

答案 1 :(得分:1)

您需要手动检查密钥是否已存在,只有在密钥不存在时才插入:

 insert into AttributeMap (intParentAttributeId, intChildAttributeId, datCreatedDate)
 select intParent, intChild, getDate()
   from @temp t
  where not exists (select null
                      from AttributeMap
                     where AttributeMap.intParent = t.intParent
                       and AttributeMap.intChild = t.intChild
                   )