Можно ли использовать $ action оператора MERGE в выходной переменной хранимой процедуры? - PullRequest
4 голосов
/ 20 января 2011

У меня есть хранимая процедура, которая либо обновляет существующую, либо вставляет отдельную запись (я использую MERGE TOP (1) ..), используя оператор MERGE в SQL Server 2008 R2.Я использую предложение MERGE OUTPUT для выдачи значения $ action, чтобы увидеть, какое действие было предпринято (INSERT, UPDATE, DELETE, 'blank').

Однако, когда я вызываю мой SP из программы на C #, я вынужден выполнить считыватель (DbCommand.ExecuteReader ()) и один раз пройти по нему, чтобы получить значение $ action ...

Мой вопрос заключается в том, можно ли каким-либо образом присоединить действие OUTPUT $ к выходному параметру SP, что позволит мне просто выполнить DbCmmand.ExecuteNonQuery () и проверить выходной параметр?Это избавит меня от необходимости создавать экземпляр читателя ...

Кстати, я делаю этот вызов в цикле, поэтому отсутствие необходимости создавать экземпляр считывателя будет немного быстрее (я надеюсь)

Ответы [ 3 ]

4 голосов
/ 20 января 2011

Пример таблицы для обсуждения

create table t1 (id int identity primary key, other int);
insert t1 select 2;

Этот TSQL делает окончательный выбор в конце, что в итоге приводит к ExecuteNonQuery

set nocount on
declare @tmp table (action sysname)
;
with new(id,other) as (select 1,4)
merge top(1)
into t1
using new
on t1.id = new.id
when matched then update set other = new.id
when not matched then insert values (other)
output $action
into @tmp
;
set nocount off
select action from @tmp

Это хорошо работает для TOP (1), так как он создает только одну строку в @tmp, но в приведенном ниже примере показано, что происходит при наличии нескольких записей, продолжая с вышеупомянутого

set nocount on
declare @tmp table (action sysname)
;
merge
into t1
using (values(1,4),(2,5)) new(id,other)
on t1.id = new.id
when matched then update set other = new.id
when not matched then insert values (other)
output $action
into @tmp
;
set nocount off
select action from @tmp

Выход:

action
======
UPDATE
INSERT
  • Влияет ли дополнительная переменная временной таблицы и инструкция SELECT для SP на производительность?

Это было бы незначительным, вы можете игнорировать его.

  • Должен ли я "обернуть" 2 в транзакции (мое приложение является многопоточным)?

Нет. Вставка в @tmp является атомарной, а выбор происходит из временной таблицы, специфичной для сессии (ничто не может помешать ей)

2 голосов
/ 20 января 2011

Вы можете шунтировать OUTPUT в табличную переменную, а затем назначить скалярный выходной параметр из этого.

Нельзя напрямую назначать строки OUTPUT скалярной переменной.

2 голосов
/ 20 января 2011

Вы можете вывести значение в переменную и сделать эту переменную выходной переменной.Это, конечно, будет работать только в том случае, если есть одно и только одно значение для этого переменной за раз, но, похоже, это ваш случай.

С другой стороны, вы можете вывести в таблицу varaible и затем выбрать записи в табличной переменной как часть вашего процесса.

Почему вы делаете это цикл?Возможно, будет гораздо быстрее обрабатывать все записи одновременно с табличной переменной в качестве входной переменной (если она у вас есть) для sp и использовать набор на основе вместо записи по записи (иначе известный как строка за агонизацией)ряд) обработка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...