SQL Server - SELECT FROM 存储过程

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

CREATE PROCEDURE MyProc
AS
BEGIN
    SELECT * FROM MyTable
END

我的实际过程有点复杂,这就是为什么需要一个sproc。

是否可以通过调用这个程序来选择输出?

比如说

SELECT * FROM (EXEC MyProc) AS TEMP

我需要使用SELECT TOP XROW_NUMBER,和一个额外的WHERE子句来分页我的数据,我并不希望把这些值作为参数传递。

对该问题的评论 (3)

你可以

创建一个表变量来保存 的结果集,然后 然后 2. 将存储过程的输出插入 的输出插入到表变量中。 然后 3. 使用该表变量 就像你使用任何其他 表...

... sql ....

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

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

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

1:

评论(3)
解决办法

您可以使用[用户自定义函数][1]或[视图][2]代替过程。

[1]: https://docs.microsoft.com/en-us/sql/relational-databases/user-defined-functions/user-defined-functions [2]: https://docs.microsoft.com/en-us/sql/relational-databases/views/views

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

评论(6)

你要么想要一个表值函数,要么将你的EXEC插入到一个临时表。

INSERT INTO #tab EXEC MyProc
评论(1)

您必须阅读OPENROWSETOPENQUERY

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

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

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

然后你需要将存储过程的结果插入到你刚才定义的表类型中去

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

最后只需从你的表类型中选择

Select * from @MyTableType
评论(3)

不需要使用临时表。

这是我的解决方案

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

你可以将sp的输出复制到temporaty表中。

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
评论(0)

使用OPENQUERY并在执行前设置'SET FMTONLY OFF。 SET NOCOUNT ON;&#39。

试试这个示例代码。

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

试着将你的存储过程转换为一个内联函数,其返回的表格如下。

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 )
评论(0)

如果'DATA ACCESS&#39。 false,

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

之后。

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

它的工作原理。

评论(0)

你可以用OPENROWSET作弊一下。

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

当然,这样每次还是会运行整个SP。

评论(0)

为了简单起见,也为了让它可以重复运行,我使用了一个系统的StoredProcedure "sp_readerrorlog&quot。 来获取数据。

-----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
评论(0)

听起来你可能只需要使用一个视图。 视图允许将查询表示为一个表,因此它,即视图,可以被查询。

评论(0)

例如,如果你的服务器叫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,以便在尝试执行命令之前查看命令!这是为了确保所有正确的单引号数量。 这是为了确保所有正确的单引号数量都在正确的地方。 :-)

希望能帮到别人。

评论(0)