CodeIgniter 2.0.3 中 Active Record 中奇怪的反引号行为
以前,我的所有查询在 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))
请提出解决方法。
Previously my all queries were running fine in CI version 2.0 but when I upgraded to 2.0.3 some of my SELECT queries were broken.
CI is adding backticks (``) automatically, but in older version its running as it is.
CI user manual have instructed to add second parameter in
db->select
as
FALSE
but still it's not working.
Code is as following:
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');
----------------
The error is as follows:
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
Have a look at CONCAT(trim(clb_company.portal_line1), `'/'`, trim(clb_device.name))
Please suggest the workaround.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
这是一个对我有用的技巧。将此行替换
为:
这将防止 CI 逃离您的字段。它并不理想,但比其他选择要好。
Here's a trick that worked for me. Replace this line
with this:
this will prevent CI from escaping your field. It's not ideal but it's better than the alternatives.
我刚刚读了一个简单的解决方案...
我更改了 var $_escape_char 的值(system/database/drivers/mysql/mysql_driver.php,第 36 行..
它被
更改为
,现在它可以工作了...但我是担心如果我造成任何安全问题..
谢谢
I just read a simple solution for this...
I changed the value of var $_escape_char (system/database/drivers/mysql/mysql_driver.php, line 36..
It was
Changed to
and now it works... But i am affraid if I made any security issues..
Thanks
在查询之前使用此行:
这将停止向构建的查询添加反引号。
Use this line before your query:
This will stop adding backticks to the built query.
解决方案很简单:
在数据库配置文件 (./application/config/database.php) 中,使用默认设置向数组添加一个新元素。
这个解决方案对我来说很有效,而且更加优雅和专业。
The solution is very simple:
In the database configuration file (./application/config/database.php) add a new element to array with default settings.
This solution is working for me and more elegant and professional.
所有其他答案都非常旧,这个适用于 CI 2.1.4
All other answers are really old, this one works with CI 2.1.4
您所说的 false 是所需要的,您可以尝试上面的代码并将输出复制并粘贴给我们吗?
这将向我们展示数据库类正在创建什么,我们可以看到什么在起作用/ 什么不是。它可能是其他东西(您没有给出生成的错误,有时 sql 错误可能会产生误导。)
来自 docs:
$this->db->select()
接受可选的第二个参数。如果您将其设置为FALSE
,CodeIgniter 将不会尝试使用反引号保护您的字段或表名称。如果您需要复合选择语句,这非常有用。The
false
you were talking about is what is needed, can you try the code above and copy and paste to us the output ofThis will show us what the DB class is creating exactly and we can see whats working / what isn't. It may be something else (you haven't given the error from that is generated sometimes sql errors can be misleading.)
From the docs:
$this->db->select()
accepts an optional second parameter. If you set it toFALSE
, CodeIgniter will not try to protect your field or table names with backticks. This is useful if you need a compound select statement.CI 只会保护您的 ACTIVE RECORD 调用,因此如果您正在运行
$this->db->query();
您会没事的,并且根据注释,您应该可以安全地使用 AD像这样的调用来禁用反引号(不知道为什么你说它们不起作用,但我没有看到你的完整代码,所以我不能确定)确保
FALSE
不带单引号(使其成为字符串),并且它可能无法验证(未经我测试)。CI will only protect your ACTIVE RECORD calls, so if you are running
$this->db->query();
you will be fine, and based on the notes you should be safe with AD calls like so to disable backticks (not sure why you say they don't work, but I don't see your full code, so I can't be sure)make sure
FALSE
is without single quotes (makes it a string), and it might not validate (not tested by me).我认为你应该检查DB_driver.php文件,有一个名为protect_identifier的变量,重点是当你检查旧版本的CI时,你会发现新版本中缺少一个条件,转义变量是检查是否可为空,粘贴旧版本中的条件,就可以了
I think you should check DB_driver.php file, there is a variable named as protect_identifier, the point is when you will check with older version of CI, you will see that there is a condition which is missing in new version,escape variable which is checked for nullability, paste that condition from older version and you will be OK
CI_DB_active_record::where()
有第三个参数用于转义,这对我来说比打开和关闭更好CI_DB_driver::_protect_identifiers
不确定添加了哪个 CI 版本in.
HTH某人
CI_DB_active_record::where()
has a third param for escaping, this has worked better for me than switching on and offCI_DB_driver::_protect_identifiers
Not sure what CI version this was added in.
HTH someone