Ответ 1
Используйте эту строку перед запросом:
$this->db->_protect_identifiers=false;
Это прекратит добавлять обратные ссылки в построенный запрос.
Раньше все мои запросы выполнялись нормально в 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))
Пожалуйста, предложите обходной путь.
Грэкиас
Используйте эту строку перед запросом:
$this->db->_protect_identifiers=false;
Это прекратит добавлять обратные ссылки в построенный запрос.
Решение очень просто: В файле конфигурации базы данных (./application/config/database.php) добавьте новый элемент в массив с настройками по умолчанию.
$db['default']['_protect_identifiers']= FALSE;
Это решение работает для меня и более элегантно и профессионально.
Все остальные ответы действительно старые, это работает с 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;
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 не будет пытаться защитить ваши имена полей или таблиц с обратными окнами. Это полезно, если вам нужен составной оператор select.
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
не имеет одинарных кавычек (делает его строкой), и он может не проверяться (не проверен мной).
Я думаю, вы должны проверить файл DB_driver.php, есть переменная с именем protected_identifier, дело в том, когда вы проверите со старой версией CI, вы увидите, что есть условие, которое отсутствует в новой версии, escape переменная, которая проверяется на значение nullability, вставьте это условие из старой версии, и вы будете в порядке
CI_DB_active_record::where()
имеет третий параметр для экранирования, это улучшилось для меня, чем включение и выключение CI_DB_driver::_protect_identifiers
public function where($key, $value = NULL, $escape = TRUE)
Не уверен, какая версия CI была добавлена.
HTH кто-то
Я просто прочитал простое решение для этого...
Я изменил значение var $_escape_char (system/database/drivers/mysql/mysql_driver.php, строка 36.
Это было
var $_escape_char = '`';
Изменено на
var $_escape_char = ' ';
и теперь это работает... Но я боюсь, если я сделал какие-либо проблемы с безопасностью.
Спасибо
Вот трюк, который сработал у меня. Заменить эту строку
$this->db->join($this->_table_device, $fieldname1. " = ". $fieldname2, 'LEFT');
с этим:
$this->db->join($this->_table_device, $fieldname1. " IN(". $fieldname2 .")", 'LEFT');
это предотвратит утечку CI из поля. Это не идеально, но лучше, чем альтернативы.