我有一个存储过程,它返回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'.


当前回答

我知道从sp执行和插入到临时表或表变量将是一个选项,但我不认为这是你的要求。根据您的要求,以下查询语句应该工作:

Declare @sql nvarchar(max)
Set @sql='SELECT   col1, col2 FROM OPENROWSET(''SQLNCLI'', ''Server=(local);uid=test;pwd=test'',
     ''EXEC MyStoredProc ''''param1'''', ''''param2'''''')'
 Exec(@sql)

如果你有可信连接,那么使用下面的查询语句:

Declare @sql nvarchar(max)
Set @sql='SELECT   col1, col2 FROM OPENROWSET(''SQLNCLI'', ''Server=(local);Trusted_Connection=yes;'',
     ''EXEC MyStoredProc ''''param1'''', ''''param2'''''')'
 Exec(@sql)

如果运行上面的语句出错,那么只需运行下面的语句:

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

我希望这将帮助那些将面临类似问题的人。如果有人想尝试temp表或表变量,应该如下所示,但在这种情况下,你应该知道sp返回多少列,然后你应该在temp表或表变量中创建这么多列:

--for table variable 
Declare @t table(col1 col1Type, col2 col2Type)
insert into @t exec MyStoredProc 'param1', 'param2'
SELECT col1, col2 FROM @t

--for temp table
create table #t(col1 col1Type, col2 col2Type)
insert into #t exec MyStoredProc 'param1', 'param2'
SELECT col1, col2 FROM #t

其他回答

对于SQL Server,我发现这工作得很好:

创建一个临时表(或永久表,并不重要),并对存储过程执行insert into语句。SP的结果集应该与表中的列匹配,否则将得到一个错误。

这里有一个例子:

DECLARE @temp TABLE (firstname NVARCHAR(30), lastname nvarchar(50));

INSERT INTO @temp EXEC dbo.GetPersonName @param1,@param2;
-- assumption is that dbo.GetPersonName returns a table with firstname / lastname columns

SELECT * FROM @temp;

就是这样!

一个快速的方法是添加一个新参数“@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这样的东西将不起作用

要实现这一点,首先你创建一个#test_table,如下所示:

create table #test_table(
    col1 int,
    col2 int,
   .
   .
   .
    col80 int
)

现在执行过程并将值放在#test_table中:

insert into #test_table
EXEC MyStoredProc 'param1', 'param2'

现在你从#test_table中获取值:

select col1,col2....,col80 from #test_table
CREATE TABLE #Result
(
  ID int,  Name varchar(500), Revenue money
)
INSERT #Result EXEC RevenueByAdvertiser '1/1/10', '2/1/10'
SELECT * FROM #Result ORDER BY Name
DROP TABLE #Result

来源: http://stevesmithblog.com/blog/select-from-a-stored-procedure/