Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

SQL MERGE израз за актуализиране на данни

Ако приемем, че искате действителен SQL Server MERGE изявление:

MERGE INTO dbo.energydata WITH (HOLDLOCK) AS target
USING dbo.temp_energydata AS source
    ON target.webmeterID = source.webmeterID
    AND target.DateTime = source.DateTime
WHEN MATCHED THEN 
    UPDATE SET target.kWh = source.kWh
WHEN NOT MATCHED BY TARGET THEN
    INSERT (webmeterID, DateTime, kWh)
    VALUES (source.webmeterID, source.DateTime, source.kWh);

Ако искате също така да изтриете записи в целта, които не са в източника:

MERGE INTO dbo.energydata WITH (HOLDLOCK) AS target
USING dbo.temp_energydata AS source
    ON target.webmeterID = source.webmeterID
    AND target.DateTime = source.DateTime
WHEN MATCHED THEN 
    UPDATE SET target.kWh = source.kWh
WHEN NOT MATCHED BY TARGET THEN
    INSERT (webmeterID, DateTime, kWh)
    VALUES (source.webmeterID, source.DateTime, source.kWh)
WHEN NOT MATCHED BY SOURCE THEN
    DELETE;

Тъй като това стана малко по-популярно, смятам, че трябва да разширя малко този отговор с някои предупреждения, които трябва да знаете.

Първо, има няколко блога, които съобщават за проблеми с паралелността с MERGE изявление в по-стари версии на SQL Server. Не знам дали този въпрос някога е бил разглеждан в по-късни издания. Така или иначе, това до голяма степен може да се заобиколи чрез указване на HOLDLOCK или SERIALIZABLE съвет за заключване:

MERGE INTO dbo.energydata WITH (HOLDLOCK) AS target
[...]

Можете също така да постигнете същото с по-рестриктивни нива на изолация на транзакциите.

Има няколко други известни проблема с MERGE . (Имайте предвид, че тъй като Microsoft изстреля Connect и не свърза проблемите в старата система с проблемите в новата система, тези по-стари проблеми са трудни за проследяване. Благодаря, Microsoft!) От това, което мога да кажа, повечето от тях не са често срещани проблеми или могат да бъдат заобиколени със същите съвети за заключване като по-горе, но не съм ги тествал.

Както е, въпреки че никога не съм имал проблеми с MERGE самият оператор винаги използвам WITH (HOLDLOCK) намек сега и предпочитам да използвам израза само в най-простите случаи.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. T-SQL:Как да създам уникален ключ, който е чувствителен към главни и малки букви?

  2. T-SQL:CTE с колони за идентичност

  3. Използване на StringWriter за XML сериализация

  4. Как могат да бъдат временно деактивирани ограниченията на външния ключ с помощта на T-SQL?

  5. Как мога да получа определена част от резултатите?