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

时间:2016-09-27 12:56:50

标签: sql sql-server tsql

我们维护了一个旧数据库,以及我们已经开始使用的新数据库。我们需要定期将数据从旧数据库传输到新数据库。目前,我们需要将旧数据库中的一个表 - 学生中的数据转移或合并,或者将其合并为新表中的两个表(即两个目标) - < strong>人和学生。现在的问题是来自旧的源数据库的数据应该在新的数据库中的两个表之间进行划分。例如(仅为了这篇文章),

旧表&#39;学生&#39;

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

新表&#39;人物

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

新表&#39;学生

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

程序应该采用要合并的行数参数 如何实现这一目标?

更新

也许你们更容易知道伪代码的含义:

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

我希望这会让它更清晰。

1 个答案:

答案 0 :(得分:1)

我们可以假设你想在一个语句而不是两个语句中执行此操作的原因是,如果要插入的第一个表中的字段是一个标识字段(在示例中为Person表中的Id),则需要插入第二个表?

如果是这样,请在第一个合并语句中添加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