2011-09-20 7 views
22

In precedenza tutte le mie query funzionavano correttamente in CI versione 2.0 ma quando ho aggiornato a 2.0.3 alcune delle mie query SELECT erano interrotte.Comportamento di backtick strano in Active Record in Code Igniter 2.0.3

CI sta aggiungendo automaticamente backtick (``), ma nella versione precedente è in esecuzione così com'è.

utente CI manuale sono incaricati di aggiungere secondo parametro in

DB-> selezionare

come

FALSE

ma ancora non funziona.

codice è il seguente: -

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

L'errore è la seguente: -

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 

Dai un'occhiata alla CONCAT (trim (clb_company.portal_line1), ` '/'` , trim (clb_device.name))

Per favore suggerire la soluzione alternativa.

Gracias

+0

avrei pensato che gli apici inversi avrebbero fatto alcuna reale differenza per la query come faranno solo incapsulano i nomi delle tabelle/campi nella query per consentire i caratteri speciali se si utilizza 'echo $ this-> db-> last_query(); 'e pubblica il codice che potrebbe consentirci di fare più luce su di esso. – simnom

+0

@simnom: crea un problema, ad es. CONCAT (trim (table1.field1), '/', assetto (table2.field2)) viene analizzato come CONCAT (trim (table1.field1), ' '/'', trim (table2.field2)) –

+0

prega di inserire un Codice di registrazione attivo nella domanda. – Louis

risposta

2

CI proteggerà soltanto le chiamate record attivo, quindi se si esegue $this->db->query(); vi andrà bene, e sulla base delle note si dovrebbe essere al sicuro con AD chiama in questo modo per disabilitare apici inversi (non so perché tu dici che non funzionano, ma non si vede il codice completo, quindi non posso essere sicuro)

$this->db->select('(SELECT SUM(payments.amount) FROM payments WHERE payments.invoice_id=4') AS amount_paid', FALSE); 
$query = $this->db->get('mytable'); 

assicurarsi FALSE è senza virgolette singole (lo rende una stringa), e potrebbe non convalidare (non testato da me).

+0

Grazie per la spiegazione Jakub, il vero problema si verifica quando si usano alcune funzioni incorporate con la virgola come separatori come ho dato l'esempio di CONCAT (campo1, '-', campo2) e vieni con concat ('field1',' '-'', 'field2') –

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

Il false di cui parlavi è ciò che è necessario, si può provare il codice di cui sopra e copiare e incollare a noi l'uscita di

echo $this->db->last_query(); 

Questo ci mostrerà ciò che la classe DB è la creazione di esattamente e possiamo vedere che cosa funziona/cosa non lo è. Potrebbe essere qualcosa di diverso (che non hai dato l'errore che si genera a volte gli errori di SQL può essere fuorviante.)

Dal docs:

$this->db->select() accetta un secondo parametro opzionale. Se lo si imposta su FALSE, CodeIgniter non tenterà di proteggere il campo oi nomi delle tabelle con i backtick. Questo è utile se hai bisogno di un'istruzione select select.

+0

Louis, ho incluso la query e l'errore, per favore dare un'occhiata. –

+1

Questo potrebbe essere un tentativo lungo ma hai messo il parametro fal falso sulle informazioni sulla società ma non sulla query che dà l'errore? (come in si usa concat più di uno in questo file? - il codice di esempio e l'errore non corrispondono, potresti semplicemente usare il codice di esempio o non essere sicuro.) – Louis

1

Penso che dovresti controllare DB_driver.file PHP, v'è una variabile denominata come protect_identifier, il punto è quando si verificherà con la versione precedente di CI, vedrete che v'è una condizione che manca nella nuova versione, la fuga variabile che è controllato per nullability, incollare tale condizione dalla versione precedente e sarete OK

0

ho appena letto una soluzione semplice per questo ...

ho cambiato il valore di var $ _escape_char (sistema/database/drivers/mysql/mysql_driver.php, linea 36 ..

era

var $_escape_char = '`'; 

cambiato in

var $_escape_char = ' '; 

e adesso funziona ... ma sto abbiate timore se ho fatto eventuali problemi di sicurezza ..

Grazie

+1

Decisamente Roopa, hai aperto la porta per INIEZIONI, non è raccomandato, ripristinare il codice originale. –

0

Ecco un trucco che ha funzionato per me. Sostituire questa linea

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

con questo:

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

questo impedirà CI fuoriuscita vostro campo. Non è l'ideale, ma è meglio delle alternative.

15

La soluzione è molto semplice: Nel file di configurazione del database (./application/config/database.php) aggiungi un nuovo elemento all'array con le impostazioni predefinite.

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

Questa soluzione è funzionante per me e più elegante e professionale.

+0

Questo mi ha aiutato a uscire da un legame. Non l'ho visto nei DOC ... –

+4

Questo ha qualche impatto sulla sicurezza? –

31

Utilizzare questa linea prima la query:

$this->db->_protect_identifiers=false; 

Questo fermerà l'aggiunta di apici inversi alla query costruita.

7

Tutte le altre risposte sono molto vecchio, questo si lavora con 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; 
+0

Funziona perfettamente. – Ankit

1

CI_DB_active_record::where() ha un terzo parametro per sfuggire, questo ha funzionato meglio per me di accensione e spegnimento CI_DB_driver::_protect_identifiers

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

Non sono sicuro di quale versione CI questo è stato aggiunto.

HTH qualcuno