【问题标题】:Getting Top N from stored procedure从存储过程中获取 Top N
【发布时间】:2012-07-13 08:34:26
【问题描述】:

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

该程序位于另一个我们访问权限非常有限的数据库上;所以我想要做的是以某种方式将存储过程包装在 queryfunctionstored procedure 中,这将允许我 选择返回数据中的前 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

我知道这绝不是正确的,有没有办法做这样的事情?目前,对于模糊查询,我们返回了数千行;这大大降低了服务器速度。

我已经为解决方案做了一些谷歌搜索和堆栈溢出,但不幸的是,我能找到的所有建议都涉及修改存储过程。

【问题讨论】:

  • 在不重写 remote 过程的情况下,唯一可以做到这一点的方法是将 proc 的输出放入一个临时表并从中进行选择。但这意味着:检索整个输出,然后从中仅选择前 10 行...
  • @marc_s:我认为OPENQUERY 也应该是一个选项。
  • @AndriyM:是的,当然 - 但它基本上做同样的事情,意思是:即使这种方法也不能将远程过程的输出限制为 10 行,对吧?
  • 依赖于存储过程 SET ROWCOUNT 10;EXEC your_proc 中的逻辑可能会起作用。
  • @Waltzy - 您需要查看存储过程的定义以检查这是否安全,因为它将适用于过程中可能改变语义的所有语句(例如,如果它确实任何中间的表变量或临时表,这些语句也会受到影响)。如果 proc 只是一个简单的SELECT ... WHERE ... ORDER BY,那么它应该没问题。

标签: tsql stored-procedures sql-server-2008-r2 subquery sql-function


【解决方案1】:

查找 EXEC SP_EXECUTESQL(@SQL) 但是问题是被调用的 sp 仍将返回所有行,因此您可能无法获得所需的性能改进。 您还可以设置查询返回的行数 - 但取决于您的访问级别 http://blog.sqlauthority.com/2007/04/30/sql-server-set-rowcount-retrieving-or-limiting-the-first-n-records-from-a-sql-query/ 希望这会有所帮助

【讨论】:

    【解决方案2】:
    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 ;
    

    【讨论】:

      猜你喜欢
      • 2017-01-01
      • 2016-08-04
      • 1970-01-01
      • 2018-03-04
      • 2011-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-28
      相关资源
      最近更新 更多