【问题标题】:CASE vs IF-ELSE-IF vs GOTO keywordCASE vs IF-ELSE-IF vs GOTO 关键字
【发布时间】:2013-06-29 07:13:49
【问题描述】:

我的应用程序中有一些规则,并且我已经在我的程序中编写了这些规则的业务逻辑。在创建过程时,我知道CASE 表达式在我的场景中不起作用。所以我尝试了两种方法来执行相同的操作(使用IF-ELSE-IFGOTO),如下所示。

方法一使用IF-ELSE-IF条件:

DECLARE @V_RuleId SMALLINT;

IF (@V_RuleId = 1) 
BEGIN 
    /*My business logic*/
END
ELSE IF (@V_RuleId = 2) 
BEGIN 
    /*My business logic*/
END
ELSE IF (@V_RuleId = 3) 
BEGIN 
    /*My business logic*/
END
/* 
...
...
...
...*/
ELSE IF (@V_RuleId = 19) 
BEGIN 
    /*My business logic*/
END
ELSE IF (@V_RuleId = 20) 
BEGIN 
    /*My business logic*/
END

方法2使用GOTO语句:

DECLARE @V_RuleId SMALLINT, @V_Temp VARCHAR(100);

SET @V_Temp = 'GOTO RULE' + CONVERT(VARCHAR, @V_RuleId);
EXECUTE sp_executesql @V_Temp;

RULE1: 
BEGIN 
    /*My business logic*/
END

RULE2: 
BEGIN 
    /*My business logic*/
END

RULE3: 
BEGIN 
    /*My business logic*/
END

/* 
...
...
...
...*/

RULE19: 
BEGIN 
    /*My business logic*/
END

RULE20: 
BEGIN 
    /*My business logic*/
END

今天我有 20 条规则。以后可以增加到任意数量。如果我可以使用 CASE 表达式,那么我的性能没有任何问题,但我不能这样做,所以我担心我的程序的性能。

还有一点需要注意的是,此过程将由应用程序非常频繁地执行。

我的问题是:

有什么方法可以在我的程序中使用 CASE 表达式吗?如果不是,在我的程序中最好使用哪种方法来提高我的代码的性能?

【问题讨论】:

  • 方法2不起作用..

标签: sql sql-server if-statement case goto


【解决方案1】:

试试这个 -

DECLARE @V_RuleId SMALLINT
SELECT @V_RuleId = 1;

DECLARE @temp TABLE
(
      RuleID INT
    , Query NVARCHAR(MAX)
)

INSERT INTO @temp (RuleID, Query)
VALUES 
    (1, 'EXEC dbo.usp_test1;'),
    (2, 'CREATE TABLE dbo.Table1 (ID INT);'),
    (3, 'DROP TABLE dbo.Table1;')

DECLARE @SQL NVARCHAR(MAX)

SELECT @SQL = Query 
FROM @temp
WHERE RuleID = @V_RuleId

PRINT @SQL

EXEC sys.sp_executesql @SQL

【讨论】:

  • 感谢您的回答,但我无法将查询放入表中,我必须将它们放入所有规则的程序中。
  • 根据要求,我必须将整个逻辑放在一个程序中,我无法为所有规则创建多个程序。
【解决方案2】:

就像你说的,我不认为 CASE 表达式可以在这里工作。 CASE 只会返回一个值。我假设您的过程将返回多个值。我喜欢你的GOTO 方法。您应该尝试几千条规则,看看性能是否确实是一个问题。

我还有另一个建议。您可以将所有代码放在一个表中并将它们作为动态 SQL 运行。它们不会是真正动态的,因为它们总是相同的,因此 SQL Server 仍然可以缓存这些执行计划。然后案例查找将是您的表索引,这非常快。我不确定它是否比GOTO 方法快。

总之,请用荒谬的规则试一试,让我们知道你的结果是什么。

【讨论】:

    【解决方案3】:

    如果可能的话,我会在域层(或应用程序中的业务层)中处理该逻辑。因为如果规则数量增加到很大数量(没有人能够读取那个大的 SQL 语句),您将来会遇到问题。

    您应该检查面向对象的 SOLID 原则,尤其是 OpenClose 原则。

    理论上你可以像这样使用案例(取决于规则在做什么):

    DECLARE @rule  int = 1;
    SELECT CASE @rule
    WHEN 1 THEN
    @rule
    WHEN 2 THEN 
    @rule
    END 
    

    但是,由于 T-SQL 不是一种过程语言,也许您应该尝试将规则存储在表中并从集合中返回规则,而不是使用过程逻辑(以获得更好的性能)如果可能的话。

    【讨论】:

    • 感谢您的回答,但在我们的产品中,我们需要在程序中执行该逻辑,因此我无法在应用程序级别实施。
    • 嗯,我希望 :),我将通过编辑原件来提供我的第二个答案!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-09
    • 1970-01-01
    • 2014-04-03
    • 2012-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多