23

以前我的所有查询在 CI 2.0 版中运行良好,但是当我升级到2.0.3时,我的一些 SELECT 查询被破坏了。

CI 会自动添加反引号 (``),但在旧版本中它会按原样运行。

CI 用户手册已指示在

数据库->选择

作为

错误的

但它仍然无法正常工作。

代码如下:

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))

请提出解决方法。

4

9 回答 9

32

Use this line before your query:

$this->db->_protect_identifiers=false;

This will stop adding backticks to the built query.

于 2013-01-09T09:48:14.423 回答
15

解决方案非常简单:在数据库配置文件 (./application/config/database.php) 中使用默认设置向数组添加一个新元素。

$db['default']['_protect_identifiers']= FALSE;

这个解决方案对我有用,而且更优雅、更专业。

于 2012-06-07T22:04:59.113 回答
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;
于 2013-09-11T19:00:32.337 回答
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 错误可能会产生误导。)

文档

$this->db->select()接受可选的第二个参数。如果您将其设置为FALSE,CodeIgniter 将不会尝试使用反引号保护您的字段或表名称。如果您需要复合选择语句,这很有用。

于 2011-09-28T19:35:38.977 回答
2

CI 只会保护你的 ACTIVE RECORD 调用,所以如果你正在运行,$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没有单引号(使其成为字符串),并且它可能无法验证(未经我测试)。

于 2011-09-20T13:59:38.913 回答
1

我认为你应该检查 DB_driver.php 文件,有一个名为protect_identifier的变量,关键是当你检查旧版本的CI时,你会看到新版本中缺少一个条件,转义变量是检查可空性,从旧版本粘贴该条件,你会没事的

于 2011-09-29T15:14:45.850 回答
1

CI_DB_active_record::where() 有第三个参数用于转义,这对我来说比打开和关闭更好CI_DB_driver::_protect_identifiers

public function where($key, $value = NULL, $escape = TRUE)

不确定这是在哪个 CI 版本中添加的。

某人

于 2015-06-11T14:22:01.707 回答
0

这是一个对我有用的技巧。替换此行

$this->db->join($this->_table_device, $fieldname1. " = ".  $fieldname2, 'LEFT');

有了这个:

$this->db->join($this->_table_device, $fieldname1. " IN(".  $fieldname2 .")", 'LEFT');

这将防止 CI 逃离您的领域。这并不理想,但它比替代品更好。

于 2011-12-16T14:46:22.663 回答
-1

我刚刚阅读了一个简单的解决方案......

我更改了 var $_escape_char 的值(system/database/drivers/mysql/mysql_driver.php,第 36 行 ..

它是

var $_escape_char = '`';

变成

var $_escape_char = ' ';

现在它可以工作了...但是如果我遇到任何安全问题,我会感到害怕..

谢谢

于 2011-10-01T06:13:30.813 回答