Как правило, я стараюсь писать процедуры Upsert ......., но я основывал «match» на unique_constraint, а не на суррогатном ключе.
Например.
dbo.Employee EmployeeUUID - это ПК, суррогатный ключ SSN - это уникальное ограничение.
dbo.uspEmployeeUpsert would look something like this:
Insert into dbo.Employee (EmployeeUUID , LastName , FirstName, SSN)
Select NEWID() , LastName , FirstName , SSN
from @SomeHolderTable holder
where not exists (select null from dbo.Employee innerRealTable where
innerRealTable.SSN = holder.SSN)
Update dbo.Employee
Set EmployeeUUID = holder.EmployeeUUID
, LastName = ISNULL (holder.LastName , e.LastName) /* or COALESCE */
, FirstName = COALESCE (holder.FirstName , e.FirstName)
from dbo.Employee e , @SomeHolderTable holder
Where e.SSN = holder.SSN
Вы также можете использовать функцию MERGE.
Вы также можете заменить номер социальное страхование с суррогатным ключом (EmployeeUUID в данном случае)
Что @SomeHolderTable вы спрашиваете?
Мне нравится передавать xml в хранимую процедуру, разбивать ее на таблицу @Variable или #Temp, а затем записывать логику для CU. D (elete) также возможен, но я обычно выделяю отдельную процедуру.
Почему я так делаю?
Потому что я могу обновить 1 или 100 или 1000 или N записей одним ударом db. Моя логика редко меняется и изолирована от одного места.
Теперь есть небольшой удар производительности для измельчения Xml. Но я считаю это приемлемым в 99% случаев. Время от времени я пишу не «установленную на основе» процедуру Upsert. Но это для тяжелых процедур нападающих для интенсивного использования удара.
Это мой прием.
Вы можете увидеть «набор на основе» часть этого подхода (со старым синтаксисом OPENXML) в этой статье:
http://msdn.microsoft.com/en-us/library/ff647768.aspx
Найти фразу: «Выполнить сыпучие обновления и вставку с помощью OpenXML "
Вот "больше кода" версия о том, что указанные выше URL говорит о:
http://support.microsoft.com/kb/315968
EDIT
if exists (select 1 from dbo.Employee e where e.SSN = holder.SSN)
BEGIN
Insert into dbo.Employee (EmployeeUUID , LastName , FirstName, SSN)
Select NEWID() , LastName , FirstName , SSN
from @SomeHolderTable holder
where not exists (select null from dbo.Employee innerRealTable where
innerRealTable.SSN = holder.SSN)
END
Я не обязательно делать это. Но это вариант, если вы хотите «логическую проверку».
Итак, с моей установкой uniqueidentifier, я передам «Пустой указатель» (00000000-0000-0000-0000-000000000000) (Guid.Empty в C#) в процедуру, когда я знаю, что у меня есть новый элемент , Это будет моя проверка «-1» в вашем сценарии.
Это один из методов, который вы могли бы проверить на наличие «если существует».
Это зависит от того, сколько у вас рук в горшке.
Кроме того, я не упоминал, что когда у меня много рук в банке, я испортю xml ..... тогда я сделаю BEGIN TRAN и COMMIT TRAN вокруг своих инструкций CU (с ROLLBACK там тоже). Таким образом, мой CU является атомарным, все или ничего.
Функция MERGE также сделает это. Но плюсы и минусы MERGE - это другая тема.
Это интересный способ обойти это +1. Моя единственная проблема здесь (хотя я знаю, что процесс займет всего несколько наносекунд дольше) заключается в том, что ** оба процесса выполняются, когда действительно требуется только один. И да, я понимаю, что первая часть выполняется только в том случае, если запись еще не существует в таблице [и наоборот], но для меня мне очень нравится аккуратность булевского теста. Это то, что я еще глубже рассмотрю. Спасибо. – Paul
Как только вы идете на основе набора, трудно вернуться назад. Я использую некоторые инструменты ORM, но они очень чаты. Вот «недокументированное» преимущество набора основанных. Индексы обновляются после действия на основе набора и не обновляются после каждого INSERT в методе вставки RBAR (строка по агонистической строке). Таким образом, если вы обновите 100 строк с помощью установленного подхода выше, индексы обновляются дважды, а не обновляются 100 раз в методе RBAR. – granadaCoder
Хорошо объяснил. К счастью, мне не нужно слишком беспокоиться о массовых загрузках - это не что иное, как простой загружаемый адрес или, возможно, некоторые личные данные; отдельные ряды * *! –
Paul