我有一个存储过程,它返回80列和300行。我要写一个select函数,它能得到2个这样的列。类似的

SELECT col1, col2 FROM EXEC MyStoredProc 'param1', 'param2'

当我使用上面的语法时,我得到了错误:

“无效的列名”。

我知道最简单的解决方案是更改存储过程,但我没有编写它,也不能更改它。

有什么办法能让我如愿以偿吗?

I could make a temp table to put the results in, but because there are 80 columns so I would need to make an 80 column temp table just to get 2 columns. I wanted to avoid tracking down all the columns that are returned. I tried using WITH SprocResults AS .... as suggested by Mark, but I got 2 errors Incorrect syntax near the keyword 'EXEC'.Incorrect syntax near ')'. I tried declaring a table variable and I got the following error Insert Error: Column name or number of supplied values does not match table definition If I try SELECT * FROM EXEC MyStoredProc 'param1', 'param2' I get the error : Incorrect syntax near the keyword 'exec'.


当前回答

这里有一个链接,指向一个非常好的文档,它解释了解决您的问题的所有不同方法(尽管其中许多方法不能使用,因为您不能修改现有的存储过程)。

如何在存储过程之间共享数据

Gulzar的答案是可行的(在上面的链接中有文档),但是编写起来会很麻烦(您需要在@tablevar(col1,…)语句中指定所有80个列名。在将来,如果一个列被添加到模式中,或者输出被改变,它将需要在您的代码中更新,否则它将出错。

其他回答

如果你能够修改你的存储过程,你可以很容易地把所需的列定义作为一个参数,并使用一个自动创建的临时表:

CREATE PROCEDURE sp_GetDiffDataExample
      @columnsStatement NVARCHAR(MAX) -- required columns statement (e.g. "field1, field2")
AS
BEGIN
    DECLARE @query NVARCHAR(MAX)
    SET @query = N'SELECT ' + @columnsStatement + N' INTO ##TempTable FROM dbo.TestTable'
    EXEC sp_executeSql @query
    SELECT * FROM ##TempTable
    DROP TABLE ##TempTable
END

在这种情况下,您不需要手动创建临时表—它是自动创建的。希望这能有所帮助。

一个快速的方法是添加一个新参数“@Column_Name”,并让调用函数定义要检索的列名。在你的sproc的返回部分,你会有if/else语句并只返回指定的列,或者如果为空-返回所有。

CREATE PROCEDURE [dbo].[MySproc]
        @Column_Name AS VARCHAR(50)
AS
BEGIN
    IF (@Column_Name = 'ColumnName1')
        BEGIN
            SELECT @ColumnItem1 as 'ColumnName1'
        END
    ELSE
        BEGIN
            SELECT @ColumnItem1 as 'ColumnName1', @ColumnItem2 as 'ColumnName2', @ColumnItem3 as 'ColumnName3'
        END
END

知道这为什么如此困难也许会有所帮助。 存储过程可以只返回文本(print 'text'),也可以返回多个表,或者根本不返回表。

所以像SELECT * FROM (exec sp_tables) Table1这样的东西将不起作用

您可以拆分查询吗?将存储的过程结果插入到表变量或临时表中。然后,从表变量中选择2列。

Declare @tablevar table(col1 col1Type,..
insert into @tablevar(col1,..) exec MyStoredProc 'param1', 'param2'

SELECT col1, col2 FROM @tablevar

正如问题中提到的,在执行存储过程之前很难定义80列的临时表。

另一种方法是根据存储过程结果集填充表。

SELECT * INTO #temp FROM OPENROWSET('SQLNCLI', 'Server=localhost;Trusted_Connection=yes;'
                                   ,'EXEC MyStoredProc')

如果您得到任何错误,您需要通过执行以下查询来启用特定的分布式查询。

sp_configure 'Show Advanced Options', 1
GO
RECONFIGURE
GO
sp_configure 'Ad Hoc Distributed Queries', 1
GO
RECONFIGURE
GO

要使用两个参数执行sp_configure以更改配置选项或运行RECONFIGURE语句,必须授予ALTER SETTINGS服务器级权限

现在可以从生成的表中选择特定的列

SELECT col1, col2
FROM #temp