MySQL 8.0.34升级后SQL查询语法错误修复求助
问题修复:MySQL 8.0升级后SQL语法错误
错误分析
从报错信息可见生成的SQL存在明显语法问题:
SELECT SUM(p.investment_capital) AS abc FROM `tbl_product_order o LEFT JOIN tbl_package_master p ON p`.`id =` `o`.`package_id` WHERE `o`.`status` = 3 AND `o`.`user_id` = '278'
核心问题是CodeIgniter的from()方法自动添加反引号时破坏了JOIN语句:你在table参数中传入了包含JOIN的完整语句,但框架会错误地给中间的关键字加反引号,导致SQL语法失效。另外手动拼接WHERE参数的方式不仅易出错,还存在SQL注入风险。
修复方案
方案1:直接重构getTotalInvested函数(推荐)
放弃使用有缺陷的通用getSelectedOneField,改用CodeIgniter查询构造器原生写法,彻底避免语法错误:
function getTotalInvested($user_id=0) { $total_invested = 0; // 用查询构造器构建安全的LEFT JOIN查询 $this->CI->db->select_sum('p.investment_capital', 'abc'); $this->CI->db->from('tbl_product_order o'); $this->CI->db->join('tbl_package_master p', 'p.id = o.package_id', 'left'); $this->CI->db->where('o.status', 3); $this->CI->db->where('o.user_id', $user_id); $query = $this->CI->db->get(); // 先判断查询是否执行成功 if (!$query) { return CURRENCY . number_format(0, 2); } $result = $query->row_array(); if (!empty($result['abc'])) { $total_invested = $result['abc']; } return CURRENCY . number_format($total_invested, 2); }
方案2:修复通用getSelectedOneField函数
如果需要保留通用函数,调整参数逻辑,拆分JOIN和WHERE的传递方式,避免框架错误加反引号:
function getSelectedOneField($select, $table, $join = [], $where = []) { $this->CI->db->select($select); $this->CI->db->from($table); // 单独处理JOIN语句 if (!empty($join)) { foreach ($join as $item) { $this->CI->db->join($item['table'], $item['on'], $item['type'] ?? 'inner'); } } // 用数组传递WHERE条件,避免注入和语法错误 if (!empty($where)) { $this->CI->db->where($where); } $query = $this->CI->db->get(); if (!$query) { return null; } $result = $query->row_array(); if ($result) { // 处理带AS的查询字段,取别名而非原表达式 $select_parts = explode(' AS ', $select); $key = end($select_parts); return $result[$key]; } return null; } // 调用方式修改为: function getTotalInvested($user_id=0) { $total_invested = 0; $join_config = [ [ 'table' => 'tbl_package_master p', 'on' => 'p.id = o.package_id', 'type' => 'left' ] ]; $where_config = [ 'o.status' => 3, 'o.user_id' => $user_id ]; $total_invested = $this->getSelectedOneField("SUM(p.investment_capital) AS abc", "tbl_product_order o", $join_config, $where_config); return CURRENCY . number_format($total_invested ?: 0, 2); }
额外优化点
- 移除
@错误抑制符,通过显式空值判断避免number_format报错,便于排查潜在问题 - 使用查询构造器的数组式WHERE参数,彻底规避SQL注入风险,符合MySQL 8.0的安全规范
内容的提问来源于stack exchange,提问作者Zac Ang
相关产品推荐
相关产品推荐

