重写这个超长的查询

Rewrite this exceedingly long query

我刚刚在我们的代码中偶然发现了这个 gem:

my $str_rep="lower(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(field,'-',''),'',''),'.',''),'_',''),'+',''),',',''),':',''),';',''),'/',''),'|',''),'\',''),'*',''),'~','')) like lower('%var%')";

我不是真正的数据库专家,但我有预感可以用更理智的方式重写它。可以吗?

抱歉,我不懂相关语言,但我想到了一些事情。

首先,您可以寻找一个替换文本功能,它不仅可以替换单个字符。许多语言都有它们。有些还进行基于正则表达式的查找和替换。

其次,代码看起来像是在尝试去除特定的字符列表。此列表可能不包括所有必要的内容,这意味着相对较高的(屁股上的痛苦)维护问题。一个更简单的解决方案可能是反转问题并询问您要保留哪些字符?像这样反转有时会产生更简单的解决方案。

您将其标记为 Perl,但它可能不是?

这里有一个 Perl 解决方案:

$var =~ s/[\-\.\_\+\,\:\;\/\|\\*\~]+//g;

这取决于您使用的 DBMS。我将 post 一些示例(请随意编辑此答案以添加更多示例)。

MySQL

真的没什么可做的;替换所有字符的唯一方法是嵌套 REPLACE 函数,因为它已经在您的代码中完成。

甲骨文数据库

可以使用 TRANSLATE 函数重写您的子句。

SQL 服务器

与 MySQL 一样,没有任何类似于 Oracle TRANSLATE 的功能。我在 this question 的答案中找到了一些(更长的)替代方案。然而,一般来说,查询会变得很长。我看不出这样做有什么真正的好处,除了可以轻松扩展更结构化的查询。

火鸟

根据 Mark Rotteveel 的建议,您可以使用 SIMILAR TO 重写整个子句。

如果允许您通过 Perl 构建查询字符串,您还可以对包含所有特殊字符的数组使用 for 循环。

编辑:抱歉,我没有看到您在标签中指出了数据库。只考虑我回答的最后一部分。