T SQL循环插入或更新

pav*_*lcc 2 sql t-sql sql-server stored-procedures sql-server-2005

我有两张桌子.

表A和表B.列是相同的.

create table TableA (
    id int
    , name varchar
    , last datetime
)

create table TableB (
    id int
    , name varchar
    , last datetime
)
Run Code Online (Sandbox Code Playgroud)

我用大量数据填充表A. 我想将表A中的数据插入或更新到表B中.

我想从表A中获取数据,如果id和name doenst匹配则插入到表B中,如果id和name匹配则更新.

我尝试了一些ETL工具,但结果非常慢.我有id和name的索引,我想用SQL尝试这个.

我有以下但不正确的工作:

SELECT      @id = ID, 
      @name = name, 
      @LSDATE = LastSeen_DateTime   
            FROM DBO.A
IF EXISTS (SELECT ID, name FROM DBO.A
WHERE  @ID = ID AND @name = Name)
Run Code Online (Sandbox Code Playgroud)

begin - update end else begin --insert end

我想我需要把它放在一个循环中并且不太确定如何使这个运行.

谢谢.

Con*_*rix 6

它可能更快做两个语句一个更新和一个插入而不是循环

此语句使用A中的数据更新所有B行,其中ID相同但名称不同

更新

Update 
    tableB
SET
   name = a.Name
From
   tableB a
   INNER JOIN tableA a
   on b.ID = a.ID 
      and A.Name <> b.Name
Run Code Online (Sandbox Code Playgroud)

此语句将所有B行插入到A中,其中id不存在于A中

插入

INSERT INTO
   tableB
(   ID,
    Name
)
SELECT
   a.ID
   a.Name
FROM 
   tableA b
WHERE
   not exists (Select A.ID From tableB a WHERE a.ID = b.ID)
Run Code Online (Sandbox Code Playgroud)

更新(将其从A转换为B而不是B转换为A)


Tan*_*ena 6

如果您使用的是SQL Server 2008(或Oracle或DB2),则可以使用合并语句.

MERGE B
USING A AS source 
ON (B.ID = source.ID and B.Name = source.Name)
WHEN MATCHED THEN 
    UPDATE SET Last = source.Last
WHEN NOT MATCHED BY TARGET THEN
    INSERT (ID, Name, Last) VALUES (source.ID, source.Name, source.Last)

   -- the following is optional, if you remove it, add a semicolon to the end of the above line. 
   OUTPUT $action, 
   inserted.ID AS SourceID, inserted.Name AS SourceName, 
   inserted.Last AS SourceLast, 
   deleted.ID AS TargetID, deleted.Name AS TargetName, 
   deleted.Last AS TargetLast ;   
Run Code Online (Sandbox Code Playgroud)

带有"output $ action"的位将显示哪些行正在更新以及哪些行正在更新.

黄鼠狼的话:我承认这不是正是你要找的,但因为其他人可以搜索这个话题,它可能是其他人在未来有帮助的.