Codeigniter使用子查询将选择的输出传递到另一个选择的IN子句

时间:2018-12-08 06:52:12

标签: codeigniter activerecord subquery codeigniter-3

我想利用Codeigniter中Active Record的自我安全性。

要求是:

  1. 根据某些条件从第一个表中获取一些序列号
  2. 然后根据一些复杂的标准检查第二个表中有哪些序列号。
  3. 最后显示第一个表的结果,第二个表的结果集中不存在。

我在CI中有以下代码:

$this->db->select('sno');
$this->db->from('table1');
$this->db->where("cid",$cid);
$subquery=$this->db->get_compiled_select();

$this->db->select("pid")->from("table2");
$this->db->group_start();
    $this->db->group_start();
        $this->db->where("col1 <",$cin);
        $this->db->where("col2 >",$cin);
    $this->db->group_end();
    $this->db->or_group_start();
        $this->db->where("col1 <",$cout);
        $this->db->where("col2 >",$cout);
    $this->db->group_end();
    $this->db->or_group_start();
        $this->db->where("col1 >",$cin);
        $this->db->where("col1 <",$cout);
    $this->db->group_end();
    $this->db->or_group_start();
        $this->db->where("col1",$cin);
        $this->db->or_where("col2",$cout);
        $this->db->or_where("col1",$cout);
        $this->db->or_where("col2",$cin);
    $this->db->group_end();
    $this->db->or_group_start();
        $this->db->where("col2 >",$cin);
        $this->db->where("col2 <",$cout);
    $this->db->group_end();
$this->db->group_end();
$this->db->where_in("col3",$subquery);
$sbquery = $this->db->get_compiled_select();

    $this->db->from('table1');
    $this->db->where("tid",$cid);
    $this->db->where_not_in("cid",$sbquery);
    $result=$this->db->get_compiled_select();
    var_dump($result);
    exit;

此代码显示以下查询(作为var_dump的结果):

SELECT * FROM `table1` WHERE `tid` = '6' AND `cid` NOT IN('SELECT `pid`\nFROM `table2`\nWHERE (\n (\n`col1` < \'2018-12-10\'\nAND `col2` > \'2018-12-10\'\n )\nOR (\n`col1` < \'2018-12-16\'\nAND `col2` > \'2018-12-16\'\n )\nOR (\n`col1` > \'2018-12-10\'\nAND `col1` < \'2018-12-16\'\n )\nOR (\n`col1` = \'2018-12-10\'\nOR `col2` = \'2018-12-16\'\nOR `col1` = \'2018-12-16\'\nOR `col2` = \'2018-12-10\'\n )\nOR (\n`col2` > \'2018-12-10\'\nAND `col2` < \'2018-12-16\'\n )\n )\nAND `col3` IN(\'SELECT `sno`\\nFROM `table1`\\nWHERE `cid` = \\\'6\\\'\')')

当我使用以下代码(最后三行代码)时,这将导致错误的结果:

$result=$this->db->get()->result();
var_dump($result);
exit;

如果我直接在SQL中命中相同的查询,则会得到相同的错误结果。

但是,如果我删除斜杠,单引号,换行符和其他特殊字符,以直接在sql中命中重写的查询,我将获得非常准确的结果。

SELECT * FROM `table1` WHERE `tid` = '6' AND `cid` NOT IN(SELECT `pid` FROM `table2` WHERE ((`col1` < '2018-12-10' AND `col2` > '2018-12-10') OR (`col1` < '2018-12-16' AND `col2` > '2018-12-16') OR (`col1` > '2018-12-10' AND `col1` < '2018-12-16') OR (`col1` = '2018-12-10' OR `col2` = '2018-12-16' OR `col1` = '2018-12-16' OR `col2` = '2018-12-10') OR (`col2` > '2018-12-10' AND `col2` < '2018-12-16')) AND `col3` IN(SELECT `sno` FROM `table1` WHERE `cid` = '6'))

请提出解决方案。

1 个答案:

答案 0 :(得分:1)

在活动记录子查询上添加FALSE作为第三个参数,以使语句不会被转义。
从更改:

$this->db->where_in("col3",$subquery);
...
$this->db->where_not_in("cid",$sbquery);

至:

$this->db->where_in("col3",$subquery,FALSE);
...
$this->db->where_not_in("cid",$sbquery,FALSE);