以前我的所有查询都在CI 2.0版中正常运行,但当我升级到 2.0.3 时,我的一些SELECT查询被破坏了。
CI会自动添加反引号(``),但在旧版本中,它会按原样运行。
CI用户手册已指示在
中添加第二个参数DB->选择
as
FALSE
但它仍无效。
代码如下:
class Company_model extends MY_Model
{
----------------
$this->db->select(' count('.$fieldname. ') as num_stations');
$this->db->select(" CONCAT_WS(',', clb_company.address1, clb_company.address2, clb_company.city, clb_company.state, clb_company.zipcode ) as companyAddress");
$this->db->from($this->_table);
$this->db->join($this->_table_device, $fieldname1. " = ". $fieldname2, 'LEFT');
$this->db->where($blablafield , '0');
----------------
错误如下:
Error Number: 1064
You 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 (`clb_device`) JOIN `clb_company` ON `clb_company`.`id` = `clb_device`.`com' at line 2
SELECT `clb_device`.`id` as deviceId, `clb_pricing_specifications`.`name` as pricingSpecName, `clb_company`.`name` as companyName, `clb_device`.`mac_address` as deviceMacAddress,
`clb_device`.`reseller_model_number` as deviceModelNumber, `clb_pricing_spec_grouping`.`pricing_master_spec_id` as pricingSpecId, `clb_device`.`address` as deviceAddress,
`clb_device`.`is_home` as deviceIsHomeCharger, CONCAT(clb_company.portal_line1, `'/'`, `clb_device`.`name)` as deviceDisplayName FROM (`clb_device`) JOIN `clb_company`
ON `clb_company`.`id` = `clb_device`.`company_id` LEFT JOIN `clb_pricing_group_devices` ON `clb_device`.`id` = `clb_pricing_group_devices`.`device_id` and clb_pricing_group_devices.is_active = 1
LEFT JOIN `clb_pricing_spec_grouping` ON `clb_pricing_group_devices`.`pricing_spec_id` = `clb_pricing_spec_grouping`.`pricing_master_spec_id` LEFT JOIN `clb_pricing_specifications` ON
`clb_pricing_spec_grouping`.`pricing_spec_id` = `clb_pricing_specifications`.`id` WHERE clb_company.vendor_id is not null AND cast(substr(clb_devi
ce.software_version, 1, 3) as decimal(2,1)) > 2.0 AND clb_device.device_state > 0 GROUP BY `clb_device`.`id` ORDER BY CONCAT(trim(clb_company.portal_line1), `'/'`, trim(clb_device.name)) desc LIMIT 20
看看 CONCAT(trim(clb_company.portal_line1),`'/'`,trim(clb_device.name))
请建议解决方法。
答案 0 :(得分:31)
在查询之前使用此行:
$this->db->_protect_identifiers=false;
这将停止向构建的查询添加反引号。
答案 1 :(得分:15)
解决方案非常简单: 在数据库配置文件(./application/config/database.php)中,使用默认设置向阵列添加新元素。
$db['default']['_protect_identifiers']= FALSE;
这个解决方案对我而言更加优雅和专业。
答案 2 :(得分:7)
所有其他答案都很旧,这个答案适用于CI 2.1.4
// set this to false so that _protect_identifiers skips escaping:
$this->db->_protect_identifiers = FALSE;
// your order_by line:
$this -> db -> order_by('FIELD ( products.country_id, 2, 0, 1 )');
// important to set this back to TRUE or ALL of your queries from now on will be non-escaped:
$this->db->_protect_identifiers = TRUE;
答案 3 :(得分:3)
class Company_model extends MY_Model
{
----------------
$this->db->select(" count('$fieldname') as num_stations",false);
$this->db->select(" CONCAT_WS(',', clb_company.address1, clb_company.address2, clb_company.city, clb_company.state, clb_company.zipcode ) as companyAddress",false);
$this->db->from($this->_table);
$this->db->join($this->_table_device, $fieldname1. " = ". $fieldname2, 'LEFT');
$this->db->where($blablafield , '0');
----------------
您正在谈论的false
是需要什么,您可以尝试上面的代码并复制并粘贴给我们
echo $this->db->last_query();
这将向我们展示DB类正在创建的内容,我们可以看到什么是工作/什么不是。它可能是别的东西(你没有给出错误,因为有时sql错误会产生误导。)
来自docs:
$this->db->select()
接受可选的第二个参数。如果将其设置为FALSE
,CodeIgniter将不会尝试使用反引号来保护您的字段或表名。如果您需要复合选择语句,这非常有用。
答案 4 :(得分:2)
$this->db->query();
你会没事的,根据笔记,你应该安全地使用AD调用来禁用反引号(不知道为什么你说他们不工作,但我没有看到你的完整代码,所以我不能确定)
$this->db->select('(SELECT SUM(payments.amount) FROM payments WHERE payments.invoice_id=4') AS amount_paid', FALSE);
$query = $this->db->get('mytable');
确保FALSE
没有单引号(使其成为字符串),并且可能无法验证(未经我测试)。
答案 5 :(得分:1)
我认为你应该检查DB_driver.php文件,有一个名为protect_identifier的变量,关键是当你用旧版本的CI检查时,你会看到新版本中缺少一个条件,escape检查可空性的变量,从旧版本粘贴该条件,你就可以了
答案 6 :(得分:1)
CI_DB_active_record::where()
有第三个用于转义的参数,这对我来说比打开和关闭更好CI_DB_driver::_protect_identifiers
public function where($key, $value = NULL, $escape = TRUE)
不确定添加了哪个CI版本。
HTH某人
答案 7 :(得分:0)
我刚刚为此阅读了一个简单的解决方案......
我更改了var $ _escape_char的值(system / database / drivers / mysql / mysql_driver.php,第36行..
是
var $_escape_char = '`';
已更改为
var $_escape_char = ' ';
现在它可以工作......但如果我遇到任何安全问题,我很害怕..
谢谢
答案 8 :(得分:0)
这是一个对我有用的技巧。替换此行
$this->db->join($this->_table_device, $fieldname1. " = ". $fieldname2, 'LEFT');
用这个:
$this->db->join($this->_table_device, $fieldname1. " IN(". $fieldname2 .")", 'LEFT');
这将阻止CI逃离你的领域。它并不理想,但它比替代品更好。