Можете ли вы использовать таблицу #Temp в Dynami c SQL в режиме OPENROWSET? - PullRequest
0 голосов
/ 05 февраля 2020

Я пытаюсь использовать таблицы #Temp в моем динамическом c SQL в Microsoft SQL Server 2014, и он работает нормально локально, но если я помещу его в OPENROWSET, чтобы я мог собирать данные с другого сервера , появляется сообщение об ошибке:

Поставщик OLE DB "SQLNCLI11" для связанного сервера "(null)" вернул сообщение «Отложенная подготовка не может быть завершена.». Сообщение 8180, уровень 16, состояние 1, строка 9 Заявление (я) не может быть подготовлено. Сообщение 208, Уровень 16, Состояние 1, Строка 9 Неверное имя объекта '# RefmdCodeList'

Это просто запрещено? Или есть какой-то другой способ, которым мне нужно это сделать?

Чтобы упростить проблему, вот два примера.
ЭТО РАБОТАЕТ:

declare @sql nvarchar(max) 
set @sql =  N' select * from #RefmdCodeList'
exec(@sql)

ЭТО НЕ РАБОТАЕТ:

declare @sql nvarchar(max) 
set @sql = N'   SELECT * FROM
                    OPENROWSET(''SQLNCLI'', 
                    ''Server=' + @PAFServer + ';Database=' +@PAFDatabase +';UID=p2kservices;PWD=P0werP@th!'',
                      N'' SELECT * from #RefmdCodeList'')'
exec(@sql)

Для людей, которые могут спросить, вот что Я действительно пытаюсь сделать. Если я удаляю таблицы #Temp, мой код, как написано ниже, работает нормально. С включенными таблицами #Temp я получаю сообщение об ошибке выше.

declare @sql nvarchar(max) 
set @sql = N'   SELECT * FROM OPENROWSET(''SQLNCLI'', ''Server=' + @PAFServer + ';Database=' +@PAFDatabase +';UID=p2kservices;PWD=P0werP@th!'',
N'' ;WITH spec_data (entity, accession_no, acc_id, spec_id, spec_description, spec_label, spec_sc_code) AS
(SELECT ''''PAMF'''' AS entity, a.accession_no, a.id, asp.id, asp.description, asp.specimen_label, substring(''''88''''+spec_sc.code, 1,5)
FROM accession_2 a (NOLOCK)
JOIN acc_specimen asp (nolock) ON asp.acc_id = a.id
LEFT OUTER JOIN acc_charges spec_ac (NOLOCK) on spec_ac.acc_id = asp.acc_id 
        AND spec_ac.rec_id = asp.id AND spec_ac.rec_type = ''''S''''
LEFT OUTER JOIN service_code spec_sc (NOLOCK) on spec_sc.id = spec_ac.service_code_id
JOIN acc_refmd aref (NOLOCK) ON aref.acc_id = a.id
WHERE recv_date >= ''''+CONVERT(VARCHAR(10),@SDate, 101) +'''' and recv_date < ''''+CONVERT(VARCHAR(10),@EDate, 101)+''''
AND aref.refmd_id in (SELECT id from #RefmdCodeList)
) 
SELECT DISTINCT entity accession_no, asp.acc_id, spec_id, spec_description, spec_label, 
    spec_sc_code, substring(''''88''''+lab_sc.code, 1,5)
FROM spec_data asp
LEFT OUTER JOIN acc_charges lab_ac (NOLOCK) on lab_ac.acc_id = asp.acc_id and rec_type = ''''L''''
JOIN service_code lab_sc (NOLOCK) on lab_sc.id = lab_ac.service_code_id
JOIN acc_order ord (NOLOCK) on ord.id = lab_ac.rec_id 
        AND ord.acc_specimen_id = asp.spec_id
WHERE substring(''''88''''+spec_sc.code, 1,5) in (SELECT service_code from #ServiceCodeList) 
OR substring(''''88''''+lab_sc.code, 1,5) in (SELECT service_code from #ServiceCodeList)
'') '

1 Ответ

0 голосов
/ 06 февраля 2020

Это просто недопустимо?

Таблица #temp видна только для текущего запущенного сеанса. Даже openrowset () на локальный сервер не увидит таблицу #temp, потому что openrowset выполняется на другом соединении (и другом сеансе).

Или есть другой способ, которым мне нужно это сделать?

Вы можете заполнить промежуточную таблицу на удаленном сервере и использовать эту промежуточную таблицу, делая вид / как если бы она была #table. Промежуточные таблицы Generi c (со столбцом int и столбцом varchar) для передачи значений работают довольно хорошо. Чтобы различать параллельные процессы, промежуточная таблица может иметь столбец sessionid (который содержит @@ spid на локальной стороне).

Для вдохновения ....

--local temp table
create table #localtemp
(
    srvcode varchar(100)
);
insert into #localtemp(srvcode)
select @@servername + '-' + name
from sys.objects;

--populate a proxy table on the remote server
declare @foo int;
select @foo = objectid
from openrowset('SQLNCLI', 'Server=Universe;Trusted_Connection=yes', 
'set fmtonly off;

if object_id(''tempdb.dbo.proxyservicetable'') is null
begin
    create table tempdb.dbo.proxyservicetable
    (
        sessionid smallint,
        servicecode varchar(100)
    );

    create clustered index uclxproxyservicetable on tempdb.dbo.proxyservicetable(sessionid);
end

select object_id(''tempdb.dbo.proxyservicetable'') as objectid;
');

select @foo as stagingtableobjectid --on the remoteservers

--cleanup any staging leftovers from previous executions
delete from
openrowset('SQLNCLI', 'Server=Universe;Trusted_Connection=yes', 
'
select *
from tempdb.dbo.proxyservicetable;
')
where sessionid = @@spid;

--populate staging with values from the current execution (#localtemp as source)
insert into
openrowset('SQLNCLI', 'Server=Universe;Trusted_Connection=yes', 
'
select *
from tempdb.dbo.proxyservicetable;
')
select @@spid, srvcode
from #localtemp;

--passthrough query, at the remote server
declare @sql nvarchar(max)
select @sql = 'select *
from openrowset(''SQLNCLI'', ''Server=Universe;Trusted_Connection=yes'', 
'' select @@servername,* from tempdb.dbo.proxyservicetable where sessionid =' + cast(@@spid as varchar(10)) + '''
)';
exec(@sql);
go

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