代码之家  ›  专栏  ›  技术社区  ›  Kieran Senior

SQL CASE语句与程序设计语言中的条件语句

  •  1
  • Kieran Senior  · 技术社区  · 16 年前

    我在工作中经历了一些旧的存储过程,经常遇到

    CASE MyColumn WHEN 'Y' THEN 'Yes' WHEN 'N' THEN 'No' ELSE 'Unknown' END
    

    当它不是与一个单词联系在一起,而是与一种颜色联系在一起时,情况会变得更糟。

    CASE MyColumn WHEN 'Y' THEN 'style="background-color:pink"' ELSE '' END
    

    这样做的原因是对于旧的ASP 1页面,所有内容都必须内联完成,但由于它是一个如此庞大的系统,不可能跟上所有页面的更新。

    有人能提供任何有效的证据,证明对条件语句使用SQL查询优于C#或Java等其他语言吗?这是提高速度的好方法吗?是否应该返回明文值,并由表示层决定应该做什么?

    6 回复  |  直到 16 年前
        1
  •  3
  •   edosoft    16 年前

    当速度至关重要时,SQL case语句甚至可能是最快的(我将运行一个测试),但为了可维护性,将普通值返回给表示层(或一些业务层)是最好的选择。

    [update]运行了一些快速而肮脏的测试(下面的代码),发现C#代码变体比SQL case变体略快。结论:返回“原始”数据并在表示层对其进行操作既更快又更易于维护。

    -爱德华

    我检索到196288行,查询如下。

    StringBuilder result = new StringBuilder();
    using (SqlConnection conn = new SqlConnection(Settings.Default.Conn))
    {                
        conn.Open();
        string cmd = "select [state], case [state] when 'ca' then 'california' else [state] end from member";
        SqlCommand command = new SqlCommand(cmd, conn);
        using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection))
        {
            while (reader.Read())
            {                        
                result.AppendLine(reader.GetString(1));
            }
        }
    }
    

    C#变体:

    StringBuilder result = new StringBuilder();
    using (SqlConnection conn = new SqlConnection(Settings.Default.Conn))
    {
    
        conn.Open();
        string cmd = "select [state] from member";
        SqlCommand command = new SqlCommand(cmd, conn);
        using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection))
        {
            while (reader.Read())
            {
                result.AppendLine(reader.GetString(0) == "ca" ? "california" : reader.GetString(0));
            }
        }
    

    }

        2
  •  2
  •   Anthony Mastrean PavanDevarakonda    16 年前

    我会担心把这种逻辑放在SQL语句中。如果数据库引擎发生变化,会发生什么?您是否必须将每个SQL语句更新为Oracle SQL?当您移动到消息总线、XML文件或web服务调用时,如果存储库本身发生了变化,该怎么办。..

    看起来您正在存储显示信息。在这种情况下,它是数据模型的一部分。让控制器(在典型的 MVC pattern )执行条件逻辑。表示层不需要知道发生了什么,存储库可以很高兴地保存数据。

        3
  •  0
  •   Quassnoi    16 年前

    有人能提供任何有效的证据,证明对条件语句使用SQL查询优于C#或Java等其他语言吗?这是提高速度的好方法吗?是否应该返回明文值,并由表示层决定应该做什么?

    有时(有时)它只是有助于避免在表示层中进行额外的编码。

    通常,如果数据库和演示文稿都是由一个人开发的,那也没关系。当工作被分担时,问题就开始了。在这种情况下,很明显,您需要一份关于数据库发出什么和ASP接受什么的明确合同。

    当然,CSS属于表示层的领域,它应该由ASP解析,而不是用SQL硬编码。

        4
  •  0
  •   SQLMenace    16 年前

    这是老式的代码,我不相信人们再这样编码了(我们现在使用CSS)
    您可能正在查看一些即将被重写或放弃的遗留内容

        5
  •  0
  •   John    16 年前

    就SQL性能而言,如果您只返回几行(或根据外观返回一行),则影响很小,因为语句的WHERE部分是在case之前计算的(case仅在与WHERE匹配的行上执行)。

    从最佳实践的角度来看,显示信息不应该在SQL中真正确定。也许返回一个主题类型,但肯定不是谨慎的风格信息。

        6
  •  0
  •   Mike Woodhouse    16 年前

    100%同意重构,将显示决策提交给表示层(或尽可能接近表示层)。

    CASE ... END SQL仍然有其用途,不过,例如,我想计算国内客户所有订单总价值的百分比。我想我会很高兴的

    SELECT
      SUM(CASE domestic WHEN 'Y' THEN order_value ELSE 0 END) / SUM(order_value) AS pctg
    FROM orders
    

    作为一个查询。除非有人知道得更好,当然。