简体   繁体   English

SQL 将源表中的 n 行合并到两个目标

[英]SQL Merge n rows from source table to two targets

We have an old database that we maintain, and a new one that we have started using.我们有一个我们维护的旧数据库,一个我们已经开始使用的新数据库。 We need to periodically transfer data from the old db to the new one.我们需要定期将数据从旧数据库传输到新数据库。 At the moment, we need to transfer, or merge as it might also be called, data from one table - Student , in the old database to two tables (ie two targets) in the new one - Person and Student .目前,我们需要将旧数据库中的一张表Student中的数据传输或合并(也称为合并)到新的PersonStudent中的两个表(即两个目标)。 Now the catch is that the data from the old, source, database should be divided among the two tables in the new one.现在的问题是来自旧的源数据库的数据应该在新的两个表中分配。 For example (just for the sake of this post),例如(只是为了这篇文章),

Old table 'Student'旧表“学生”

------------------------------  
IdNo | FirstName | LastName  |
578  | John      | Doe       |
645  | Sara      | Doe       |

New table 'Person'新表“人”

-----------
Id | IdNo |
11 | 578  |
23 | 645  |  

New table 'Student'新表“学生”

--------------------------------------  
Id | PersonId | FirstName | LastName | 
101| 11       | John      | Doe      |
102| 23       | Sara      | Doe      |

And the procedure should take a parameter of the number of rows to merge.并且该过程应该采用要合并的行数的参数。
How can this be accomplished?如何做到这一点?

Update更新

Perhaps it would be easier for you guys to know what I mean by pseudo code:也许你们更容易知道我所说的伪代码是什么意思:

MERGE [NewDB].[dbo].[Person] p, [NewDB].[dbo].[Student] ns -- 2 targets, this does not work
USING [OldDB].[dbo].[student] os                -- source table, old student
ON p.IdNo = s.IdNo
WHEN MATCHED THEN                               -- Update existing rows
    UPDATE p
    SET p.SomeCoumn1 = os.SomeColumn1      -- works. os (old student) is know here
    UPDATE ns
    SET ns.SomeColumn2 = os.SomeColumn2     -- Does not work. os is not known here
WHEN NOT MATCHED BY TARGET THEN                 -- Add new rows
    INSERT INTO p (IdNo, SomeOlumn1)
    VALUES (os.Idno, os.SomeColumn1);           -- os (old Studnet) is known here
    INSERT INTO ns (SomeColumn2)    
    VALUES (os.SomeColumn2);                 -- Does not work. os is not knwon here

I hope that makes it somewhat clearer.我希望这使它更清楚一些。

May we assume the reason you want to do this in one statement instead of two is that one if the fields in the first table you are inserting in to is an identity field (Id in the Person table in your example) that needs to be inserted into the second table?我们是否可以假设您想在一个语句而不是两个语句中执行此操作的原因是,如果您要插入的第一个表中的字段是需要插入的标识字段(在您的示例中 Person 表中的 ID)进入第二张桌子?

If so, add an OUTPUT clause in the first merge statement so that you have the relationship and fields you require for the second merge statement.如果是这样,请在第一个合并语句中添加一个 OUTPUT 子句,以便您拥有第二个合并语句所需的关系和字段。

declare @OldStudent table (IdNo int, FirstName varchar(30), LastName varchar(30))

declare @Person table (Id int identity, IdNo int)

declare @NewStudent table (Id int identity, PersonId int, FirstName varchar(30), LastName varchar(30))

insert @OldStudent (IdNo, FirstName, LastName)
select 578, 'John', 'Doe'
union all select 645, 'Sara', 'Doe'

declare @output table ([Action] varchar(20), PersonId int, IdNo int)

MERGE @Person p
USING @OldStudent os        
ON p.IdNo = os.IdNo
WHEN MATCHED THEN                               -- Update existing rows
    UPDATE  SET IdNo = os.IdNo
WHEN NOT MATCHED BY TARGET THEN                 -- Add new rows
    INSERT  (IdNo) VALUES (os.Idno) 
OUTPUT $action, inserted.Id, inserted.IdNo into @output;

WITH src AS 
(
    select
        o.IdNo, o.PersonId, os.FirstName, os.LastName
    from
        @output o
        inner join @OldStudent os on os.IdNo = o.IdNo
)
MERGE INTO @NewStudent as ns
USING src
ON src.PersonID = ns.PersonID
WHEN MATCHED THEN                               
    UPDATE SET FirstName = src.FirstName, LastName = src.LastName
WHEN NOT MATCHED BY TARGET THEN                 -- Add new rows
    INSERT (PersonID, FirstName, LastName) VALUES (src.PersonID, src.FirstName, src.LastName);


select * from @Person
select * from @NewStudent

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM