【问题标题】:How to limit results of Stored procedure for MS-SQl如何限制 MS-SQl 存储过程的结果
【发布时间】:2020-12-18 03:11:49
【问题描述】:

问题是...我将收到一个命令来执行一个过程...比如EXEC SAMPLE_PROCEDURE_NAME我无法修改或将计数/数字传递给该过程

现在,在执行时,该过程正在返回所有行。我想限制收到的行数

以下是我尝试过的一些事情(程序名称 = Demo4

这个失败了

select top 10 * FROM (EXEC Demo4)

这个也失败了

;WITH Results_CTE AS
(
    EXEC Demo4
)
select top 10 *
FROM Results_CTE

这个也失败了

DECLARE @tmpNewValue TABLE (*)
INSERT INTO @tmpNewValue 
  EXEC Demo4
select top 10 * FROM @tmpNewValue

如果有人能提供帮助,我将不胜感激。

【问题讨论】:

  • 您不能在存储过程中SELECT。如果要限制过程返回的行数,则需要将TOP 子句放在过程中的SELECT inside 中。另外,在使用TOP 时,请确保您有ORDER BY;否则你会得到任意行,结果将不一致。
  • 也许您应该在您的过程中添加一个@Top 参数,然后在您的存储过程的定义中添加TOP (@TOP) 和一个ORDER BY
  • 我无法修改程序
  • 这有一种XY Problem 的强烈气味。正如我第一次提到的,您不能从程序中SELECT。考虑到您甚至不知道定义,那么您甚至没有可行的ORDER BY 子句。您需要正确地定义您 INSERT 到的表,或 ALTER 过程。考虑到你不知道定义,你只剩下后者了。
  • 您使用什么应用程序来执行 proc?您只能处理客户端应用程序中返回的前 10 行。没有 T-SQL 解决方案可以限制具有未知结果集架构的任意 proc 的行数,除非您使用 SQLCLR。

标签: sql sql-server database


【解决方案1】:

您需要指定结果集中的列才能将它们放入表中。所以:

declare @tmpNewValue table (
    col1 type1,
    col2 type2,
    . . .
);

然后你可以插入行:

INSERT INTO @tmpNewValue 
      EXEC Demo4;

并返回 10 个 任意 行:

select top 10 *
from @tmpNewValue;

你需要一个ORDER BY 来获得十个特定的行(比如“第一”,不管这意味着什么)。

如果您希望它们按插入顺序排列并且没有其他方法,那么您可以在表中使用标识列:

declare @tmpNewValue table (
    id int identity(1, 1),
    col1 type1,
    col2 type2,
    . . .
);

insert into @tmpNewValue (col1, col2, . . . )   -- no `id` column here
      exec Demo4;

然后:

select top (10) *
from @tmpNewValue
order by id;

我应该补充一点,我强烈不鼓励返回这样的结果集。存储过程不应被视为可查询对象。代码可能会因为有人对存储过程进行小修改而中断——比如添加调试或审计代码。

还有其他方法可以处理这些情况:

  • 如果不需要多行,则可以使用OUTPUT参数。
  • 在许多情况下,可以将存储过程编写为用户定义的函数。
  • 您可以传入一个表变量来返回一个表(尽管这需要用户定义的类型)。

【讨论】:

  • 不幸的是,OP 使 cmets 中此答案中的所有内容无效,而不是在问题的实际内容中添加所有(奇怪的)要求,因为我完全同意这里的所有内容。例如,OP 完全忽略了他们无法更改定义以及执行的 SP 在问题内容中是“动态的”。这两个事实都完全改变了需求(并且有一种没有被告知真实故事的强烈代码味道)。
  • 这是一种短期可行的解决方法,但长期来看可能是一个糟糕的解决方案。
  • @PraveenPrasad 。 . .如果你以后想使用数据,你需要知道表结构。就是这么简单。听起来您需要重新审视整个架构——尤其是如果同一个存储过程可以在不同时间返回不同的结果集。
  • “假设我已经知道此过程将返回哪些数据。” 因为您没有告诉问题中的人们该信息,@PraveenPrasad。您解释了 cmets 中的所有警告,这是错误的地方。但我坚持认为这显然是XY Problem
  • 再次,因为由 SP 来实现 TOP、@PraveenPrasad 。你把EXEC 当作SELECT 对待,而它一点也不像一个
【解决方案2】:

您可以通过在运行存储过程之前设置行数来限制存储过程中的行数并稍后释放它,如下所示

解决方案:SET ROWCOUNT 50; EXEC Demo4; SET ROWCOUNT 0;

描述:运行SET ROWCOUNT 50; 将限制任何查询的结果,包括存储过程。然后您以EXEC Demo4; 执行存储过程,以释放连接,将行数限制为50,您必须将其设置为零为SET ROWCOUNT 0;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-10
    • 1970-01-01
    • 2016-06-12
    相关资源
    最近更新 更多