Я намагаюся оновити таблицю з масивом значень. Кожен елемент масиву містить інформацію, яка відповідає рядку в таблиці в базі даних SQL Server. Якщо рядок уже існує в таблиці, ми оновлюємо цей рядок інформацією в даному масиві. В іншому випадку ми вставляємо новий ряд у таблицю. Я в основному описав прихильність.
Тепер я намагаюся досягти цього в збереженій процедурі, яка приймає параметр XML. Причина, що я використовую параметр XML, а не табличний параметр, полягає в тому, що, виконуючи останнє, мені доведеться створити власний тип у SQL і пов’язати цей тип із збереженою процедурою. Якщо я колись щось міняв у своїй збереженій процедурі або моїй схемі db по дорозі, мені доведеться повторити як збережену процедуру, так і спеціальний тип. Я хочу уникнути цієї ситуації. Крім того, перевага, яку має TVP над XML, не корисна для моєї ситуації, тому що розмір мого масиву даних ніколи не перевищить 1000. Це означає, що я не можу використовувати запропоноване тут рішення: Як вставити кілька записів за допомогою XML на SQL-сервер 2008
Також подібна дискусія тут ( UPSERT - Чи є краща альтернатива MERGE або @@ rowcount? ) Відрізняється від того, що я прошу, тому що я намагаюся вставити кілька рядків до таблиці.
Я сподівався, що я просто використаю наступний набір запитів для відновлення значень з xml. Але це не спрацює. Цей підхід повинен працювати лише тоді, коли вхід є одним рядком.
begin tran
update table with (serializable) set select * from xml_param
where key = @key
if @@rowcount = 0
begin
insert table (key, ...) values (@key,..)
end
commit tran
Наступною альтернативою є використання вичерпного IF EXISTS або одного з його варіантів наступної форми. Але я відкидаю це на підставі недостатньої ефективності:
IF (SELECT COUNT ... ) > 0
UPDATE
ELSE
INSERT
Наступним варіантом було використання оператора Merge, як описано тут: http://www.databasejournal.com/features/mssql/using-the-merge-statement-to-perform-an-upsert.html . Але потім я читав про проблеми із запитом на об’єднання тут: http://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/ . З цієї причини я намагаюся уникати Злиття.
Отже, тепер у мене питання: чи є якийсь інший варіант або кращий спосіб досягти декількох результатів за допомогою параметра XML у збереженій процедурі SQL Server 2008?
Зверніть увагу, що дані в параметрі XML можуть містити деякі записи, які не повинні бути UPSERTed через те, що вони старші за поточний запис. ModifiedDateІ в XML, і в цільовій таблиці є поле, яке необхідно порівняти, щоб визначити, чи слід оновити або відкинути запис.
MERGEякі вказує Бертран, - це переважно кращі випадки та неефективність, а не пробки - MS не випустили б його, якби це було справжнє мінне поле. Ви впевнені, що згортки, через які ви переживаєте MERGE, не створюють більше потенційних помилок, ніж заощаджують?
MERGE. Етапи INSERT та UPDATE MERGE все ще обробляються окремо. Основна відмінність мого підходу - це змінна таблиця, яка містить оновлені ідентифікатори запису, і запит DELETE, який використовує цю змінну таблиці для видалення цих записів із таблиці темпів вхідних даних. І я гадаю, ДЖЕРЕЛО може бути безпосередньо з @ XMLparam.nodes () замість того, щоб скидати до темп-таблиці, але все-таки, це не багато зайвих матеріалів, щоб не потрібно було турбуватися про те, щоб коли-небудь опинитися в одному з цих крайових випадків; - ).