PDO MSSQL - wrong BIGINT value returned

Salut.

Incerc sa interoghez pe o cheie primara BIGINT pe o baza de date MSSQL, insa unele rezultate se intorc rotunjite, diferite de cele stocate in baza de date:

9200000000000359 exista in DB, la fel si 9200000000000361. Interogarile pe oricare din aceste doua valori returneaza 9200000000000360 (side note irelevant: aceasta valoare nu exista in baza de date).

La o prima vedere, valorile sunt convertite gresit in binar, iar la conversia inapoi in zecimal rezulta valorile rotunjite, diferite de cele stocate in DB.

Note:

  • folosesc PHP5.6 pe o masina 64bit (nu 32bit)
  • aceasta problema se manifesta indiferent de driverul MSSQL pentru PHP folosit: dblib, odbc…
  • folosind un client SQL (Heidi, Navicat etc), problema nu se manifesta

Exista vreo setare de php.ini pentru dblib/odbc care sa rezolve aceste conversii gresite?


Intrebarea a fost adresata si aici, dar niciun noroc pana acum.

1 Like

Dacă rulezi PHP pe Windows esti limitat la 32 bits (chiar daca tu ai instalat PHP pe 64 bits). Trebuie sa faci upgrade la PHP 7, care suporta 64 bits pe Windows.

1 Like

Problema se manifesta atat local (PHP 7.0.11 pe macOS Sierra), cat si pe serverul CentOS 6.7 (Linux 2.6.32-573.el6.x86_64 / PHP 5.6.25).

Next guess: prin configurație (parametrul SQLFLT8) sau ORM sau prin scriptul tău valoarea aia BIGINT e transormată în float cumva?
Valoarea maximă pe care poți să o reprezinți în siguranță cu float este 2^53 - 1, adica 9007199254740991 (significant bit pression: 52 bits, restul pana la 64 sunt folositi pentru exponent - 11 - si semn - 1).

1 Like

Incearca driverul mssql distribuit de Microsoft (merge doar pe Windows din pacate):
https://www.microsoft.com/en-us/download/details.aspx?id=20098
Daca vrei sa folosesti MSSQL ca si baza de date in productie probabil ca va trebui sa rulez si php pe Windows cu driverul din link.

Am avut mai demult de facut niste migrari de date de pe MSSQL pe MySQL si am intalnit multe probleme de genul asta.

It seems that Yii makes a conversion to float on the result. Even plain PHP 7 on a 64 bit machine returns the following output:

php > echo (int)(float)9200000000000359;
9200000000000360

Using plain PHP and PDO, the correct output is returned:

$db = new PDO($dbc->connectionString, $dbc->username, $dbc->password);
$stmt = $db->query("...... WHERE id = 9200000000000359");
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC)[0]['id']);

// output:
array(1) {
    [0] => string(16) "9200000000000359"
}
4 Likes

Hehe, deci am nimerit-o până la urmă.