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


当前回答

如果您这样做是为了手动验证数据,您可以使用LINQPad。

在LinqPad中创建一个到数据库的连接,然后创建类似于下面的c#语句:

DataTable table = MyStoredProc (param1, param2).Tables[0];
(from row in table.AsEnumerable()
 select new
 {
  Col1 = row.Field<string>("col1"),
  Col2 = row.Field<string>("col2"),
 }).Dump();

参考http://www.global-webnet.net/blogengine/post/2008/09/10/LINQPAD-Using-Stored-Procedures-Accessing-a-DataSet.aspx

其他回答

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

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

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

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/

如果你只需要这样做一次,最简单的方法是:

在导入和导出向导中导出到excel,然后将此excel导入到表中。

我会剪切粘贴原始SP并删除所有列,除了你想要的两列。或。我将返回结果集,将其映射到适当的业务对象,然后LINQ出这两列。

创建一个动态视图,并从中获得结果.......

CREATE PROCEDURE dbo.usp_userwise_columns_value
(
    @userid BIGINT
)
AS 
BEGIN
        DECLARE @maincmd NVARCHAR(max);
        DECLARE @columnlist NVARCHAR(max);
        DECLARE @columnname VARCHAR(150);
        DECLARE @nickname VARCHAR(50);

        SET @maincmd = '';
        SET @columnname = '';
        SET @columnlist = '';
        SET @nickname = '';

        DECLARE CUR_COLUMNLIST CURSOR FAST_FORWARD
        FOR
            SELECT columnname , nickname
            FROM dbo.v_userwise_columns 
            WHERE userid = @userid

        OPEN CUR_COLUMNLIST
        IF @@ERROR <> 0
            BEGIN
                ROLLBACK
                RETURN
            END   

        FETCH NEXT FROM CUR_COLUMNLIST
        INTO @columnname, @nickname

        WHILE @@FETCH_STATUS = 0
            BEGIN
                SET @columnlist = @columnlist + @columnname + ','

                FETCH NEXT FROM CUR_COLUMNLIST
                INTO @columnname, @nickname
            END
        CLOSE CUR_COLUMNLIST
        DEALLOCATE CUR_COLUMNLIST  

        IF NOT EXISTS (SELECT * FROM sys.views WHERE name = 'v_userwise_columns_value')
            BEGIN
                SET @maincmd = 'CREATE VIEW dbo.v_userwise_columns_value AS SELECT sjoid, CONVERT(BIGINT, ' + CONVERT(VARCHAR(10), @userid) + ') as userid , ' 
                            + CHAR(39) + @nickname + CHAR(39) + ' as nickname, ' 
                            + @columnlist + ' compcode FROM dbo.SJOTran '
            END
        ELSE
            BEGIN
                SET @maincmd = 'ALTER VIEW dbo.v_userwise_columns_value AS SELECT sjoid, CONVERT(BIGINT, ' + CONVERT(VARCHAR(10), @userid) + ') as userid , ' 
                            + CHAR(39) + @nickname + CHAR(39) + ' as nickname, ' 
                            + @columnlist + ' compcode FROM dbo.SJOTran '
            END

        --PRINT @maincmd
        EXECUTE sp_executesql @maincmd
END

-----------------------------------------------
SELECT * FROM dbo.v_userwise_columns_value