IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

sqlsrv (linux) et PHP8.0 : parcours en fetch_array incomplet [SQL-Server]


Sujet :

PHP & Base de données

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Février 2011
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2011
    Messages : 5
    Par défaut sqlsrv (linux) et PHP8.0 : parcours en fetch_array incomplet
    Bonjour,

    un cas des plus gênant la semaine dernière, sur une base en production de quelques dizaines de tables :
    exécution d'une requête : 
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT TOP 10000 * FROM ENMPNEW.dbo.brxb  WHERE bx_cannee IN (2020,2021)

    Nombre de lignes annoncées : 683 (et c'est bien ce qui est attendu, en vérifiant via SSMS) avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sqlsrv_num_rows($lienbase)
    Un parcours avec un fetch dans un simple while :

    
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while ($row = sqlsrv_fetch_array($lienbase, SQLSRV_FETCH_ASSOC)) { nblu++ ; }
    ne me fournit que les 10 premières lignes, sans aucune erreur, il en manque 673.

    D'autres formulations sont testées :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM ENMPNEW.dbo.brxb  WHERE bx_cannee IN (2020,2021)  ORDER BY bx_cbrxb DESC
    Une seule ligne parcourue pour les 683 annoncées.

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM ENMPNEW.dbo.brxb  WHERE bx_cannee IN (2020,2021)  ORDER BY bx_cannee DESC
    ne fournit aucune ligne sur les 683 annoncées

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM ENMPNEW.dbo.brxb  WHERE bx_cannee IN (2020,2021)  ORDER BY bx_cannee ASC
    Me fournit cette fois les deux premières lignes des 683 qui sont toujours annoncées.

    Pour cette table en particulier, jamais d'erreur signalée nulle part, pourtant quelle que soit la requête exécutée, le nombre de lignes parcourues ne correspond pas à la réalité, une chance que je m'en sois aperçu.
    Même un parcours global sans clause WHERE ne me permet de lister que 41 des 8370 lignes en base (et annoncées).

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM ENMPNEW.dbo.brxb  ORDER BY bx_cannee ASC

    Sans le "ORDER BY" j'arrive à en lister 1493.

    J'ai mis à jour le système ubuntu 20.04LTS, (5.4.0-89-generic) ainsi que les diverses bibliothèques et rebooté le système, en vain.

    J'ai également reconstruit les index (en l'occurrence sur la colonne bx_cbrxb) et mis à jour les statistiques dans mssql.

    Quelques précisions infra, j'ai tenté en passer en PHP8.1 mais il me faut passer en version 5.10beta pour les bibliothèques, testé mais en vain.

    mssql-server is already the newest version (15.0.4188.2-3)

    PHPINFO

    PHP Version 8.0.14

    pdo_sqlsrv

    pdo_sqlsrv support enabled

    ExtensionVer 5.9.0

    Directive Local Value Master Value

    pdo_sqlsrv.client_buffer_max_kb_size 10240 10240

    pdo_sqlsrv.log_severity 0 0

    pdo_sqlsrv.report_additional_errors 1 1

    pdo_sqlsrv.set_locale_info 2 2

    sqlsrv

    sqlsrv support enabled

    ExtensionVer 5.9.0

    Directive Local Value Master Value

    sqlsrv.ClientBufferMaxKBSize 10240 10240

    sqlsrv.LogSeverity 0 0

    sqlsrv.LogSubsystems 0 0

    sqlsrv.SetLocaleInfo 2 2

    sqlsrv.WarningsReturnAsErrors On On
    Toute suggestion est la bienvenue...

    R. Maillard.

  2. #2
    Membre chevronné Avatar de licardentaistor
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Juillet 2021
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juillet 2021
    Messages : 345
    Par défaut
    Bonjour,

    et comme ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    for ($i=0; $i < sqlsrv_num_rows($stmt); $i++){
        $row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC, SQLSRV_SCROLL_ABSOLUTE, $i);
     
    }

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Février 2011
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2011
    Messages : 5
    Par défaut
    Citation Envoyé par licardentaistor Voir le message
    Bonjour,

    et comme ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    for ($i=0; $i < sqlsrv_num_rows($stmt); $i++){
        $row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC, SQLSRV_SCROLL_ABSOLUTE, $i);
     
    }
    Bonjour,
    merci pour cette idée, ça fonctionne bien en manipulant un pointeur.
    Malheureusement cette méthode n'a rien de pratique, mais confirme que ce bug se situe plutôt dans les bibliothèques (sqlsrv.so ?) et non du moteur mssql. Il reste des plus dangereux puisqu'il dissimule des données lorsque l'on utilise des instructions qui n'ont rien d'exotiques.
    J'en ai des centaines comme cela : je doute d'être le seul à faire un while avec un fetch qui, par ailleurs, fonctionne bien
    A moins d'un (mauvais) paramétrage particulièrement précis qui ne viserait qu'une seule table sur plus de 30, la situation reste bloquée pour moi. Je vais en modifier quelques-uns du coté de php, je verrai bien.

  4. #4
    Membre chevronné Avatar de licardentaistor
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Juillet 2021
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juillet 2021
    Messages : 345
    Par défaut
    pour info j'utilise la même méthode pour lire mes tables et je n'ai pas de soucis (PHP7 et pdo_sqlsrv 5.9.0), quelle est la version du driver Sql Server pour PHP ?(via phpinfo)

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Février 2011
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2011
    Messages : 5
    Par défaut
    Citation Envoyé par licardentaistor Voir le message
    pour info j'utilise la même méthode pour lire mes tables et je n'ai pas de soucis (PHP7 et pdo_sqlsrv 5.9.0), quelle est la version du driver Sql Server pour PHP ?(via phpinfo)
    j'ai essayé plusieurs versions PHP7.4.25 et 5.9 puis PHP8.1.1 avec 5.10beta

    JE CORRIGE ce que j'ai écrit dans ma précédente réponse, les 683 enregistrements sont effectivement accédés, sauf que (ben oui), certains valent FALSE, un dump de la structure en retour le montre, j'ai même épuré le code dans la boucle en me contentant d'un compteur et d'un "echo" à l'écran du dump pour être sûr de ne pas faire d'écrasement mémoire avec une instruction pourrie, pour illustrer je copie ici une petite partie des "echo" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    gerer_bases.php à 2022-01-25 11:09:59::924 req2 676 : FALSE :
    gerer_bases.php à 2022-01-25 11:09:59::924 req2 677 : non null : Array ( [bx_cbrxb] => 8431 [bx_date] => DateTime Object ( [date] => 2022-01-18 00:00:00.000000 [timezone_type] => 3 [timezone] => Europe/Berlin ) [bx_fretr] => F [bx_categorie] => Scolarité [bx_cannee] => 2021 [bx_montant] => 2774.0000 [bx_nbchq] => 3 [bx_tmpsi] => �� [bx_modep] => CB BUREAU [bx_nb] => 17702 )
    gerer_bases.php à 2022-01-25 11:09:59::924 req2 678 : non null : Array ( [bx_cbrxb] => 8432 [bx_date] => DateTime Object ( [date] => 2022-01-19 00:00:00.000000 [timezone_type] => 3 [timezone] => Europe/Berlin ) [bx_fretr] => F [bx_categorie] => Scolarité [bx_cannee] => 2021 [bx_montant] => 949.5000 [bx_nbchq] => 2 [bx_tmpsi] => �.D [bx_modep] => CB BUREAU [bx_nb] => 17703 )
    gerer_bases.php à 2022-01-25 11:09:59::924 req2 679 : FALSE :
    gerer_bases.php à 2022-01-25 11:09:59::924 req2 680 : FALSE :
    gerer_bases.php à 2022-01-25 11:09:59::924 req2 681 : FALSE :
    gerer_bases.php à 2022-01-25 11:09:59::924 req2 682 : FALSE :
    gerer_bases.php à 2022-01-25 11:09:59::924 req2 683 : non null : Array ( [bx_cbrxb] => 8437 [bx_date] => DateTime Object ( [date] => 2022-01-21 00:00:00.000000 [timezone_type] => 3 [timezone] => Europe/Berlin ) [bx_fretr] => F [bx_categorie] => Scolarité [bx_cannee] => 2021 [bx_montant] => 1520.0000 [bx_nbchq] => 1 [bx_tmpsi] => �{ [bx_modep] => CB BUREAU [bx_nb] => 17708 )
    On peut clairement voir que les enregistrements 676, 679 à 682 sont de type FALSE (testé avec === FALSE) (mais pas NULL, j'ai vérifié ça aussi). Cela signale une erreur, je vais aller voir plus loin...
    Une affaire à suivre, mais je vois le bout du tunnel, j'aurai dû commencer par là ; lire attentivement le manuel pour sqlsrv_fetch_array
    Ça y est je tiens le début :
    [CODE]erreur : Array ( [0] => Array ( [0] => HY090 [SQLSTATE] => HY090 [1] => 0
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     => 0 [2] => [unixODBC][Driver Manager]Invalid string or buffer length [message] => [unixODBC][Driver Manager]Invalid string or buffer length ) )
    Reste à comprendre pourquoi, je vais regarder de plus près l'installation des bibliothèques, (pecl install sqlsrv etc.), je pense que le problème est par là... Je repasse en version 5.9 et PHP 8.0.14.
    Ah, changement pour un poil mieux :
    [CODE]erreur : Array ( [0] => Array ( [0] => 01004 [SQLSTATE] => 01004 [1] => 0
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     => 0 [2] => [Microsoft][ODBC Driver 17 for SQL Server]String data, right truncation [message] => [Microsoft][ODBC Driver 17 for SQL Server]String data, right truncation ) )
    Pas une erreur grave ça...

  6. #6
    Nouveau membre du Club
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Février 2011
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2011
    Messages : 5
    Par défaut L'explication : issue
    en creusant un peu, j'en arrive à cette page :
    https://docs.microsoft.com/en-us/sql...ql-server-2017

    où l'on explique que microsoft ne gère toujours pas correctement les accentuations, en fait le problème d'encodage UTF-8 dans le cas des pilotes dans une installation sur un linux.
    (oui, bon, je n'aime pas krosoft, c'est un euphémisme)
    Je vais reformuler ma requête en espérant trouver quelque chose qui passe bien.
    Est-ce suffisant pour considérer le sujet comme résolu ? je dirai non, le problème demeure, mais j'ai au moins une réponse, donc oui pour ce fil.
    Merci à tous

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 10
    Dernier message: 23/04/2019, 23h19
  2. Débat : quelle distribution Linux choisir pour débuter ?
    Par Anonymous dans le forum Distributions
    Réponses: 227
    Dernier message: 18/02/2015, 10h09
  3. [SQL-Server] Module sqlsrv fonctionne sous linux ?
    Par Ikaly dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 29/10/2014, 11h27
  4. OmniORB : code sous Windows et Linux
    Par debug dans le forum CORBA
    Réponses: 2
    Dernier message: 30/04/2002, 17h45
  5. Je ne peux établir une connexion cliente sous Linux.
    Par Anonymous dans le forum CORBA
    Réponses: 5
    Dernier message: 16/04/2002, 15h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo