SQL Server - SELECT FROM存储过程

时间:2009-09-29 13:05:58

标签: sql sql-server sql-server-2005 stored-procedures

我有一个返回行的存储过程:

CREATE PROCEDURE MyProc
AS
BEGIN
    SELECT * FROM MyTable
END

我的实际程序有点复杂,这就是为什么有必要使用。

是否可以通过调用此过程来选择输出?

类似的东西:

SELECT * FROM (EXEC MyProc) AS TEMP

我需要使用SELECT TOP XROW_NUMBER和其他WHERE子句来分页我的数据,我真的不想将这些值作为参数传递。

15 个答案:

答案 0 :(得分:158)

你可以

  1. 创建一个表变量来保存 结果集来自存储过程和 那么
  2. 插入输出     存储过程到表变量中,     然后
  3. 使用表变量         正如你所做的那样         表...
  4. ... sql ....

    Declare @T Table ([column definitions here])
    Insert @T Exec storedProcname params 
    Select * from @T Where ...
    

答案 1 :(得分:149)

你应该看看Erland Sommarskog的这篇优秀文章:

它基本上列出了您的方案的所有可用选项。

答案 2 :(得分:135)

您可以使用User-defined functionview代替程序。

一个过程可以返回多个结果集,每个结果集都有自己的模式。它不适合在SELECT声明中使用。

答案 3 :(得分:69)

您要么需要Table-Valued function,要么将EXEC插入临时表:

INSERT INTO #tab EXEC MyProc

答案 4 :(得分:40)

您必须阅读OPENROWSETOPENQUERY

SELECT  * 
INTO    #tmp FROM    
OPENQUERY(YOURSERVERNAME, 'EXEC MyProc @parameters')

答案 5 :(得分:32)

没有必要使用临时表。

这是我的解决方案

SELECT  *  FROM    
OPENQUERY(YOURSERVERNAME, 'EXEC MyProc @parameters')
WHERE somefield = anyvalue

答案 6 :(得分:30)

您需要声明一个表类型,其中包含的存储过程返回的列数相同。表类型中的列的数据类型和过程返回的列应该相同

declare @MyTableType as table
(
FIRSTCOLUMN int
,.....
)  

然后,您需要在刚刚定义的表类型中插入存储过程的结果

Insert into @MyTableType 
EXEC [dbo].[MyStoredProcedure]

最后只需从表格类型中选择

Select * from @MyTableType

答案 7 :(得分:23)

您可以将sp的输出复制到临时表。

CREATE TABLE #GetVersionValues
(
    [Index] int,
    [Name]  sysname,
    Internal_value  int,
    Character_Value sysname
)
INSERT #GetVersionValues EXEC master.dbo.xp_msver 'WindowsVersion'
SELECT * FROM #GetVersionValues
drop TABLE #GetVersionValues

答案 8 :(得分:6)

使用OPENQUERY并执行设置'SET FMTONLY OFF; SET NOCOUNT ON;'

试试这个示例代码:

SELECT top(1)*
FROM
OPENQUERY( [Server], 'SET FMTONLY OFF; SET NOCOUNT ON; EXECUTE  [database].[dbo].[storedprocedure]  value,value ')

答案 9 :(得分:5)

你可以用OPENROWSET作弊:

SELECT ...fieldlist...
FROM OPENROWSET('SQLNCLI', 'connection string', 'name of sp')
WHERE ...

当然,每次都会运行整个SP。

答案 10 :(得分:5)

尝试将您的过程转换为内联函数,该函数返回一个表,如下所示:

CREATE FUNCTION MyProc()
RETURNS TABLE AS
RETURN (SELECT * FROM MyTable)

然后你可以把它称为

SELECT * FROM MyProc()

您还可以选择将参数传递给函数,如下所示:

CREATE FUNCTION FuncName (@para1 para1_type, @para2 para2_type , ... ) 

并称之为

SELECT * FROM FuncName ( @para1 , @para2 )

答案 11 :(得分:5)

如果'数据访问'错误,

EXEC sp_serveroption 'SQLSERVERNAME', 'DATA ACCESS', TRUE

后,

SELECT  *  FROM OPENQUERY(SQLSERVERNAME, 'EXEC DBNAME..MyProc @parameters')

它有效。

答案 12 :(得分:4)

为了简单起见并使其可重新运行,我使用了一个系统StoredProcedure" sp_readerrorlog"获取数据:

-----USING Table Variable
DECLARE @tblVar TABLE (
   LogDate DATETIME,
   ProcessInfo NVARCHAR(MAX),
   [Text] NVARCHAR(MAX)
)
INSERT INTO @tblVar Exec sp_readerrorlog
SELECT LogDate as DateOccured, ProcessInfo as pInfo, [Text] as Message FROM @tblVar



-----(OR): Using Temp Table
IF OBJECT_ID('tempdb..#temp') IS NOT NULL  DROP TABLE #temp;
CREATE TABLE #temp (
   LogDate DATETIME,
   ProcessInfo NVARCHAR(55),
   Text NVARCHAR(MAX)
)
INSERT INTO #temp EXEC sp_readerrorlog
SELECT * FROM #temp

答案 13 :(得分:2)

听起来您可能只需要使用view。视图允许将查询表示为表,以便可以查询视图。

答案 14 :(得分:1)

例如,如果您的服务器名为SERVERX,我就这样做了......

EXEC sp_serveroption 'SERVERX', 'DATA ACCESS', TRUE;
DECLARE @CMD VARCHAR(1000);
DECLARE @StudentID CHAR(10);
SET @StudentID = 'STUDENT01';
SET @CMD = 'SELECT * FROM OPENQUERY([SERVERX], ''SET FMTONLY OFF; SET NOCOUNT ON; EXECUTE MYDATABASE.dbo.MYSTOREDPROC ' + @StudentID + ''') WHERE SOMEFIELD = SOMEVALUE';
EXEC (@CMD);

要检查这是否有效,我注释掉EXEC()命令行并将其替换为SELECT @CMD以在尝试执行命令之前查看命令!那是为了确保所有正确数量的单引号都在正确的位置。 : - )

我希望能帮助别人。