忽略DB2 SELECT语句中的某些字符

时间:2014-01-06 15:18:36

标签: php sql regex ibm-midrange db2-400

在网站中构建文本搜索时,我将其传递给PHP循环:

$queryList=explode(' ', $queryString);
foreach ($queryList as $queryParm) {
    foreach ($fields as $key => $query) {
        $whereStr.=($key == 0) ? " AND (ucase($query) LIKE ?" : " OR ucase($query) LIKE ?";
        $db->parms[]="%$queryParm%";
        if ($key+1 == count($fields)) $whereStr.=")";
    }
}

这将分隔查询的单词并使每个单词成为一个单独的参数。我正在构建一个只允许使用字母数字和空格的正则表达式,但现在问题是我需要SQL来匹配这个正则表达式,例如,如果有一个名为“ FakeCo的Unicorn Repellant#123 ”的项目,那么搜索“ fakecos unicorn repellant 123 ”应该产生结果,而忽略了“'”和“#”存在的事实。实际上由于列表“ 123 fakeco ”的结构也应该显示结果。

有没有办法将正则表达式应用于DB2语句?

这是针对DB2 for i(版本7.1)

运行的

编辑:尝试解决方案(在上面提到的PHP之前插入),一些字符导致问题&不得不被删除,当它运行时表现不佳

$sqlNeedsEscape=array("?", "'");
$ignoreChars="'\"?~!@#$%^&*()-=+[]{}|<>,./\\";
$ignoreChars=str_split($ignoreChars);
$whereBefore='';
$whereAfter='';
foreach ($ignoreChars as &$ic) {
    if (in_array($ic, $sqlNeedsEscape)) $ic="'$ic";
    error_log($ic);
    $whereBefore.="replace(";
    $whereAfter.=",'$ic','')";
}

然后将$whereStr.=行更改为:

$whereStr.=($key == 0) ? " AND (ucase(trim($whereBefore $query $whereAfter)) LIKE ?" : " OR $whereBefore ucase(trim($query)) $whereAfter LIKE ?";

实际上它是替换(替换(查询,'!',''),'@',''),'#','')每个字段,只包括几个替换。当我看到它对性能的影响时,我不再追逐这个想法了。我将与我们的RPG开发者讨论Buck Calabro建议的UDF解决方案。这听起来像是唯一可能的“真正”解决方案。

4 个答案:

答案 0 :(得分:2)

DB2 for i LIKE predicate不支持正则表达式。

答案 1 :(得分:2)

正如@JamesA所指出的,从7.1开始,WHERE子句中不支持正则表达式。这并不意味着某人没有编写用户定义函数来实现一个。 Dennis Lovelady在http://archive.midrange.com/midrange-l/201209/msg00810.html的Midrange dot com邮件列表上分享了他的想法。它是用RPG编写的,所以你需要让一个IBM i程序员为你加载它。因为这是一个UDF,所以数据库优化器不能使用索引,因此以这种方式完成的查询并不像人们预期的那样高效。

答案 2 :(得分:1)

由于您正在处理IBM i 7.1版,因此IMO的最佳解决方案是加载DB2 Omnifind Text Search Server(5733-OMF)产品......

简而言之,Omnifind提供&#34;高速语言文本搜索&#34 ;;所以搜索鼠标不仅可以找到包含鼠标的东西,还可以找到任何包含鼠标的东西。

http://pic.dhe.ibm.com/infocenter/iseries/v7r1m0/index.jsp?topic=%2Frzash%2Frzashkickoff.htm http://www-304.ibm.com/partnerworld/wps/servlet/ContentHandler/whitepaper/i/omnifind/search

这是一种免费许可产品。请注意,它也适用于6.1。

除了提供CONTAINS()函数之外,还有一个SCORE()函数,可以对搜索结果进行排名。

在6.1之前,IBM提供了一种称为(DB2 Extender)文本搜索引擎(5770-DE1)的收费产品,该产品具有许多相同的功能,但使用效果不佳。

HTH,

查尔斯

答案 3 :(得分:0)