Tsql 从存储过程中获取Top N

Tsql 从存储过程中获取Top N,tsql,stored-procedures,sql-server-2008-r2,subquery,sql-function,Tsql,Stored Procedures,Sql Server 2008 R2,Subquery,Sql Function,我有一个无法修改的存储过程,在有人建议我重新编写存储过程或将查询从存储过程内部添加到函数之前,我要强调这一点 这个过程存在于另一个数据库中,我们对该数据库的访问非常有限;因此,我想做的是以某种方式将存储过程包装在一个查询、函数或存储过程中,这将允许我从返回的数据中选择前N行 理想情况下,我可以打电话给像 DECLARE @ForeName varchar(50) DECLARE @Surname varchar(50) DECLARE @DOB datetime DECLARE @Sex var

我有一个无法修改的存储过程,在有人建议我重新编写存储过程或将查询从存储过程内部添加到函数之前,我要强调这一点

这个过程存在于另一个数据库中,我们对该数据库的访问非常有限;因此,我想做的是以某种方式将存储过程包装在一个查询函数存储过程中,这将允许我返回的数据中选择前N行

理想情况下,我可以打电话给像

DECLARE @ForeName varchar(50)
DECLARE @Surname varchar(50)
DECLARE @DOB datetime
DECLARE @Sex varchar(1)

SET @Surname = 'Smith'

SELECT TOP 10 (
   EXECUTE @RC = [Some_Other_Database].[dbo].[sp_search_demographics] 
     ,@ForeName
     ,@Surname
     ,@DOB
     ,@Sex
)
GO
编辑:(我还应该注意,存储过程返回一个包含行数和行数的参数)

edit2:我还应该注意,我使用的是MS SQL Server 2008 R2

我知道这绝对是不对的,有没有办法做到这一点?目前,对于模糊的查询,我们得到了数千行返回;这大大降低了服务器的速度

我在谷歌上搜索了一些解决方案,并进行了堆栈溢出,但不幸的是,我能找到的所有建议都涉及到修改存储过程。

查找EXEC SP_EXECUTESQL(@SQL) 但是,问题是被调用的sp仍将返回所有行,因此您可能无法获得所需的性能改进。 您还可以设置查询返回的行数,但这取决于您的访问级别
希望这有帮助

在不重写远程过程的情况下,唯一可以做到这一点的方法是将该过程的输出放入临时表中,然后从中进行选择。但这意味着:检索整个输出,然后只从中选择前10行…@marc_s:我认为
OPENQUERY
也应该是一个选项。@AndriyM:是的,当然-但它基本上做了相同的事情,这意味着:即使这种方法也不能将远程过程的输出限制为仅10行,对吗?取决于存储过程中的逻辑
设置行计数10;EXEC您的_proc
可能会起作用。@Waltzy-您需要查看存储的proc的定义,以检查它是否安全,因为它将应用于proc中可能会更改语义的所有语句(例如,如果它执行任何中间填充表变量或临时表,这些语句也将受到影响)。如果程序只是一个简单的
选择。。。哪里按下单
那么就可以了。
Declare @i  Numeric(18,2)
Declare @strSQL nvarchar(1000)
select @i = Round(COUNT(1)/10,2) from tb_Item
print(@i)
Declare @j int = 0

Declare @rem numeric(18,2)
select @rem = COUNT(1) - ((COUNT(1)/10) * 10) from tb_Item 

while @i > 0
Begin
    set @j = (@j + 1);

    if @j = 1
    Begin
        WITH OrderedOrders AS
        (
            select 
                ROW_NUMBER() over(order by ItemID) AS RowNumber
                ,ItemName
            from tb_Item 
        ) 
        SELECT ItemName, RowNumber  
        FROM OrderedOrders 
        WHERE RowNumber BETWEEN (@j*10)-10 AND @j*10;
    End
    Else
    Begin
        WITH OrderedOrders AS
        (
            select 
                ROW_NUMBER() over(order by ItemID) AS RowNumber
                ,ItemName
            from tb_Item 
        ) 
        SELECT ItemName, RowNumber  
        FROM OrderedOrders 
        WHERE RowNumber BETWEEN ((@j*10)-10) + 1 AND @j*10;
    End 
    set @i = @i - 1;
end;

WITH OrderedOrders AS
(
    select 
        ROW_NUMBER() over(order by ItemID) AS RowNumber
        ,ItemName  
    from tb_Item 
) 
SELECT ItemName, RowNumber  
FROM OrderedOrders 
WHERE RowNumber BETWEEN (@j*10)+1 and (@j*10) + @rem ;