多个REGEX值在SQL中不起作用

时间:2015-04-16 07:59:24

标签: php mysql

我为自己的网站创建了动态查询。查询是使用以下完成的:

$sql='SELECT CONCAT(issues.type,"0",issues.kbid) as KBID,issue_tasks.PARENTID as Parent,issues.issuesummary as Summary,products.productdescription as Product,organizations.shortname as Organization,issue_priorities.description as Priority,date_format(issues.createddate, "%d/%m/%Y") as Reported,date_format(issues.lastupdated, "%d/%m/%Y") as Updated,issue_status.statusdescription as Status,issue_resolutions.resdescription as Resolution,users.logon as Assigned FROM issues
        INNER JOIN issue_priorities ON issue_priorities.VALUE = issues.PRIORITY - 1 
        INNER JOIN issue_resolutions ON issue_resolutions.RESID = issues.RESOLUTION 
        INNER JOIN users ON users.ID = issues.ASSIGNEDUSERID
        INNER JOIN products ON products.PRODUCTID = issues.PRODUCTID
        INNER JOIN organizations ON organizations.orgid = issues.creatingorg
        INNER JOIN issue_status ON issue_status.STATUSID = issues.STATUS
        LEFT JOIN issue_tasks ON issue_tasks.CHILDID = issues.KBID
        WHERE ';

if(isset($_SESSION['summ']))
{
$sql.= sprintf('issues.issuesummary REGEXP "%s"', implode('|', $words));
}

编辑:我的完整SQL查询:

SELECT CONCAT(issues.type,"0",issues.kbid) as KBID,issue_tasks.PARENTID as Parent,issues.issuesummary as Summary,products.productdescription as Product,organizations.shortname as Organization,issue_priorities.description as Priority,date_format(issues.createddate, "%d/%m/%Y") as Reported,date_format(issues.lastupdated, "%d/%m/%Y") as Updated,issue_status.statusdescription as Status,issue_resolutions.resdescription as Resolution,users.logon as Assigned FROM issues INNER JOIN issue_priorities ON issue_priorities.VALUE = issues.PRIORITY - 1 INNER JOIN issue_resolutions ON issue_resolutions.RESID = issues.RESOLUTION INNER JOIN users ON users.ID = issues.ASSIGNEDUSERID INNER JOIN products ON products.PRODUCTID = issues.PRODUCTID INNER JOIN organizations ON organizations.orgid = issues.creatingorg INNER JOIN issue_status ON issue_status.STATUSID = issues.STATUS LEFT JOIN issue_tasks ON issue_tasks.CHILDID = issues.KBID WHERE issues.issuesummary REGEXP "sabre|rtf"

但我不断收到错误:

  

SQLSTATE [42000]:语法错误或访问冲突:1139从regexpSQLSTATE [42000]收到错误'empty(sub)expression':语法错误或访问冲突:1139从regexp获得错误'empty(sub)expression'无法执行查询!!!

我不知道为什么我会在这里遇到封装错误。

2 个答案:

答案 0 :(得分:1)

假设$words包含您要在正则表达式中使用的单词,可以简化代码:

if (isset($_SESSION['summ']) && count($words)) {
    $sql .= sprintf('issues.issuesummary REGEXP "%s"', implode('|', $words);
}

答案 1 :(得分:1)

您遇到的错误ER_REGEXP_ERROR是MySQL服务器在您提供的正则表达式模式无法解析时生成的错误。换句话说,你的正则表达式在语法上是不正确的。

在您的特定情况下给出的消息“ empty(sub)expression ”表明正则表达式包含一个空的子表达式。如果没有看到代码生成的最终正则表达式,则无法确定 - 但由于您将多个子表达式与|交替运算符组合在一起,因此可以合理地猜测这些子表达式中的一个或多个是空:如果$words数组的至少一个元素是(converted to)空字符串'',则会发生这种情况。

所有这些都说明了,为什么你在这里使用正则表达式并不清楚。如果$words包含正则表达式模式,那么它可能是一种合理的方法 - 尽管在这种情况下,在加入它们时,应该将每个子表达式放在括号中(以避免任何优先级低于交替使用的运算符)你的意图)。另一方面,如果$words只包含您希望完全匹配的文字值,那么MySQL的IN()运算符将更有效,更恰当和正确:

WHERE issues.issuesummary IN ('abc', 'xyz', ...)

这可以通过以下PHP代码实现:

$sql .= "issues.issuesummary IN ('".implode("','", $words)."')";

但请注意,$words的元素必须首先转义,以避免出现某些字符的错误(这也会导致SQL注入漏洞)!更好的是,你可以参数化每个文字。

如何处理这些事情取决于您使用的MySQL API - 因为您未在问题中指出任何内容,我认为具体示例超出了此答案的范围。