同时将数据插入多个表

时间:2017-09-13 19:22:39

标签: sql sql-server tsql

这就是我想要做的事情:

我们说我有两张桌子dbo.source& dbo.destination 我希望将所有记录从源复制到目标,如果目标中不存在某个自然键(唯一的非群集)。如果插入成功,则将一些值输出到临时缓冲表。 接下来我想列出来自DID在目的地中匹配的来源的所有记录,并将这些记录复制到缓冲表中。

无论如何我可以实现这一点,以便缓冲表不能保存冗余数据吗?

这是我目前的逻辑:

步骤1:从源表中获取自然键与目标不匹配的记录并插入目标 将这些插入带有标志

的缓冲区表中
MERGE INTO dbo.Destination dest USING dbo.Source AS src 
ON dest.Name = src.Name --Natural Key
WHEN NOT MATCHED THEN
INSERT (xxx) VALUES (xxx)
OUTPUT src.ID, Inserted.ID, 'flagA'
INTO dbo.Buffer;

步骤2: 从源表中获取自然键与目标匹配的记录 将这些插入缓冲区并带有标志

Insert INTO dbo.Buffer
Select src.ID, src.Name, 'flagB'
FROM dbo.Source src 
inner join dbo.Destination dest
on src.Name = dest.Name

有了这个逻辑,我在我的缓冲区中获得了多余的行,这些行并没有按预期精确地跟踪插入。任何人都可以基于我想要做的事情批评我的SQL。

2 个答案:

答案 0 :(得分:3)

你可以尝试一下这样的技巧,不喜欢这种技术就是你总是更新一个字段。也许,你需要根据自己的需要调整我的例子。

Redux

结果

目的地表

DECLARE @Source table (id int identity , myValue varchar(5))
DECLARE @Destination table (id int identity  , myValue varchar(5))
DECLARE @Buffer table (sourceId int , InsertId varchar(5),flag varchar(5))

insert @Source (myValue) values ( 'a') ,( 'e'),( 'i'),( 'o'),( 'u')
insert @Destination (myValue) values ('a') ,('b'),('c')

;merge @Destination t 
using @Source S 
on
t.myValue = s.myValue
when not matched then insert (myValue) values (s.myValue)
when matched then update set myValue = t.myValue
output s.id, inserted.id, case $action when 'INSERT' then 'flagA' else 'flagB' end into @Buffer;


select * from @Destination
select * from @Buffer

缓冲表

id          myValue
----------- -------
1           a
2           b
3           c
4           e
5           i
6           o
7           u

使用此输出

sourceId    InsertId flag
----------- -------- -----
2           4        flagA
3           5        flagA
4           6        flagA
5           7        flagA
1           1        flagB

output s.id, case $action when 'INSERT' then Cast(inserted.id as varchar(5)) else inserted.myValue end , case $action when 'INSERT' then 'flagA' else 'flagB' end into @Buffer;

答案 1 :(得分:2)

运行第二个查询时,它也匹配刚刚插入的行。你应该这样做:

Insert INTO dbo.Buffer
Select src.ID, src.name, 'flagB'
FROM dbo.Source src
    inner join dbo.Destination dest on src.Name = dest.Name
where not exists (
    select * from dbo.Buffer b where b.xxx = 'flagA' and b.yyy = src.name
)

或者只是在与目标匹配时使用,如LONG建议的那样。