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