繁体   English   中英

SQL Server 2014-MainTable和TempTable-如果不存在则插入其他更新

[英]SQL Server 2014 - MainTable & TempTable - IF Not Exists Insert Else Update

我在Microsoft SQL Server 2014上有两个表具有相同的列。

MainTable和TempTable。

我想将TempTable中的更新数据/新数据输入到MainTable中,以避免重复。

MainTable如下所示:

在此处输入图片说明

TempTable如下所示:

在此处输入图片说明

TempTable中的数据将不断变化。 它可能具有更新的数据或新的行。

我试图实现的是,将数据从TempTable插入/更新到MainTable。

TempTable :-在此示例中, 编号为101和104的行具有更新的数据。 它还具有Numbr 105和106的新行。 我想更新101和104的数据,并同时插入105和106。

请提出建议,因为我是SQL新手。


UPDATE1:

使用以下查询后:

--Insert New
INSERT INTO MAINTABLE
SELECT A.*
FROM 
TempTable as A 
LEFT JOIN MainTable as B
ON B.Number = A.Number
WHERE B.Number IS NULL

--Update Old
UPDATE A
SET A.Number = B.Number,
    A.Name = B.Name,
    A.LastActive = B.LastActive,
    A.Country = B.Country
FROM 
TempTable as A 
LEFT JOIN MainTable as B
ON B.Number = A.Number
WHERE B.Number IS NOT NULL

MainTable的输出:

在此处输入图片说明

它有效,但是当TempTable中的数据更新并添加新数据时:

在此处输入图片说明

运行查询后的结果:

MainTable和TempTable分别

在此处输入图片说明

添加了新的第108行(从TempTable-> MainTable ),但更新的第106行无效,并且从MainTable复制了TempTable中的值。

INSERT INTO MAINTABLE
SELECT A.*
FROM 
TempTable as A 
LEFT JOIN MainTable as B
ON B.Number = A.Number
WHERE B.Number IS NULL

--Update Old
UPDATE A
SET A.Name = B.Name,
A.LastActive = B.LastActive,
A.Country = B.Country
FROM TempTable as B 
INNER JOIN MainTable as A
 ON B.Number = A.Number
WHERE A.Name <> B.Name,
 A.LastActive <> B.LastActive,
 A.Country <> B.Country

我假设Numbr是两个表中的键或唯一字段。 如果不是这种情况,则不应使用这些查询。 此外,如果性能存在问题,则应在两个表中为该字段建立索引。

这是最简单的方法:

BEGIN TRANSACTION;
INSERT INTO MainTable (Numbr, Name, LastActive, Country)
SELECT t.Numbr, t.Name, t.LastActive, t.Country
FROM TempTable t
WHERE NOT EXISTS (SELECT 1 FROM MainTable m WHERE m.Numbr = t.Numbr);

UPDATE m
    SET Name = t.Name,
        LastActive = t.LastActive,
        Country = t.Country
FROM MainTable m
INNER JOIN TempTable t
    ON m.Numbr = t.Numbr
WHERE m.Name <> t.Name
    OR m.LastActive <> t.LastActive
    OR m.Country <> t.Country;
COMMIT;

请注意,如果“名称”,“ LastActive”或“国家/地区”是可为空的字段,则语法变得更加冗长。 例如,如果所有三个字段均可为空,则应使用以下语法:

BEGIN TRANSACTION;
INSERT INTO MainTable (Numbr, Name, LastActive, Country)
SELECT t.Numbr, t.Name, t.LastActive, t.Country
FROM TempTable t
WHERE NOT EXISTS (SELECT 1 FROM MainTable m WHERE m.Numbr = t.Numbr);

UPDATE m
    SET Name = t.Name,
        LastActive = t.LastActive,
        Country = t.Country
FROM MainTable m
INNER JOIN TempTable t
    ON m.Numbr = t.Numbr
WHERE m.Name <> t.Name
    OR (m.Name IS NULL AND t.Name IS NOT NULL)
    OR (m.Name IS NOT NULL AND t.Name IS NULL)
    OR m.LastActive <> t.LastActive
    OR (m.LastActive IS NULL AND t.LastActive IS NOT NULL)
    OR (m.LastActive IS NOT NULL AND t.LastActive IS NULL)
    OR m.Country <> t.Country
    OR (m.Country IS NULL AND t.Country IS NOT NULL)
    OR (m.Country IS NOT NULL AND t.Country IS NULL);
COMMIT;

如果绝对需要最大程度地减少写入次数,则应将UPDATE语句分解为每个字段的一个查询。 这可能会运行得更快或更慢,所以仅仅因为您编写的内容较少并不意味着查询将执行得更快。 同样,我假设您的系统中没有可为空的字段:

BEGIN TRANSACTION;
INSERT INTO MainTable (Numbr, Name, LastActive, Country)
SELECT t.Numbr, t.Name, t.LastActive, t.Country
FROM TempTable t
WHERE NOT EXISTS (SELECT 1 FROM MainTable m WHERE m.Numbr = t.Numbr);

UPDATE m
    SET Name = t.Name
FROM MainTable m
INNER JOIN TempTable t
    ON m.Numbr = t.Numbr
WHERE m.Name <> t.Name;

UPDATE m
    SET LastActive = t.LastActive
FROM MainTable m
INNER JOIN TempTable t
    ON m.Numbr = t.Numbr
WHERE m.LastActive <> t.LastActive;

UPDATE m
    SET Country = t.Country
FROM MainTable m
INNER JOIN TempTable t
    ON m.Numbr = t.Numbr
WHERE m.Country <> t.Country;
COMMIT;
--Insert New
INSERT INTO MAINTABLE
SELECT A.*
FROM 
TempTable as A 
LEFT JOIN MainTable as B
ON B.Number = A.Number
WHERE B.Number IS NULL

--Update Old
UPDATE A
SET A.Number = B.Number,
    A.Name = B.Name,
    A.LastActive = B.LastActive,
    A.Country = B.Country
FROM 
TempTable as A 
LEFT JOIN MainTable as B
ON B.Number = A.Number
WHERE B.Number IS NOT NULL

暂无
暂无

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

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