Sql server 使用where子句筛选存储过程的结果集

Sql server 使用where子句筛选存储过程的结果集,sql-server,tsql,Sql Server,Tsql,我希望筛选存储过程的结果集。我想要的是如下(非工作)语法: 编辑-这只是一个例子,如果可能的话,我想要一个通用的解决方案 -- add 'loopback' linkedserver if exists (select * from master..sysservers where srvname = 'loopback') exec sp_dropserver 'loopback' go exec sp_addlinkedserver @server = N'loopback',

我希望筛选存储过程的结果集。我想要的是如下(非工作)语法:

编辑-这只是一个例子,如果可能的话,我想要一个通用的解决方案

-- add 'loopback' linkedserver 
if exists (select * from master..sysservers where srvname = 'loopback')
    exec sp_dropserver 'loopback'
go
exec sp_addlinkedserver @server = N'loopback',
    @srvproduct = N'',
    @provider = N'SQLOLEDB', 
    @datasrc = @@servername
go

select * into #t from openquery(loopback, 'set fmtonly on exec sp_who') 
select * from #t
drop table #t
go

您可以在此之前将存储过程的结果放入临时表或表变量中,然后查询该表,对该表应用所需的where子句

[编辑]

像这样:

DECLARE @foo TABLE
(
SRV_NAME NVARCHAR(100),
SRV_PROVIDERNAME NVARCHAR(100),
SRV_PRODUCT NVARCHAR(100),
SRV_DATASOURCE NVARCHAR(100),
SRV_PROVIDERSTRING NVARCHAR(100),
SRV_LOCATION NVARCHAR(100),
SRV_CAT NVARCHAR(100)
)

INSERT INTO @foo
EXEC  sp_linkedservers

SELECT * FROM @foo WHERE SRV_PRODUCT = 'SQL Server'

当然,您可以将最后一个where子句更改为您希望筛选的内容。

将存储过程移动到表值用户定义函数。保留现有的存储过程,但只是让它调用这个新函数,而不是复制逻辑。然后在查询中使用该函数。

假设您希望该函数用于问题中概述的确切目的,而不是一般解决方案,那么您可以只查询sys.servers(SQL 2005+)(或sysservers 2005之前的版本),无需使用sp_linkedserver存储过程:

-- SQL 2005+
IF EXISTS ( SELECT 1 FROM sys.servers WHERE name = 'myServer' )
    PRINT N'dropping linked servers'
GO

-- SQL 2000
IF EXISTS ( SELECT 1 FROM sysservers WHERE srvname = 'myServer' )
    PRINT N'dropping linked servers'
GO

这是一个系统存储过程。无法更改它。如果存储过程使用临时表,这也可能不起作用。因为用户定义的函数不能使用临时表。那么,在sql server中,这是您可以完全按照自己的意愿执行操作的唯一方法,为什么会被否决呢?恕我冒犯,这很聪明,但有两个原因-openquery可能是一个安全问题,所以在许多系统上它会被关闭;对于这个问题,建立一个链接服务器是过分的;我知道你使用的是链接服务器和openquery的“副作用”,其他人不希望看到,这是完全正确的。我假设OP并不总是知道存储过程的确切输出。如果您确实知道这一点,那么首先声明表并从存储过程插入是一个很好的解决方案。如果不是,那么我的建议是唯一可行的方法。在SQL 2000上,您需要使用临时表而不是表变量,并且在不声明结果集架构的情况下,是否没有办法做到这一点?当存储过程包含INSERT-EXEC语句时,这可能不起作用。因为这种句子不能嵌套。
-- SQL 2005+
IF EXISTS ( SELECT 1 FROM sys.servers WHERE name = 'myServer' )
    PRINT N'dropping linked servers'
GO

-- SQL 2000
IF EXISTS ( SELECT 1 FROM sysservers WHERE srvname = 'myServer' )
    PRINT N'dropping linked servers'
GO