【问题标题】:How not to return select statements in SQL Server stored procedure if there is raiseerror below?如果下面出现 raiseerror,如何不返回 SQL Server 存储过程中的 select 语句?
【发布时间】:2018-07-22 18:03:44
【问题描述】:

如果有 raiseerror 或 throw 下面,SQL Server 是否可以通过某种方式在存储过程中不返回 select 语句?

我有选择语句,如果行数大于某个数字,我会引发错误。在我的应用程序中,我使用 ado.net,因此错误出现在第二个结果中(我必须执行 NextResult(),所以在此之前我必须处理我的第一个结果)。是否有可能知道是否有第二个结果?还是可以不返回 select ?或者我该如何解决这个问题:如果它的行数大于某个特定数字,则不处理选择?

【问题讨论】:

  • select 语句没有副作用,所以没有什么可以撤消的。
  • 是的,我的意思是不要在 sp 结果中返回那个选择
  • 你的意思是如果你有SELECT 1; SELECT 0/0 不返回第一个数据集?就像@GordonLinoff 所说,您不能“撤消”数据集。如果您想在发生错误时丢弃该数据集,请处理应用程序中的错误。
  • 否则,我唯一能想到的就是把你所有的数据集放到临时表中,然后在处理完SP中的所有数据集后返回这些数据集。如果您有很多数据集或非常大的数据集,则可能会对性能产生(严重)影响。在应用程序中进行丢弃是这里的“正确”选择(在我看来)。
  • (不要粗鲁,但是)你似乎不太愿意接受这里的建议。如果您无法更改您的应用程序或对象,那么您可以做什么?您似乎想要对 SQL Server 本身进行功能更改,而不是更改您的应用程序以使用 SQL Server 的已知功能。您可能需要考虑扩展您的问题以解释您的实际目标(目前尚不清楚,仅在 cmets 中进行了解释),然后希望如何实现您的目标和您面临的限制.无法更改您的对象或应用程序是很大的限制。

标签: sql sql-server stored-procedures ado.net raiserror


【解决方案1】:

您无法检查语句在不运行的情况下将返回多少行,不。如果在运行该语句之前,您有一个(简单)语句(如 SELECT * FROM MyTable1 MT1 JOIN MyTable2 MT2 on MT1.ID = MT2.fID;),SQL Server 将不知道将返回多少行。

但是,如果您不想在该数据集有更多 x 行的情况下返回该数据集,则可以使用 IF 语句:

IF (SELECT COUNT(*) FROM MyTable1 MT1 JOIN MyTable2 MT2 on MT1.ID = MT2.fID) <= 1024 BEGIN

    SELECT *
    FROM MyTable MT1
         JOIN MyTable MT2 ON MT1.ID = MT2.fID;

    SELECT ... --Your other SELECT statement
END ELSE BEGIN
    RAISERROR(...
END

如果超过 1024 行,则不会返回任何数据集。此选项(可能)比将所有数据插入临时表之类的过程成本更低,尤其是在您使用大型数据集时。如果您将所有内容都插入到临时表中,则需要读取每一行行并将其写入 tempdb,然后在您在语句末尾返回数据时回读;这不是一个需要大量数据的廉价操作。

【讨论】:

  • 谢谢,我也在考虑这个解决方案。但在这种情况下,我必须运行我的查询两次,这是一个包含许多连接和条件的繁重查询
  • @AramGevorgyan 你真的无能为力。这就是为什么我建议在您的应用程序中处理它。如果这不是一个选项,那么您就是在强迫自己采用一个不太理想的解决方案,这意味着不止一次运行部分查询。
  • 如果有办法知道是否有第二个结果而不丢失第一个结果,我会使用 ado.net,我会在我的应用程序中处理它
  • @AramGevorgyan,SQL Server 以串行方式将结果流回应用程序,因此后续消息和结果集位于第一个消息和结果集之后,并且在应用程序使用第一个消息和结果集之前不可用。您唯一的选择是运行两次查询,使用 Gordon 提到的临时表方法,或者在您的应用代码而不是 T-SQL 中处理它。
  • 那么,你的逻辑(伪逻辑)是Perform SELECT statement1; IF Statement1.Rows &gt; x {RaiseError. Exit} Perform SELECT Statement2. Exit吗?否则,为什么不返回 2 个结果集,除非发生错误(然后应该在应用程序中处理)。 @DanGuzman 是我建议的临时表。但是,感谢您将我与 Gordan 混淆。 ;)
猜你喜欢
  • 1970-01-01
  • 2010-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-14
相关资源
最近更新 更多