[英]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.