Вы должны создать временную таблицу для хранения результатов сохраненного процесса, а затем объединить результаты в вашу таблицу.Временная таблица рекомендуется для переменной таблицы, так как она будет лучше присоединяться к существующей таблице благодаря лучшей статистике.
CREATE TABLE #TempResults
(
Field1 DATATYPE1,
Field2 DATATYPE2,
...,
PRIMARY KEY CLUSTERED (KeyField1,...)
)
INSERT INTO #TempResults (Field1, Field2, ...)
EXEC Schema.ProcName @Param1, ...
Теперь есть два способа слияния.Первый работает во всех версиях SQL Server, а второй использует команду, которая была введена в SQL Server 2008.
-- this should work on all SQL SERVER versions
UPDATE rt
SET rt.Field2 = tmp.Field2,
...
FROM Schema.RealTable rt
INNER JOIN #TempResults tmp
ON tmp.KeyField1 = rt.KeyField1
...
INSERT INTO Schema.RealTable (Field1, Field2, ...)
SELECT tmp.Field1, tmp.Field2, ...
FROM #TempResults tmp
LEFT JOIN Schema.RealTable rt
ON rt.KeyField1 = tmp.KeyField1
...
WHERE rt.KeyField1 IS NULL
ИЛИ:
-- the MERGE command was introduced in SQL SERVER 2008
MERGE Schema.RealTable AS target
USING (SELECT Field1, Field2,... FROM #TempResults) AS source (Field1, Field2,..)
ON (target.KeyField1 = source.KeyField1)
WHEN MATCHED THEN
UPDATE SET Field2 = source.Field2,
...
WHEN NOT MATCHED THEN
INSERT (Field1, Field2,...)
SELECT tmp.Field1, tmp.Field2, ...
FROM #TempResults tmp
Для получения дополнительной информации о команде MERGE, перейдите сюда:
http://msdn.microsoft.com/en-us/library/bb510625(v=SQL.100).aspx
Теперь, если у вас большой набор результатов для слияния, а таблица, в которую вы объединяетесь, очень большая и в ней много операций, где используется этот тип операцийможет вызвать некоторую блокировку, тогда она может быть зациклена для выполнения наборов по 1000 строк за раз или что-то в этом роде.Что-то вроде этого:
<insert CREATE TABLE / INSERT...EXEC block>
CREATE TABLE #CurrentBatch
(
Field1 DATATYPE1,
Field2 DATATYPE2,
...
)
DECLARE @BatchSize SMALLINT = ????
WHILE (1 = 1)
BEGIN
-- grab a set to work on
DELETE TOP (@BatchSize)
OUTPUT deleted.Field1, deleted.Field2, ...
INTO #CurrentBatch (Field1, Field2, ...)
FROM #TempResults
IF (@@ROWCOUNT = 0)
BEGIN
-- no more rows
BREAK
END
<insert either UPDATE / INSERT...SELECT block or MERGE block from above
AND change references to #TempResults to be #CurrentBatch>
TRUNCATE TABLE #CurrentBatch
END