【问题标题】:LTRIM / RTRIM - But only where First/Last character is a space?LTRIM / RTRIM - 但只有第一个/最后一个字符是空格?
【发布时间】:2017-09-14 21:57:39
【问题描述】:

不确定我还能在哪里问这个...但我正在查看我们系统中的一些代码,并在我们的一个数据清理过程中遇到了这个...

UPDATE #X SET
     Email = CASE
                 WHEN LEFT(Email, 1) = ' ' OR RIGHT(Email, 1) = ' '
                 THEN LTRIM(RTRIM(Email))
                 ELSE Email
             END

这对我来说似乎毫无意义,不知道为什么不写成:

UPDATE #X SET Email = LTRIM(RTRIM(Email))

是否有一些我不知道的好处或者可能是一些数据问题,比如隐式转换错误或它正在避免的事情?有很多像这样的不必要的代码,我想开始清理。

没有明显的时间节省。我运行了 Statistics IO 和 Time 以及查询计划,它们都是相同的。

【问题讨论】:

  • 请注意,大多数排序规则中的尾随空格被忽略以进行比较

标签: sql sql-server tsql query-optimization


【解决方案1】:

这毫无意义,但出于不同的原因。大概应该写成:

UPDATE #X
    SET Email = LTRIM(RTRIM(Email))
    WHERE Email LIKE ' %' OR EMAIL LIKE '% ';

如果值不会改变,则没有理由尝试更新。

注意事项:

  • SET 真的应该放在设置值的第一行。好的,这是一种审美观点。
  • 我认为LIKE 在寻找空间方面更清楚。此外,它更强大,因为它可以查找字符组。而且,它可以是 sargable,允许使用索引(尽管在这种情况下不是)。

【讨论】:

  • 同意。这就是我计划编写它的方式……但是,我将把它扩展到空格、水平制表符、CR 和 LF。并且必须在那些上使用 Replace,因为 TRIM 函数只删除空格。
  • 是的,这篇文章的格式已更改。在 proc 中都是一行。
【解决方案2】:

此代码可能是为 2005 年之前的 SQL Server 版本编写的。在其中,Microsoft 已向 update 添加了优化,如果列的原始值与新列的值相同,则实际上会跳过修改一个(即没有进行实际更改)。在 2000 年及以前的版本中,所有受影响的行都被视为已更改,因此被放入事务日志中,从而使其膨胀。

但是,正如 Gordon 所指出的,即使在这种情况下,原作者也弄错了。条件应该已放入WHERE,因为case 不过滤任何行。所以是的,你是对的,这可以而且应该被清理。

附:如果您已经使用 2017 版本,那么终于可以使用 TRIM() 函数了,这实际上不仅仅是一个 ltrim(rtrim()) 等效函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-20
    • 2015-09-05
    相关资源
    最近更新 更多