简体   繁体   English

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

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

I have two tables with same columns on Microsoft SQL Server 2014. 我在Microsoft SQL Server 2014上有两个表具有相同的列。

MainTable and TempTable. MainTable和TempTable。

I would like to enter the updated / fresh data from TempTable onto MainTable avoiding duplicates. 我想将TempTable中的更新数据/新数据输入到MainTable中,以避免重复。

The MainTable looks like the following: MainTable如下所示:

在此处输入图片说明

The TempTable looks like the following: TempTable如下所示:

在此处输入图片说明

The data in the TempTable will constantly change. TempTable中的数据将不断变化。 It may have updated data or new rows. 它可能具有更新的数据或新的行。

What I am trying to achieve is, insert / update the data from TempTable onto MainTable. 我试图实现的是,将数据从TempTable插入/更新到MainTable。

TempTable : - In this example, The row with Numbr 101 and 104 has the updated data. TempTable :-在此示例中, 编号为101和104的行具有更新的数据。 It also has new rows with Numbr 105 and 106 . 它还具有Numbr 105和106的新行。 I would like to update the data of 101 and 104 and also insert 105 and 106. 我想更新101和104的数据,并同时插入105和106。

Please advice as I am new to SQL. 请提出建议,因为我是SQL新手。


UPDATE1: UPDATE1:

After using the following query: 使用以下查询后:

--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

The Output of MainTable : MainTable的输出:

在此处输入图片说明

It worked, but when the data in TempTable is updated and new data is added: 它有效,但是当TempTable中的数据更新并添加新数据时:

在此处输入图片说明

The Result after running the query: 运行查询后的结果:

MainTable and TempTable respectively MainTable和TempTable分别

在此处输入图片说明

The new Row 108 got added (From TempTable --> MainTable ) but the updated Row 106 had no effect and the value in TempTable got copied from MainTable. 添加了新的第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

I'm assuming that Numbr is a key or unique field in both tables. 我假设Numbr是两个表中的键或唯一字段。 If that's not the case, then you should not use these queries. 如果不是这种情况,则不应使用这些查询。 Additionally, the field should be indexed in both tables if performance is a problem. 此外,如果性能存在问题,则应在两个表中为该字段建立索引。

This is the simplest way: 这是最简单的方法:

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;

Note that if Name, LastActive, or Country are nullable fields then the syntax gets much more verbose. 请注意,如果“名称”,“ LastActive”或“国家/地区”是可为空的字段,则语法变得更加冗长。 For example, if all three fields are nullable, then you should use this syntax: 例如,如果所有三个字段均可为空,则应使用以下语法:

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;

If you absolutely need to minimize the number of writes, then you should break up the UPDATE statement into one query for each field. 如果绝对需要最大程度地减少写入次数,则应将UPDATE语句分解为每个字段的一个查询。 This may run faster or may run slower, so just because you're writing less doesn't mean the queries will execute faster. 这可能会运行得更快或更慢,所以仅仅因为您编写的内容较少并不意味着查询将执行得更快。 Again, I've assumed there are no nullable fields in your system: 同样,我假设您的系统中没有可为空的字段:

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