我在工作中经历了一些旧的存储过程并经常遇到
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)吗?这是速度的好习惯吗?是否应该返回普通值并且表示层决定应该做什么?
答案 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
作为查询。当然,除非有人知道更好。