2012-12-12 16 views
23

Ecco il codice rilevante:PHP e SQL Server - i nomi dei campi troncati

function connect(){ 
    // DB credentials and info defined here.... 
    $connection = odbc_connect("DRIVER={SQL Server Native Client 11.0}; Server=$server; Database=$db;", $loginname, $loginpass); 
    return $connection; 
} 

function odbc_fetch_results($stmt, &$results) { 
    $numrows = odbc_num_rows($stmt); 
    $row = odbc_fetch_array($stmt); 
    print_r($row); // Prints: Array ([MEASUREMENT_UNI] => kg) 
    if($row){ 
     $results = array ($row); 
     while($row = odbc_fetch_array($stmt)){ 
      array_push($results, $row); 
     } 
    } 
    return $numrows; 
} 

$sql = "select * from measurements where ID=$id"; 
$stmt = executeSQL($conn,$sql); 
$nrows = odbc_fetch_results($stmt, $results); 
odbc_free_result($stmt); 
print_r($result[0]); // Prints: Array ([0] => Array ([MEASUREMENT_UNI] => kg)) 

Il risultato dovrebbe contenere una columnn chiamato MEASUREMENT_UNIT che (quando faccio un print_r posso verificare) viene troncato a MEASUREMENT_UNI che è solo 15 caratteri. L'ultima lettera T è stata interrotta.

Ho provato anche una query con un diverso tavolo e un diverso colonna sul database di SQL Server come un test per assicurarsi che non era una strana configurazione con la particolare tabella o colonna che sto lavorando con. Ho verificato che la stessa cosa si verifica con una tabella/colonna diversa: i nomi delle colonne vengono troncati a 15 caratteri quando eseguo una query di selezione come sopra.

Ho anche provato una selezione che specifica il nome del campo come select MEASUREMENT_UNIT from from measurements where ID=$id anziché select * ma che non risolve il problema.

Ho visto altri post simili a questo proposito ma sembrano indicare che dovrei essere in grado di ottenere almeno 30 caratteri, non il limite di 15 caratteri che sto vedendo.

Perché il nome della colonna viene troncato a 15 caratteri?

Modifica: il collegamento a un database di server MySQL non sembra comportare lo stesso problema. I nomi delle colonne DB delle tabelle MySQL NON sono stati troncati, il che mi porta a credere che questo non sia un problema con il plugin ODBC.

$connection = odbc_connect("DRIVER={MySQL};Server=$server; Database=$db;", $loginname, $loginpass); 
$sql = "select * from measurements where ID=$id"; 
$stmt = executeSQL($conn,$sql); 
$nrows = odbc_fetch_results($stmt, $results); 
odbc_free_result($stmt); 
print_r($result[0]); // Prints CORRECTLY: Array ([0] => Array ([MEASUREMENT_UNIT] => kg)) 

nota che entrambe le sezioni di codice di cui sopra sono stati testati nello stesso file sullo stesso server con la stessa installazione ODBC PHP +.

+0

È 'odbc_fetch_results' una funzione personalizzata? Non lo vedo nella documentazione di PHP. –

+0

@GigaWatt Sembra che non stavo pensando chiaramente. Ho pubblicato il codice per la funzione 'odbc_fetch_results'. – nmc

+4

Lancia un 'print_r ($ row);' immediatamente dopo '$ row = odbc_fetch_array ($ stmt);'. Questo dovrebbe farci vedere se il troncamento è nel tuo codice o nella chiamata 'obdc_fetch_array'. –

risposta

1

Il problema è sicuramente con il Microsoft ODBC driver versione 11, e sono fissati in ODBC Driver 13 Preview for SQL Server.

Ho scoperto questo come la mia macchina di sviluppo su cui gira Ubuntu 14.04 con il Driver 13 Preview installato funziona bene, ma poi quando ho implementato il nostro server di produzione con RHEL 7 con il Driver 11, tutti i tipi di devastazione si sono verificati mentre i nomi delle colonne venivano troncati a 15 caratteri.

La documentazione di Microsoft è scarsa per il supporto di Linux, quindi se stai usando Ubuntu, ecco il gist di installarlo.

+1

Alla fine ho provato a provare questo e sembra che Driver ODBC 13 risolva questo problema! '$ connection = odbc_connect (" DRIVER = {Driver ODBC 13 per SQL Server}; Server = $ server; Database = $ db; ", $ loginname, $ loginpass);' – nmc

14

Apparentemente il problema è con ODBC. C'è un bug in PHP dove i nomi delle colonne sono troncati a 31 caratteri, e l'unico modo per risolvere questo problema è ricompilare PHP, cambiando la lunghezza dell'array di name in /ext/odbc/php_odbc_includes.h (di solito 32 ma apparentemente era 16 nel tuo caso), ma questo non è dimostrato di essere sicuro o non sicuro. Vai a here e here per visualizzare ulteriori informazioni a riguardo.

+0

Grazie, ho visto quel bug report ma non sono riuscito a trovare il file '/ ext/odbc/php_odbc_includes.h' come specificato. Esiste un altro file in cui potrebbe essere presente questa configurazione? – nmc

+1

Devi compilarlo dalle fonti, purtroppo. Non è solo un campo in un file di configurazione. –

+0

Ahhh, questa è la chiave: deve essere compilata dalla fonte. Mi chiedo se ci siano altre soluzioni a questo rispetto al dover compilare PHP dal sorgente – nmc

1

La soluzione definitiva consiste nel ricompilare il PHP come suggerito nei thread di bug PHP o provare ad aggiornare la versione di PHP più recente.

è possibile aggirare il problema da colonne selettivamente ridenominazione nella vostra selezione per quelli più brevi:

$sql = "SELECT measurement_unit AS measure_unit, * FROM measurements WHERE ID=$id"; 
// now in your array you will have new index called "measure_unit" 
Problemi correlati