使用 IF..ELSE IF 控制 T-SQL SP 中的流 - 还有其他方法吗?

Posted

技术标签:

【中文标题】使用 IF..ELSE IF 控制 T-SQL SP 中的流 - 还有其他方法吗?【英文标题】:Control flow in T-SQL SP using IF..ELSE IF - are there other ways? 【发布时间】:2009-10-13 18:41:29 【问题描述】:

我需要将我的 T-SQL 存储过程 (MS SQL 2008) 控制流分支到多个方向:

CREATE PROCEDURE [fooBar]
   @inputParam INT
AS
BEGIN
  IF @inputParam = 1
  BEGIN
    ...
  END
  ELSE IF @inputParam = 3
  BEGIN
    ...
  END
  ELSE IF @inputParam = 3
  BEGIN
    ...
  END
END

还有其他方法吗?例如,在C# 中,我应该使用switch-case 块。

【问题讨论】:

BEGIN/END 不是必需的,除非您在决策逻辑的该部分中执行多项操作。 @rexem:是的,我知道。我故意写这个是因为每个块都包含很多代码 @rexem,每当我省略了开始结束时,我在维护时后悔了,当他们在 IF 的分支中添加第二步时忘记添加它们。我现在总是使用它们。 @HLGEM:好点子,我还没有那种快乐 :) 存储过程,要表现良好,应该只做一项任务,并尽量减少 T-SQL 中这种类型的条件逻辑。更好的设计是制作多个 proc,每个 proc 执行一项任务,并在您的应用程序中决定调用哪个。这是与全功能编程语言的根本区别。缓存计划是 if/then 的一个问题,尽管 SQL 2008 在语句级重新编译方面取得了一些进展。 【参考方案1】:

IF...ELSE... 几乎就是我们在 T-SQL 中所拥有的。没有什么能比得上结构化编程的 CASE 语句。如果您要处理一组扩展的 ...ELSE IF...,请务必在每个块中包含 BEGIN...END 以保持清晰,并始终记住,一致的缩进是您的朋友!

【讨论】:

我总是在编写开始和结束之间的代码之前编写我的 ifs 和 begin 和 end,这样可以节省大量的调试时间,以便在任何介于两者之间的代码之前放入 begin 结束. T-SQL中存在case语句 T-SQL case 语句,怎么说呢,用作“子句”,是其他语句的一部分——最常见的是 SELECT 语句。它们不能像在各种 .NET 语言中那样用于控制程序流。 在我们复制粘贴驱动的世界中,如果这个答案包含一个实际的例子会很好;) 是的,但是,原始问题包含 if-else ifbegin/end 结构的示例,另一个示例将是多余的。【参考方案2】:

您也可以尝试以SELECT CASE 声明的形式制定您的答案。然后,您可以稍后创建简单的 if then's,在需要时使用您的结果,因为您已经缩小了可能性。

SELECT @Result =   
CASE @inputParam   
WHEN 1 THEN 1   
WHEN 2 THEN 2   
WHEN 3 THEN 1   
ELSE 4   
END  

IF @Result = 1   
BEGIN  
...  
END  

IF @Result = 2   
BEGIN   
....  
END  

IF @Result = 4   
BEGIN   
//Error handling code   
END   

【讨论】:

这将是 GOTO 的确切工作【参考方案3】:

不,但是在存储过程中使用 IF...ELSE...END IF 时应该小心。如果您的代码块完全不同,您可能会遇到性能不佳的问题,因为每次都需要重新缓存过程计划。如果它是一个高性能系统,您可能希望为每个代码块编译单独的存储过程,并让您的应用程序决定在适当的时间调用哪个过程。

【讨论】:

这是真的。但是,如果分支只能发生在过程中(而不是您的应用程序调用多个过程中的一个),那么您仍然会遇到一系列 IF 语句。 我的 proc 名称 [execOperation] 已从 ASP.NET FormView 调用,其参数来自下拉列表,其中包含可能的操作类型列表。所以我不可能拥有多个单独的 proc,不幸的是【参考方案4】:

Transact-SQL control-of-flow 语言关键字是:

BEGIN...ENDBREAKCONTINUEGOTO labelIF...ELSERETURNTHROWTRY...CATCHWAITFORWHILE

【讨论】:

【参考方案5】:

不,如果是要走的路,您使用它有什么问题?

顺便说一句,您的示例永远不会到达第三个代码块,因为它和第二个代码块完全相同。

【讨论】:

【参考方案6】:
CASE expression
      WHEN value1 THEN result1
      WHEN value2 THEN result2
      ...
      WHEN valueN THEN resultN

      [
        ELSE elseResult
      ]
END

http://www.4guysfromrolla.com/webtech/102704-1.shtml了解更多信息。

【讨论】:

这仅适用于查询。我需要在块内编写任何内容,即具有不同查询和其他 SP 调用的多行代码 在 T-SQL 中 CASE 是一个 EXPRESSION 而不是一个控制分支。非常不同的野兽。 这超出了 SELECT 语句上下文。

以上是关于使用 IF..ELSE IF 控制 T-SQL SP 中的流 - 还有其他方法吗?的主要内容,如果未能解决你的问题,请参考以下文章

9.if/else/elif

Python基础流程控制-if..else

if else 逻辑关系问题

Python流程控制语句怎么写?

如何在 Snowflake 中编写等效的 IF ELSE adhoc sql 查询

第六章:分支控制流(if else switch)