幸福

如人饮水,冷暖自知

CodeIgniter 使用 concat 查询报错问题

应用场景:无限极分类

数据表字段:id(主键)、cate_name(分类名称)、pid(父级别ID)、path(路径)、add_time(添加时间)

在无限极分类中,对查询结果需要进行排序时,通常使用到MYSQL的函数“CONCAT”用以拼接字符,此前在TP中使用时未见异常,但在CI中却会报错,控制器中查询如下:

$result = $this->db
 ->select("id,cate_name,add_time,concat(path,'-',id) as bpath")
 ->where(array('type' => 1, 'pid' => 0)->order_by('bpath')
 ->get('test')

執行會報如下錯誤:
发生了一个数据库错误
Error Number: 1064You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘FROM (`test`)WHERE `type` =  1AND `pid` =  0ORDER BY `b’ at line 2SELECT `id`, `cate_name`, `add_time`, concat(path, `’-‘`, `id)` as bpathFROM (`test`)WHERE `type` =  1AND `pid` =  0ORDER BY `bpath` LIMIT 1

看到錯誤提示,很明顯會發現如下錯誤

concat(path, `’-‘`, `id)` as bpath
首先“-”被轉義成了`’-‘`,其次“id”被轉義成了“`id)`”,這樣看來SQL執行不報錯才怪呢。

第一次遇到這樣的錯誤,我亦在網上搜尋,然尋求解決方法無果,但也看到了類似老外網友的提問,地址如下:

http://stackoverflow.com/questions/4623958/concat-in-php-codeigniter/4623968

WechatIMG161.jpeg

如圖解答中,僅是在“CONCAT”拼接之後,添加了一個“FALSE”,這樣貌似無益於問題的解決。終極解決方法看來只有看CI中執行是哪一步錯了,上面已提及查詢錯誤是因為

$this->db->select("id,cate_name,add_time,concat(path,'-',id) as bpath")
被轉義成了:SELECT `id`, `cate_name`, `add_time`, concat(path, `'-'`, `id)` as bpath

就從此處找起,這裡調用的是CI的“select”方法,該方法存在于下面的文件中第79行:

E:\wamp\www\CodeIgniter\system\database\DB_active_rec.php

原生寫法如下:

public function select($select = '*', $escape = NULL)
{
    if (is_string($select)) {
        $select = explode(',', $select);
    }

默認查詢的字段都是用“,”連接的,這裡可以看到“select”方法是對查詢的字符用“,”進行分割,使其成為一個數組,那麼原先的查詢中使用的“concat(path,'-',id) as bpath”也是包含“,”的,所以問題就出在這裡,打印出分割后的數組如下:

[ar_select] => Array(
    [0] => id            
    [1] => cate_name           
    [2] => add_time            
    [3] => concat(path            
    [4] => '-'            
    [5] => id) as bpath
)

所以為了避免這樣的錯誤,我對“select”方法進行了改進,如下:

public function select($select = '*', $escape = NULL)
{
    if (is_string($select)) {
        if (preg_match("/(#)/", $select)) {
            $select = explode('#', $select);
        } else {
            $select = explode(',', $select);
        }
    }

是為了避免直接籠統的用“,”進行統一分割,而是採用了正則進行匹配,若要查詢的字段中連接字符包含“#”號時,則使用“#”進行分割,否則使用“,”進行分割,那麼在查詢時,需要使用MYSQ函數“CONCAT”的地方,多個字段就不要用“,”進行連接了,改為如下:
$this->db->select("id#cate_name#add_time#concat(path,'-',id) as bpath")
再次打印“select”查詢結果如下:
[ar_select] => Array (            
    [0] => id            
    [1] => cate_name            
    [2] => add_time            
    [3] => concat(path,-,id) as bpath        
)

這樣就正常了,由此完美解決!


去打赏

您的支持将鼓励我们继续创作!

[微信] 扫描二维码打赏

[支付宝] 扫描二维码打赏

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注