Я предполагаю, что причина такого поведения в том, что когда вы вызываете OPENROWSET с другого сервера, он сначала и отдельно запрашивает информацию о структуре вывода процедуры (METADATA). И самое интересное, что эта структура вывода взята из первого оператора SELECT, найденного в процедуре. Более того, если инструкция SELECT следует условию IF, запрос METADATA игнорирует это условие IF, поскольку нет необходимости запускать всю процедуру - достаточно первого выполненного оператора SELECT. (Кстати, чтобы отключить это поведение, вы можете включить SET FMTONLY OFF в начале вашей процедуры, но это может увеличить время выполнения процедуры).
Выводы:
- когда METADATA запрашивается из временной таблицы (созданной в процедуре), она фактически не существует, поскольку запрос METADATA фактически не запускает процедуру и не создает временную таблицу.
- если временная таблица может быть заменена табличной переменной, это решает проблему
- если для бизнеса жизненно важно использовать временную таблицу, запрос METADATA можно передать с помощью поддельной first инструкции SELECT, например:
declare @t table(ID int, Name varchar(15));
if (0 = 1) select ID, Name from @t; -- fake SELECT statement
create table #T (ID int, Name varchar(15));
select ID, Name from #T; -- real SELECT statement
- и еще одна вещь - использовать общий прием с FMTONLY (это не моя идея):
declare @fmtonlyOn bit = 0;
if 1 = 0 set @fmtonlyOn = 1;
set fmtonly off;
create table #T (ID int, Name varchar(15));
if @fmtonlyOn = 1 set fmtonly on;
select ID, Name from #T;