数据库错误:您的 SQL 语法有错误;


Database ERROR:You have an error in your SQL syntax;

我正在做php开发,我得到了这样的错误

数据库错误:您的 SQL 语法有错误;请查看与您的 MySQL 服务器版本对应的手册,了解在")和 acid_event.sid IN(7, 8, 9, 20, 23, 24)' 在第 3 行

SELECT DISTINCT ip_src FROM acid_event
               WHERE timestamp >='2015-09-08 00:00:00' AND timestamp <='2015-09-08 23:59:59'
                AND acid_event.analyzed='N' AND (signature=2176) OR signature=70 OR signature=424 OR signature=927 OR signature=981 OR signature=19 OR signature=928 OR signature=1414 OR signature=289) AND acid_event.sid IN(7, 8, 9, 20, 23, 24)

如果我们把它隔开一点,我们可以很容易地看到错误

SELECT DISTINCT ip_src FROM acid_event
    WHERE timestamp >='2015-09-08 00:00:00' AND timestamp <='2015-09-08 23:59:59'
        AND acid_event.analyzed='N' 
        AND (signature=2176) <----- Remove this bracket as it closes to early
        OR signature=70 
        OR signature=424 
        OR signature=927 
        OR signature=981 
        OR signature=19 
        OR signature=928 
        OR signature=1414 
        OR signature=289) 
        AND acid_event.sid IN(7, 8, 9, 20, 23, 24)

删除该括号;)

只需再次阅读您的代码,最简单的方法是再次使用另一个 IN 语句,因此您希望查询如下所示:

SELECT DISTINCT ip_src FROM acid_event
    WHERE timestamp >='2015-09-08 00:00:00' AND timestamp <='2015-09-08 23:59:59'
        AND acid_event.analyzed='N' 
        AND signature IN(2176, 70, 424, 927, 981, 19, 928, 1414, 289)
        AND acid_event.sid IN(7, 8, 9, 20, 23, 24)

您可以执行以下操作:

    for ( $i=1;$i<=$nummansigs;$i++) 
    {
        $sql = "SELECT sig_id FROM signature WHERE sig_sid=".$sigsid[$i];
        $idresult = $db->acidExecute($sql);
        $mansig = "IN ("
        while ( $idrow = $idresult->acidFetchRow() )
        {
          $mansig = $mansig . "{$idrow[0]}, ";
         }
         $idresult->acidFreeRows();
    }
    $mansig = trim($mansig, ", ")
     $mansig = $mansig.")";

虽然,你还没有发布所有代码,所以我不知道它实际上是如何工作的。

在最终 SQL 中,右括号比左括号多。从您提供的部分代码中不清楚为什么会发生这种情况。

但是,我建议简化您构建的 SQL,以便它产生类似以下内容:

SELECT DISTINCT ip_src FROM acid_event
WHERE timestamp >='2015-09-08 00:00:00' AND timestamp <='2015-09-08 23:59:59'
AND acid_event.analyzed='N' 
AND signature IN (2176, 70, 424, 927, 981, 19, 928, 1414, 289)
AND acid_event.sid IN(7, 8, 9, 20, 23, 24)

这可以使用这个更简单的代码来完成,该代码首先收集数组$list中的值,然后将其转换为signature IN (...)语法:

if ( $isman ) {
    $list = array();
    for ( $i=1;$i<=$nummansigs;$i++) {
        // get the sig_ids for the first manadatory signature
        $sql = "SELECT sig_id FROM signature WHERE sig_sid=".$sigsid[$i];
        $idresult = $db->acidExecute($sql);
        while ( $idrow = $idresult->acidFetchRow() ) {
            $list[] = $idrow[0];
        }
        $idresult->acidFreeRows();
    }
    $mansig = "";
    if (count($list)) {
        $mansig = " AND signature IN (" . implode(",", $list) . ") ";
    }
    $notmansig = str_replace(" IN ", " NOT IN ", $mansig);
}

代码也可以改进为不在每个 for 循环迭代中执行新查询,但我会把优化留给你。原理是相同的:尝试使用sig_sid IN (...list of sids...)条件执行一个查询,以便一次性获得所有必要的值。

您的查询在签名=289时未打开")")。删除")"或添加开头"("