使用OPENQUERY(执行存储过程)来创建新的临时表失败,错误11526(Using OPENQU

2019-07-18 04:04发布

我有我的开发PC上安装SQL Server 2012的完整版本。

我想下面的例子在这里 ,展示了如何使用存储过程作为数据源创建一个新的临时表。 我想的几个存储过程的结果组合成一个单一的临时表(列结构/各种结果集的定义相同)。

要测试管道是否正常工作,我发出这个查询:

 SELECT * FROM OPENQUERY("FOO\SQL2012", 'exec mySchema.myStoredProc')

但我发现了从简单的测试,在水暖选择查询此错误:

消息11526,级别16,状态1,过程sp_describe_first_result_set,1号线
元数据不能确定,因为声明“插入#tmp(foo1,foo2的,foo3)选择‘O’为foo1,foo2的,foo3”在过程“myStoredProc”使用临时表。

如果我没有理解错误,OPENQUERY取决于服务器能够从数据库中永久定义,在我的存储过程的实例,是短暂的临时表中提取的列数据类型,缺乏持续性的定义。 如果是这样的话, 有没有告诉OPENQUERY做它最好的,并尝试做出明智的猜测列的数据类型的任何设置?

这里的虚拟SP我与测试:

create proc testproc
as
begin

create table #test
(id int, name varchar(5) );

insert into #test(id,name)values(1,'xxx');
select * from #test;
--drop table #test;   -- tried dropping and not dropping, same error either way
end

Answer 1:

试试这个:

SELECT *
FROM OPENQUERY("FOO\SQL2012", 'SET FMTONLY OFF; EXEC mySchema.myStoredProc;') X;

这样做的原因是,当您在一个链接服务器执行存储过程,供应商首先尝试确定最终的行集的形状。 它通过发出SET FMTONLY ON; 然后运行你的发言。 在不使用临时表的存储过程,这个精美的作品。 查询解析器基本上没有干运行,而无需实际获取的所有数据,只是元数据(有点像示出了估计的执行计划)。

问题是,当存储过程中没有使用临时表,它失败,因为该临时表的元数据不存在:它无法通过荟萃分析,对于不使用临时表的存储过程的作品被收集。 固化,然后,是手动SET FMTONLY OFF; 该批次内正在执行的存储过程。

请注意,使用这种方法将使运行两次存储过程。 在第一时间,以收集所述元数据(数据被丢弃),并且所述第二时间来实际返回数据。 如果调用的存储过程是特别昂贵或有副作用,你可能需要作出补贴。

最后,请注意,这招不上的每个存储过程的工作。 有些事情存储过程可以做到,只是抛出一个扳手的作品。 我不知道所有的可能性,但他们中的一个将返回多个记录。

在回答您的更新是SET FMTONLY OFF不起作用:你能有可能重组的SP不使用临时表,或使用一个会话键控永久表? 这些选项可以做的工作。 在SQL Server 2012中,您还必须围绕数据与传递的选项表值参数 。

你可能会喜欢读厄兰Sommarskog的如何存储过程之间共享数据 ,因为它可能会为你提供灵感的方式来实现自己的目的。



Answer 2:

添加“ WITH RESULT SETS [NONE | UNDEFINED] ”以EXEC通话结束应该纠正这个问题。 http://technet.microsoft.com/en-us/library/ms188332.aspx



Answer 3:

如果来宾服务器SP没有在开始时的结果集(选择查询),链接服务器无法解析结果集。 我使用的选项如下:

create procedure test
as

    if 1=2
    select a, b, c from table

    declare @variable varchar(10)
    ----...and rest of your procedure...

    --in the end
    select a, b, c from table


文章来源: Using OPENQUERY (exec stored procedure) to create new temporary table fails with error 11526