SQL CASE语句与编程语言中的条件语句

时间:2009-01-28 14:17:18

标签: sql language-agnostic

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

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 个答案:

答案 0 :(得分:3)

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

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

-Edoode

我在下面查询了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));
        }
    }

}

答案 1 :(得分:2)

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

,该怎么办?

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

答案 2 :(得分:0)

  

任何人都可以提供任何有效的证据证明使用条件语句的SQL查询超过了其他语言(例如C#或Java)吗?这是速度的好习惯吗?是否应该返回普通值并且表示层决定应该做什么?

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

通常,如果数据库和演示文稿都是由一个人开发的,则无关紧要。当工作共享时,问题就开始了。在这种情况下,显然,您需要一份关于数据库发出的内容和ASP接受的合同。

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

答案 3 :(得分:0)

那是旧式代码,我不相信人们会再这样编码了(我们现在使用CSS)
您可能正在考虑一些很快将被重写或遗弃的遗留内容

答案 4 :(得分:0)

就SQL性能而言,如果您只返回几行(或者通过它的外观返回一行),那么影响最小,因为在案例之前评估语句的WHERE部分(仅对案例执行与where)匹配的行。

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

答案 5 :(得分:0)

100%同意重构以将显示决策放到表示层(或尽可能接近)。

SQL中的

CASE ... END仍然可以使用它,例如,我想要计算国内客户所有订单总价值的百分比。

我觉得我很满意
SELECT
  SUM(CASE domestic WHEN 'Y' THEN order_value ELSE 0 END) / SUM(order_value) AS pctg
FROM orders

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