Странное поведение обратных галочек в Active Record в CodeIgniter 2.0.3 - PullRequest
22 голосов
/ 20 сентября 2011

Ранее все мои запросы работали нормально в CI версии 2.0, но когда я обновился до 2.0.3 , некоторые из моих запросов SELECT были прерваны.

CI добавляет backticks (``) автоматически, но в более старой версии он работает как есть.

Руководство пользователя CI поручило добавить второй параметр в

db-> выберите

как

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

Пожалуйста, предложите обходной путь.

Ответы [ 9 ]

31 голосов
/ 09 января 2013

Используйте эту строку перед вашим запросом:

$this->db->_protect_identifiers=false;

Это остановит добавление обратных галочек в построенный запрос.

15 голосов
/ 08 июня 2012

Решение очень простое: в файле конфигурации базы данных (./application/config/database.php) добавьте новый элемент в массив с настройками по умолчанию.

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

Это решение работает для меняи более элегантно и профессионально.

7 голосов
/ 11 сентября 2013

Все остальные ответы действительно старые, этот работает с 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 голосов
/ 28 сентября 2011
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 не будет пытаться защитить имена ваших полей или таблиц обратными галочками. Это полезно, если вам нужен составной оператор выбора.

2 голосов
/ 20 сентября 2011

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 без одинарных кавычек (делает его строкой) и может не проверяться (не проверено мной).

1 голос
/ 11 июня 2015

CI_DB_active_record::where() имеет третий параметр для выхода, для меня это сработало лучше, чем включение и выключение CI_DB_driver::_protect_identifiers

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

Не уверен, в какой версии CI это было добавлено.

HTH кто-то

1 голос
/ 29 сентября 2011

Я думаю, что вы должны проверить файл DB_driver.php, есть переменная с именем protect_identifier, дело в том, что когда вы проверите более старую версию CI, вы увидите, что в новой версии отсутствует условие, escapeпеременная, которая проверяется на обнуляемость, вставьте это условие из старой версии, и вы будете в порядке

0 голосов
/ 16 декабря 2011

Вот трюк, который работал для меня. Заменить эту строку

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

с этим:

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

это предотвратит выход КИ из вашего поля. Это не идеально, но лучше, чем альтернативы.

0 голосов
/ 01 октября 2011

Я только что прочитал простое решение для этого ...

Я изменил значение var $ _escape_char (system / database / drivers / mysql / mysql_driver.php, строка 36 ..

Это было

var $_escape_char = '`';

Изменено на

var $_escape_char = ' ';

и теперь это работает ... Но я боюсь, если у меня возникнут какие-либо проблемы с безопасностью ..

Спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...