Вложенный exec обходной путь - PullRequest
3 голосов
/ 24 марта 2010

У меня есть 2 хранимые процедуры usp_SP1 и usp_SP2. Оба они используют вставку в #tt exec sp_somesp. Я хотел создать третью хранимую процедуру, которая решит, какую хранимую процедуру вызывать. Что-то вроде:

create proc usp_Decision
(
   @value int
)
as
begin
   if (@value = 1)
     exec usp_SP1  -- this proc already has insert into #tt exec usp_somestoredproc
   else
        exec usp_SP2  -- this proc too has insert into #tt exec usp_somestoredproc
end

Позже я понял, что мне нужна некоторая структура, определенная для возвращаемого значения из usp_Decision, чтобы я мог заполнить поле набора данных SSRS. Итак, вот что я попробовал:

  1. Внутри usp_Decision создал временную таблицу и попытался выполнить «вставку в #tt exec usp_SP1». Это не сработало. ошибка "вставка exec не может быть вложенной"

  2. Внутри usp_Decision попытался передать переменную таблицы каждому из сохраненных процедур, обновить таблицу в хранимых процессах и выполнить команду «выбрать * из». Это тоже не сработало. Переменная таблицы, передаваемая в качестве параметра, не может быть изменена в сохраненном процессе.

Пожалуйста, предложите, что можно сделать.

Ответы [ 4 ]

1 голос
/ 24 августа 2010

Можете ли вы изменить usp_SP1 и usp_SP2?

Если это так, в usp_Decision создайте локальную временную таблицу с правильной схемой для вставки результатов:

create table #results (....)

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

if object_id('tempdb..#results') is not null begin
  insert #results (....)
  select .....
end
else begin
  select ....
end

Когда управление возвращается к вызывающей процедуре, #results будет заполняться вложенным процессом, в зависимости от того, какой из них был вызван.

Если наборы результатов не используют одну и ту же схему, вам может потребоваться создать две временные таблицы в usp_Decision.

0 голосов
/ 25 марта 2010

Рассматривали ли вы пользовательские функции с табличными значениями (встроенные или с несколькими операторами)? По аналогии с предложением HLGEM, он вернет набор, который вам, возможно, не потребуется вставлять где-либо.

0 голосов
/ 31 марта 2010

См. Эту статью блога для одного wortkaround (использует OPENROWSET для создания по существу петлевого соединения, при котором происходит один из вызовов INSERT EXEC)

0 голосов
/ 25 марта 2010

Ни в коем случае не фанат глобальных временных таблиц (другие процессы могут читать эти таблицы и могут мешать данным в них).

Почему бы не каждому процессу использовать локальную временную таблицу и выбрать * из этой таблицы в качестве последнего шага. Затем вы можете вставить в локальную временную таблицу в вызывающей процедуре.

простой пример

create proc usp_mytest1
as
select top 1 id into #test1
from MYDATABASE..MYTABLE (nolock)

select * from #test1
go
--drop table #test
create proc usp_mytest2
as
select top 10 MYTABLE_id into #test2
from MYDATABASE..MYTABLE (nolock)

select * from #test2
go

create proc usp_mytest3 (@myvalue int)
as
create table #test3 (MYTABLE_id int)
if @myvalue = 1
Begin
insert #test3
exec ap2work..usp_mytest1
end
else
begin
insert #test3
exec ap2work..usp_mytest2
end

select * from #test3

go

exec ap2work..usp_mytest3 1

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