Я намагаюся оновити таблицю з масивом значень. Кожен елемент масиву містить інформацію, яка відповідає рядку в таблиці в базі даних 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 () замість того, щоб скидати до темп-таблиці, але все-таки, це не багато зайвих матеріалів, щоб не потрібно було турбуватися про те, щоб коли-небудь опинитися в одному з цих крайових випадків; - ).