CodeIgniter 3.0.0 where_not_in仅在查询

时间:2015-07-15 00:16:45

标签: php mysql codeigniter mysqli codeigniter-3

我将当前的CodeIgniter网站从版本2.1.4更新到3.0.0,并且我按照CodeIgniter's site上列出的文档从mysql更新了我的数据库驱动程序到mysqli。每当我尝试排除某些产品和特定品牌时,我的网站都会为我的MySQL数据库运行MySQL语法错误......

$this->db->where_not_in('product_tbl.productID', $voidProducts);
$this->db->where_not_in('product_tbl.brand', $voidBrands);

这似乎会在生成的查询中围绕NOT参数产生额外的反引号(`),如下所示......

SELECT * FROM `product_tbl` WHERE collection IS NOT NULL AND `product_tbl`.`productID` NOT IN('1', '2', '3', '4') AND product_tbl.brand `NOT` IN('brand1', 'brand2', 'brand3') GROUP BY `collection` ORDER BY `collection` ASC 

如果我尝试直接在MySQL数据库上运行SQL查询,只要我从与products_tbl.brand列关联的NOT中取出反引号就可以正常工作。

我有相同的where_not_in功能来过滤掉这家商店可能不想特别展示的任何特定产品,并且工作正常。这个问题似乎只发生在品牌专栏上。我尝试将它们放在不同的顺序中,品牌列仍然会产生相同的错误,而productID列则没有。我尝试将品牌where_not_in声明评论出来,并且当它再次搜索品牌时它会在其他模型上出现故障,它会在品牌列上运行相同的错误,而不是在任何其他列上我可能会将事情分开where_not_in。

我不确定该问题中哪些内容甚至可以完全包含哪些内容会对您有所帮助,但请让我知道还应该包含哪些内容来帮助解决此问题。非常感谢任何帮助,谢谢!

TLDR:where_not_in();对于CodeIgniter 3中的特定列,在NOT上产生额外的反引号。

2 个答案:

答案 0 :(得分:0)

更新到3.0.1似乎摆脱了这个和其他问题 http://forum.codeigniter.com/thread-62548.html

答案 1 :(得分:0)

更新到3.0.1应解决此问题(如@JuanitoMint所述)

但是,如果出于某种原因,您无法更新到3.0.1(在我写这个答案时仍然在RC2上),您可以解决此问题:

修改system/database/DB_query_builder.php,在第2355行(函数_compile_wh),添加:

// temporal fix (has already been fixed in 3.0.1)
if($matches[2] == 'NOT'){
    continue;
}

这就是整个功能的样子:

// --------------------------------------------------------------------

    /**
     * Compile WHERE, HAVING statements
     *
     * Escapes identifiers in WHERE and HAVING statements at execution time.
     *
     * Required so that aliases are tracked properly, regardless of wether
     * where(), or_where(), having(), or_having are called prior to from(),
     * join() and dbprefix is added only if needed.
     *
     * @param   string  $qb_key 'qb_where' or 'qb_having'
     * @return  string  SQL statement
     */
    protected function _compile_wh($qb_key)
    {
        if (count($this->$qb_key) > 0)
        {
            for ($i = 0, $c = count($this->$qb_key); $i < $c; $i++)
            {
                // Is this condition already compiled?
                if (is_string($this->{$qb_key}[$i]))
                {
                    continue;
                }
                elseif ($this->{$qb_key}[$i]['escape'] === FALSE)
                {
                    $this->{$qb_key}[$i] = $this->{$qb_key}[$i]['condition'];
                    continue;
                }

                // Split multiple conditions
                $conditions = preg_split(
                    '/(\s*AND\s+|\s*OR\s+)/i',
                    $this->{$qb_key}[$i]['condition'],
                    -1,
                    PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY
                );

                for ($ci = 0, $cc = count($conditions); $ci < $cc; $ci++)
                {
                    if (($op = $this->_get_operator($conditions[$ci])) === FALSE
                        OR ! preg_match('/^(\(?)(.*)('.preg_quote($op, '/').')\s*(.*(?<!\)))?(\)?)$/i', $conditions[$ci], $matches))
                    {
                        continue;
                    }

                    // $matches = array(
                    //  0 => '(test <= foo)',   /* the whole thing */
                    //  1 => '(',       /* optional */
                    //  2 => 'test',        /* the field name */
                    //  3 => ' <= ',        /* $op */
                    //  4 => 'foo',     /* optional, if $op is e.g. 'IS NULL' */
                    //  5 => ')'        /* optional */
                    // );

                    if ( ! empty($matches[4]))
                    {
                        $this->_is_literal($matches[4]) OR $matches[4] = $this->protect_identifiers(trim($matches[4]));
                        $matches[4] = ' '.$matches[4];
                    }
                    // temporal fix (has already been fixed in 3.0.1)
                    if($matches[2] == 'NOT'){
                        continue;
                    }

                    $conditions[$ci] = $matches[1].$this->protect_identifiers(trim($matches[2]))
                        .' '.trim($matches[3]).$matches[4].$matches[5];
                }

                $this->{$qb_key}[$i] = implode('', $conditions);
            }

            return ($qb_key === 'qb_having' ? "\nHAVING " : "\nWHERE ")
                .implode("\n", $this->$qb_key);
        }

        return '';
    }

注意:最好更新到3.0.1,除非您有非常具体的理由不更新。