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

CREATE PROCEDURE MyProc
AS
BEGIN
    SELECT * FROM MyTable
END


我的实际过程稍微复杂一点,这就是为什么需要一个sproc的原因。
是否可以通过调用此过程选择输出?

类似的东西:

一个额外的SELECT TOP X子句来分页我的数据,我真的不想将这些值作为参数传递。

评论

我不确定您打算在这里做什么,因为在执行该过程时,您将获得返回的行。是否要在SELECT语句中执行该过程,以便将其绑定到可分页的对象?

您是否有特定的原因为什么不想将值作为参数传递?按照您所建议的方式执行此操作效率很低-您将选择比所需更多的数据,然后不使用所有数据。

在这里看看:sommarskog.se/share_data.html

如果有人想将sp输出插入到TABLE变量中,而sp中有很多列,请按Ctrl + T以文本形式输出结果,然后复制第一列行并从那里删除多余的空格,您将列名称很容易。要返回到网格输出,请按Ctrl + D

#1 楼

您可以使用用户定义的函数或视图代替过程。

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

评论


另外,如果在转换为UDF之后发现需要存储过程语义,则可以始终将UDF与过程包装在一起。

–乔尔·科恩(Joel Coehoorn)
09-09-29 13:26

如果需要发送多个存储过程的参数并将它们组合成一个大的存储过程,该怎么办?可以查看,获取参数,就像存储过程一样

–mrN
2011年8月18日在7:14

@mrN视图不接受参数,而UDF接受。

–梅尔达德·阿夫沙里(Mehrdad Afshari)
11年8月18日在8:26

您好,我真的需要在不将sp转换为视图或函数的情况下执行此操作,这可能吗?

–路易斯·贝塞里尔(Luis Becerril)
17 Mar 7 '17 at 17:46

虽然您的答案是正确的陈述,但它不会回答问题。...“从存储过程中选择”这肯定不是理想的选择,但事实就是如此……@Aamir的答案是正确的答案。要么需要更改问题,要么对我来说有点荒谬。

–Urasquirrel
19年6月17日在22:42

#2 楼

您可以


创建一个表变量以保存存储的proc中的
结果集,然后
然后插入
的输出将proc存储到表变量中,
,然后
像使用任何其他
表一样完全使用表变量
...

... sql ....

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


评论


INSERT #T或INSERT @T的问题是INSERT EXEC语句不能嵌套。如果存储过程中已经有INSERT EXEC,则此操作将无效。

– MOHCTP
13年5月30日在1:44



这可能是最可移植的解决方案,与基本SQL最接近。它还有助于维护强列类型定义。应该比上面更多的投票。

–user2074102
2014年8月8日在18:58



在sp重新编译方面,表变量在这里看起来比临时表更有用。因此,我同意,这个答案应该有更多的支持。

– resnyanskiy
16 Mar 16 '16 at 5:21

#3 楼

您需要表值函数或将EXEC插入临时表中:


评论


INSERT #T或INSERT @T的问题是INSERT EXEC语句不能嵌套。如果存储过程中已经有INSERT EXEC,则此操作将无效。

– MOHCTP
13年5月30日在1:44



#4 楼

您必须了解OPENROWSET和OPENQUERY

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


评论


如何动态获取YOURSERVERNAME?您不能期望总是知道。这个休息不是隔周二吗?所以,如果我有100台服务器,它们都使用不同的名称...

–Urasquirrel
19年6月17日23:30

如果我的数据库没有配置为允许该怎么办?

–Urasquirrel
19年6月17日在23:34

尝试@@ servername动态获取

–悉达多·甘地(Siddhartha Gandhi)
19/12/10在15:37

#5 楼

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

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


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

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


最后只需从表类型中选择

Select * from @MyTableType


评论


这对我来说是最好的解决方案,因为您无需指定服务器名称,连接字符串,也不必配置任何链接的服务器即可使其正常工作-我不想为了获得这些而这样做一些数据回来。谢谢!糟糕的答案!

–马特
17 Dec 5'在9:27



好答案ღ❤ೋღ❤ღೋ❤ღ

–纳希德
18年8月19日在6:29

如果存储过程过于困难-例如,当存储过程使用两个临时表时,此方法将无法使用。

– nick_n_a
18/12/27在9:25



#6 楼

不必使用临时表。

这是我的解决方案

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


评论


这需要您将服务器作为链接服务器添加到其自身,但它的作用就像一个吊饰!谢谢!

–vaheeds
16年11月16日在9:42

关于此的一些重要警告:stackoverflow.com/questions/2374741/…

–基思·阿德勒(Keith Adler)
17年5月19日在7:57

嗯...我收到错误消息“错误7411:未为数据访问配置服务器'YourServerName'。”我需要更改什么?

–马特
17年5月5日在9:21

您是否已将服务器添加为链接服务器? YourServerName是服务器的名称。您必须使用真实的服务器名称更改YourServerName。

– DavideDM
17年5月5日在10:50

@Matt:sp_serveroption'MYSERVER','DATA ACCESS',TRUE;

– alexkovelsky
'18 Sep 10'在16:25

#7 楼

您可以将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 楼

尝试将过程转换为内联函数,该内联函数将返回一个表,如下所示: br />
还可以选择将参数传递给函数,如下所示:

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


并调用它

#9 楼

使用OPENQUERY,然后执行set'SET FMTONLY OFF; SET NOCOUNT ON;'

尝试以下示例代码:

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


#10 楼

如果'DATA ACCESS'为假,

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


之后,

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


有效。

#11 楼

您可以使用OPENROWSET进行一些欺骗:

评论


SQL Server阻止访问组件“ Ad Hoc Distributed Queries”的状态“ OpenRowset / OpenDatasource”,因为此组件的安全配置已关闭此组件。系统管理员可以通过使用sp_configure启用“临时分布式查询”的使用。有关启用“临时分布式查询”的更多信息,请在SQL Server联机丛书中搜索“临时分布式查询”。

– GuidoG
11月20日12:51

#12 楼

为了简单起见并使其可重新运行,我使用了系统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 楼

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

#14 楼

例如,如果您的服务器名为SERVERX,这就是我的操作方法。使用EXEC()在尝试执行命令之前先对其进行检查!那是为了确保所有正确数量的单引号都在正确的位置。 :-)

我希望能帮助某人。