【问题标题】:Codeigniter DB select logic errorCodeigniter 数据库选择逻辑错误
【发布时间】:2013-01-24 01:18:49
【问题描述】:

在我的数据库中,我有一堆产品。在我的产品表中,我有一个名为 active 的列,默认为 1(这意味着它是“活动的”)当我删除产品而不是删除行时,我只是将活动列更改为 0

我还有一个搜索功能,可以按名称或描述等搜索产品。我使用 codeigniter 作为框架。这是生成查询的代码:

$search_query = $this->db->from('company_products')
->where('company_products.active', 1)
->or_like(array('name'=> $keywords, 'model'=> $keywords, 'brand'=> $keywords, 'description'=> $keywords))
->order_by('id', 'RANDOM')
->get();

这段代码生成这个mysql查询:

SELECT `company_products`.*
FROM (`company_products`)
WHERE `company_products`.`active` =  1
AND  `name`  LIKE '%chair%'
OR  `model`  LIKE '%chair%'
OR  `brand`  LIKE '%chair%'
OR  `description`  LIKE '%chair%'

“删除”产品(将活动列更改为 0)后,该产品仍会显示在搜索结果中。这就是我怀疑代码上发生的事情:

(SELECT a product WHERE active = 1 - AND - name LIKE %search_string%) 
 - OR - 
(SELECT a product WHERE model LIKE %search_string%)
 - OR - 
(SELECT a product WHERE brand LIKE %search_string%)
 - OR - 
(SELECT a product WHERE description LIKE %search_string%)

但这就是我想要的:

(SELECT a product WHERE active = 1) 

 - AND - 

{ (SELECT a product WHERE model LIKE %search_string%) 
- OR - 
(SELECT a product WHERE model LIKE %search_string%) 
- OR - 
(SELECT a product WHERE brand LIKE %search_string%) 
- OR - 
(SELECT a product WHERE description LIKE %search_string%) }

我希望我的伪代码不会太混乱。我想使用 codeigniter 的活动记录类来完成此操作。

【问题讨论】:

    标签: php mysql sql codeigniter


    【解决方案1】:

    活动记录不会单独执行此操作,您需要将它们分组,否则它们将作为或针对查询的整个 where 部分工作。您需要手动在复杂查询中构建 WHERE 语句,就个人而言,在这些情况下,我根本不关心活动记录,但如果您真的想使用它,您可以这样做:

    $where = "`company_products`.`active` =  1 AND (`name`  LIKE '%$keywords%' 
    OR `model`  LIKE '%$keywords%' OR `brand`  LIKE '%$keywords%' OR 
    `description`  LIKE '%$keywords%')";
    $search_query = $this->db->from('company_products')
    ->where($where)
    ->order_by('id', 'RANDOM')
    ->get();
    

    【讨论】:

    • 您会为安全做些什么?转义$关键字? htmlspecialchars?我喜欢活动记录,因为它预先存在针对 SQL 注入等的安全性。
    • 我可能是错的,但我相信,因为活动记录仍在构建查询,它仍然会像您使用以前的方式一样被转义。
    【解决方案2】:

    使用括号:

    SELECT `company_products`.*
    FROM (`company_products`)
    WHERE `company_products`.`active` =  1
    AND  (`name`  LIKE '%chair%'
     OR  `model`  LIKE '%chair%'
     OR  `brand`  LIKE '%chair%'
     OR  `description`  LIKE '%chair%')
    

    阅读 MySQL 中的 Operator Precedence(基本上它适用于所有 RDBMS)

    【讨论】:

    • 他说他想继续使用 CI 的活动记录来做他的查询。
    • 我认为 CI 应该允许以某种方式对条件进行分组。许多其他查询生成器允许这样做
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多