【问题标题】:Remove single quotes from where_in in codeigniter从 codeigniter 中的 where_in 中删除单引号
【发布时间】:2017-12-09 02:46:04
【问题描述】:

我正在开发search 功能。 我创建了一个搜索表单,用户可以在其中搜索基于TypeopeFormate 的应用程序。

我在 join 查询中使用了 子查询 来获得所需的结果。 我已经在MySQL Workbench 中测试了我的查询,它工作正常。

但是当我使用查询构建器技术在 Codeigniter 中尝试相同的查询时,我遇到了问题。

这是在工作台中运行良好的查询:

SELECT (*)
FROM `App`
LEFT JOIN `App_type` 
ON `App_type`.`app_id` = `App`.`id`
LEFT JOIN `App_formate` 
ON `App_formate`.`app_id` = `App`.`id`
WHERE `App`.`id` IN(select app_id FROM App_type WHERE type_id in (3,2,6) group by app_id HAVING COUNT(*) = 3)
AND `App_formate`.`formate_id` IN('1', '3')
AND `jobs`.`ope_min` <= '3'
AND `jobs`.`ope_max` >= '3'
GROUP BY `jobs`.`id`;

这是我使用的连接查询:

$subquery = "select app_id FROM App_type WHERE type_id in ($selected_type) group by app_id HAVING COUNT(*) = $type_count";

$search_app_query = $this->db
    ->select('*')
    ->from('App')
    ->join('App_type', 'App_type.app_id = App.id', 'left outer')
    ->join('App_formate', 'App_formate.app_id = App.id', 'left outer')      
    ->where_in('App.id',$subquery)  //<-- Here is the problem
    ->where_in('App_formate.formate_id',$data['selected_formates'])
    ->where('App.ope_min <=',$data['ope_value'])
    ->where('App.ope_max >=',$data['ope_value'])    
    ->group_by("App.id", "desc")
    ->get();

当我调试这个问题时,它显示了

 I have found the problem is in this part of the query:
 "WHERE `App`.`id` IN('select app_id 
 FROM App_type 
 WHERE type_id in (3,2,6) 
 group by app_id HAVING COUNT(*) = 3')"

此子查询中的单引号造成了问题。

到目前为止我所尝试的:

我试过删除这个单引号

  1. REPLACE($subquery, '''', '')
  2. -&gt;where_in('App.id',trim($subquery,"'"))
  3. $subquery_improved = substr($subquery, 1, -1);

但是所有这些解决方案都不起作用。他们没有删除单引号。

注意:我知道$this-&gt;db-&gt;query(),但不想使用它。

【问题讨论】:

  • 我不熟悉框架——尤其是如何将该子查询作为 实际子查询传递。 但是,如果文档没有明确说明,并且如果子查询的结果不是压倒性的,只需自行执行它并将结果传递到:where_in('App.id', $subquery_results)。我假设$subquery_results 需要是array
  • @svidgen 我知道 where_in 需要数组,但唯一的问题是$subquery 开头和结尾处的单引号,顺便感谢您的建议。
  • 尝试使用 echo $this->get_compiled_select() 并查看构建的查询是什么
  • 我已经做到了,我得到了问题所在但没有​​得到解决方案,我想我必须给它一个赏金。
  • 你可以试试where_in('App.id',$subquery)而不是where("App.id IN (".$subquery.")",NULL, false)

标签: php mysql codeigniter


【解决方案1】:

你的任务看起来很简单

而不是

->where_in('App.id',$subquery)  //<-- Here is the problem

你可以试试下面的

->where("App.id IN (".$subquery.")",NULL, false)

您可以在 Codeigniter 文档here(第 4 点和以下部分)中找到此确切信息。

【讨论】:

    【解决方案2】:

    我的方法类似于下面,以更通用的方式。我一直在尝试遵循 MVC 模式,同时打破小函数中的功能。虽然你没有分享你所有的代码,但我还是会推荐它。

    您应该将我的自定义名称更改为函数、数组等,使其与您的代码匹配。希望对您有所帮助。

    模型功能

    public function getApp_ids($selected_type, $type_count) {
       $subquery = "select app_id FROM App_type WHERE type_id in ($selected_type) group by app_id HAVING COUNT(*) = $type_count";
       $result = $subquery->get();
       if($result->num_rows() > 0) //the check here is relevant to your data
           return $result->result_array();
       return false;
    }
    

    模型函数

    public function searchApp($appIds, $data) {
      //$appIds and $data are parameters to this function. 
        $search_app_query = $this->db
           ->select('*')
           ->from('App')
           ->join('App_type', 'App_type.app_id = App.id', 'left outer')
           ->join('App_formate', 'App_formate.app_id = App.id', 'left outer')      
           ->where_in('App.id',$appIds)  //pass the array of your IDs
           ->where_in('App_formate.formate_id',$data['selected_formates'])
           ->where('App.ope_min <=',$data['ope_value'])
           ->where('App.ope_max >=',$data['ope_value'])    
           ->group_by("App.id", "desc")
           ->get();
    
        if($search_app_query->num_rows() > 0) //again, the check is yours
             return $search_app_query->result_array();
        return false;
    }
    

    在你的控制器中,像这样

    public function YOUR_FUNCTION($selected_type, $type_count) {
       //call this function from model to grab the app_id you want. Don't forget to pass the parameters you sql needs.
       $appIdsResult = $this->YOUR_MODEL->getApp_ids($selected_type, $type_count);
    
       //Manipulate your result in another array, so you can get rid off the indexes and do some checks if you want
       $appIds = array();
       foreach ($appIdsResult as $appId) {
           array_push($appIds, $appId['app_id']); //Check the index app_id, it is the result from your DB.
        }
    
        //Call searchApp from your model and pass the found $appIds and your $data ofcourse
        $result = $this->YOUR_MODEL->searchApp($appIds, $data);
        //In $result will be your answer
    }
    

    【讨论】:

    • 先生使用了子查询,因为在我的搜索表单中,我使用了用户的类型、格式和操作。那时,正如您建议的那样,我应该首先获取类型和 loopite,然后将其放入 whare_in 但先生,如果它那么简单,那么我将获得 50 赏金。
    • 对于Although you didn't share all of your code,请查看我对这个问题的所有编辑。它具有表结构和流程的所有相关信息
    • 我已经指定我只想删除那个单引号。只是。我没有发现我该如何描述使用过的连接,因为它是我正在做的最好的方式。 @ankitsuthar
    • 我想您已经尝试过我的解决方案但没有奏效。有时您必须退后一步,重新考虑您正在尝试做的事情,并将问题“转移”到下一层或上一层。简单与赏金无关紧要。您可以忽略、投反对票或只是不接受我的回答。试图帮助。和平。
    • @satafaka 如果您感到被冒犯,我深表歉意,但请理解我在问题中添加的问题只是一个问题,此查询是大项目的一小部分,执行您建议的更改将影响系统并对系统中的现有代码进行了太大的更改。如果您看到我的编辑,那么您会看到我已经解决了这个问题。我离我所想的解决方案只有一英寸的距离。所以你建议的技术和方法非常好,但这次没有奏效。谢谢先生的回答。
    【解决方案3】:

    替换此代码:

    ->where_in('App.id',$subquery)  //<-- Here is the problem
    

    使用此代码:

    ->where_in("App.id", $subquery, FALSE)
    

    第三个参数接受布尔值来确定函数是否应该转义值和标识符。当设置为 FALSE 时,它不使用单引号作为转义字符。

    希望这会有所帮助。

    【讨论】:

    • @always-a-learner 你试过我的解决方案了吗?我打印查询并且单引号消失了..你仍然在'where_in'函数中..
    • 你应该解释第三个参数的作用,以及link to the documentation
    【解决方案4】:

    使用手动查询(不安全,使用非常非常小心)

    $sql = "SELECT ....[Your Query].....":
    $query = $this->db->query($sql);
    if ($query->num_rows() > 0){
        // Found
    }else{
        // Not Found
    }
    

    【讨论】:

      【解决方案5】:

      //首先确认子查询如果子查询没有变化则只返回一个结果

      $subquery = "select GROUP_CONCAT(CONCAT(\"'\",app_id,\"'\")) FROM App_type WHERE type_id in ($selected_type) group by app_id HAVING COUNT(*) = $type_count";
      
      $search_app_query = $this->db
      ->select('*')
      ->from('App')
      ->join('App_type', 'App_type.app_id = App.id', 'left outer')
      ->join('App_formate', 'App_formate.app_id = App.id', 'left outer')      
      ->where_in('App.id',$subquery,false)  //<-- pass 3rd parameter as false for removing single quotes
      ->where_in('App_formate.formate_id',$data['selected_formates'])
      ->where('App.ope_min <=',$data['ope_value'])
      ->where('App.ope_max >=',$data['ope_value'])    
      ->group_by("App.id", "desc")
      ->get();
      

      【讨论】:

        【解决方案6】:

        我认为您的 $subquery 被视为参数字符串,而不是查询。
        活动记录方法的一般语法是

        ->where_in('field_name', array() || 'string values');
        

        $subquery必须是这样的

        $subquery = $this->db
                ->select('app_id')
                ->from('App_type')
                ->where_in('type_id',array(3,2,6))
                ->group_by('app_id')
                ->having(' COUNT(*) = 3')
                ->get()
                ->row()
                ->app_id;
        

        希望它会起作用:)

        【讨论】:

        • 正如我在问题中提到的那样,我得到 AND App_formate.formate_id IN('1', '3')` 完全符合 where_in 的预期,所以这不是问题。
        • 您的回答无济于事,但感谢 deepak 的建议。如果您想更深入,那么您会看到我编辑的内容以查看表格结构。
        【解决方案7】:

        代替

        SELECT (*)
        

        使用

        SELECT *
        

        代替

        WHERE `App`.`id` IN(
            select app_id FROM App_type
                WHERE type_id in (3,2,6) group by app_id HAVING COUNT(*) = 3)
        

        使用

        JOIN (
            select app_id FROM App_type
                WHERE type_id in (3,2,6) group by app_id HAVING COUNT(*) = 3
             ) AS x  ON x.app_id = App.id
        

        (翻译成 CodeIgniter 留给读者作为练习。)

        【讨论】:

          【解决方案8】:

          首先在查询之后,放上这段代码:

          echo $this->db->last_query();exit;

          这将打印查询,您将知道问题出在哪里。同时复制该查询并尝试在 phpmyadmin 中运行它。

          如果您遇到单引号问题,也可以尝试这种类型的解决方案:

          在子查询中使用单引号写入 $type_count,即 '$type_count'

          ->where("App.ope_min <='",$data['ope_value']."'")
          ->where("App.ope_max >='",$data['ope_value']."'")    
          ->group_by("App.id", "desc")
          ->get();
          

          如果您想问其他问题,请告诉我。

          【讨论】:

            【解决方案9】:

            只需在 where_in 语句中添加第三个参数。试试这个 -

            $subquery = "select app_id FROM app_type WHERE type_id in (3,2,6) group by app_id HAVING COUNT(*) = 3";
                $search_app_query = $this->db
                ->select('*')
                ->from('app')
                ->join('app_type', 'app_type.app_id = app.id', 'left outer')
                ->join('app_formate', 'app_formate.app_id = app.id', 'left outer')      
                ->where_in('app.id',$subquery, FALSE)  
                ->where_in('app_formate.formate_id',array(1,3))
                ->where('app.ope_min <=',3)
                ->where('app.ope_max >=',3)    
                ->group_by("app.id", "desc")
                ->get()->result();
            

            【讨论】:

            • 我会尽力回复您,先生。感谢您的建议。
            【解决方案10】:

            我建议您不要将子查询直接放在 where in 条件中,因为您有时也可能得到零结果。所以最好的方法是像这样单独执行你的子查询。

            $subdata = $this->db->select("app_id ")->from("App_type ")->where_in("type_id",$selected_type)->group_by(""app_id)->having("COUNT(*) = $type_count")->get()->result_array();
            
            $search_app_query = $this->db
                ->select('*')
                ->from('App')
                ->join('App_type', 'App_type.app_id = App.id', 'left outer')
                ->join('App_formate', 'App_formate.app_id = App.id', 'left outer');
            if(!empty($subdata)) {     
                $this->db->where_in('App.id',$subdata);
            }
                $this->db->where_in('App_formate.formate_id',$data['selected_formates'])
                ->where('App.ope_min <=',$data['ope_value'])
                ->where('App.ope_max >=',$data['ope_value'])    
                ->group_by("App.id", "desc")
                ->get(); 
            

            【讨论】:

              【解决方案11】:

              感谢大家的建议。

              我已经找到解决问题的方法,而无需更改其他代码。

              感谢sintakonte-SO user他的评论是解决这个问题的关键。

              解决方案只是更改我之前想要的一行代码。

              $search_app_query = $this->db
                  ->select('*')
                  ->from('App')
                  ->join('App_type', 'App_type.app_id = App.id', 'left outer')
                  ->join('App_formate', 'App_formate.app_id = App.id', 'left outer') 
              
                  // This is what he suggested me to change and it works. 
                  ->where('App.id IN('.$subquery.')')     
              
                  ->where_in('App_formate.formate_id',$data['selected_formates'])
                  ->where('App.ope_min <=',$data['ope_value'])
                  ->where('App.ope_max >=',$data['ope_value'])    
                  ->group_by("App.id", "desc")
                  ->get();
              

              再次感谢sintakonte-SO user

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2022-01-16
                • 1970-01-01
                • 1970-01-01
                • 2012-11-23
                • 1970-01-01
                • 1970-01-01
                • 2021-10-28
                • 2022-01-22
                相关资源
                最近更新 更多