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