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 :

Requête INSERT SQL Server via ODBC et PHP : erreur de syntaxe à tort


Sujet :

PHP & Base de données

  1. #1
    Membre à l'essai
    Profil pro
    Développeur informatique
    Inscrit en
    Mai 2006
    Messages
    17
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Réunion

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2006
    Messages : 17
    Points : 14
    Points
    14
    Par défaut Requête INSERT SQL Server via ODBC et PHP : erreur de syntaxe à tort
    Bonjour,

    Je dispose d'une page PHP qui exécute un ensemble de requêtes SQL en transaction pour écrire dans une base SQL Server 2008 R2. Le site de production tourne avec la configuration suivante :
    - PHP 5.3 32 bits
    - Driver ODBC SQL Server 32 bits version 6.01
    - IIS 7.5

    Tout fonctionne bien sur le site de production.

    Je dois faire évoluer mon site pour le passer en PHP 7.3 64 bits. On a installé un nouveau serveur Windows Server 2016 avec IIS 10 et un driver ODBC SQL Server plus récent en 64 bits (version 10).
    Depuis, sans modifier mon code, j'ai tenté d'exécuter la même page et une de mes requêtes SQL ne fonctionne pas :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    INSERT INTO LIGNELIVRAISON 
    (ARTICLEID, LCDEID, LIVID, LIGNELIVQTELIV, LIGNELIVDATECREATION, LIGNELIVQTEINITIALE, LIGNELIVMTUNITHT, LIGNELIVMTUNITTVA, LIGNELIVMTUNITTTC, LIGNELIVMTREMISE, LIGNELIVCODELOT, LIGNELIVDATEPEREMPTION) 
    VALUES 
    (1573, 44551, 35232, 3, CONVERT(datetime, '27/09/2019 13:48:54'), 3, 50, 4.25, 54.25, 0, '???', CONVERT(date, '31/12/2050'));

    Le message d'erreur que j'ai est le suivant :
    Code 37000 : [Microsoft][ODBC SQL Server Driver][SQL Server]Syntaxe incorrecte vers '*='.
    Or, les caractères *= ne font pas partie de la requête ci-dessus comme on peut le constater.
    J'ai essayé plusieurs versions de PHP (5 ou 7), plusieurs drivers ODBC SQL Server plus récents que celui initialement installé, mais dans tous les cas, je me retrouve avec ce message d'erreur lors que j'exécute cette requête avec odbc_exec().
    Cette requête copiée/collée dans un éditeur de requêtes SQL Server fonctionne très bien.

    Je suppose que c'est lié au driver ODBC, mais je ne peux pas installer le même que celui de l'ancien serveur car il n'est pas compatible Windows Server 2016 et est 32 bits (mon PHP est 64 bits). J'ai également essayé de passer en PHP 32 bits, sans succès.

    J'ai également tenté de passer par PDO ou les fonctions sqlsrv, mais le résultat est le même.

    Voici la partie du code PHP concernée :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
     
    $ms->hdebug();
        //$ms->libre('SET IMPLICIT_TRANSACTIONS OFF');
        //$ms->libre('BEGIN TRANSACTION');
        odbc_autocommit($ms->get_lien(), false);
     
        $id_utilisateur_creation = id_utilisateur_athome($my, $ms);
     
        // On a ajouté un contrôle en amont mais par sécurité, on ajoute un contrôle ici
        if ($id_utilisateur_creation === FALSE) {
          $id_utilisateur_creation = 1;
        }
     
        // 25 = Fournisseur matériel
        $id_type_intervenant = 25; 
        $type_facture = 'F';
        // 2 = Location
        $id_type_produit = 2;
        // 5 = Livrée
        $id_etat_commande = 5;
        $franco_port = 'N';
        $tproduitcode = 'LOCA';
        $date = date('d/m/Y');
        $date_heure = date('d/m/Y H:i:s');
        $montant_remise = 0;
        $total_ttc = 0;
        $etat_sejour_suivi = 14;
        // Pour éviter une erreur lors de l'insertion des lignes de livraison, liées a une procédure stockée
        $code_lot_article = '???';
        $date_peremption_article = '31/12/2050';
        $commentaires = addslashes('Commande créée pour le bon de location n° ' . $_POST['id_location']);
     
        // Récupération des TVA AtHome
        $tva_athome = $ms->lire(
          'TVAID, TVATAUX * 100',
          'TVA',
          "AND TVAVISIBLE = 'O'",
          "TVATAUX ASC"
        );
     
        $mapping_tva = array();
     
        foreach($tva_athome as $tva) {
          list($id_tva, $taux_tva) = $tva;
          $mapping_tva[$id_tva] = round($taux_tva, 2);
        }
        // -
     
        // Etape 1: Création de la commande et lignes de commande
        $id_commande = $ms->ajouter(
          'CDEFRN',
          'UTIID, TPRODUITID, FOURNID, ETATCDEID, PATID,
           CDEFRNDATE, CDEFRNFRANCOPORT, CDEFRNDATECREATION, TProduitCode, CDEFRNCOMMENTAIRE',
          "$id_utilisateur_creation, $id_type_produit, {$_POST['id_fournisseur']}, $id_etat_commande, {$_POST['ipp']},
           CONVERT(date, '$date'), '$franco_port', CONVERT(datetime, '$date_heure'), '$tproduitcode', '$commentaires'"
        );
     
        $lignes_commande = array();
     
        // Ajout des lignes d'articles
        foreach($_POST['articles'] as $id_article) {
          if ($_POST['prix'][$id_article] > 0 && $_POST['quantite'][$id_article] > 0) {
            $quantite = $_POST['quantite'][$id_article];
            $taux_tva = $mapping_tva[$_POST['tva'][$id_article]];
            $prix_ht = round($_POST['prix'][$id_article], 2);
            // On calcule les arrondis ici pour ne pas avoir de problème d'arrondi dans AtHome à cause des champs de type money
            $prix_ttc = round($prix_ht * (1 + ($taux_tva / 100)), 2);
            $montant_tva = $prix_ttc - $prix_ht;
     
            $lignes_commande[$id_article] = $ms->ajouter(
              'LIGNECDEFRN',
              'CDEFRNID, ARTICLEID, LCDEQTECDE, LCDEMTHT, LCDEMTTVA,
               LCDEMTTTC, LCDEMTREMISE, LCDEDATECREATION, LCDEQTEINITIALE',
              "$id_commande, $id_article, $quantite, $prix_ht, $montant_tva,
               $prix_ttc, $montant_remise, CONVERT(datetime, '$date_heure'), $quantite"
            );
     
            $total_ttc += $prix_ttc;
          }
        }
     
        $total_ttc = round($total_ttc, 2);
     
        // Etape 2: Livraison
        $id_livraison = $ms->ajouter(
          'LIVRAISON',
          'CDEFRNID, LIVDATE, LIVDATECREATION',
          "$id_commande, CONVERT(date, '$date'), CONVERT(datetime, '$date_heure')"
        );
     
        $lignes_livraison = array();
     
        // Ajout des lignes de livraison
        foreach($_POST['articles'] as $id_article) {
          if ($_POST['prix'][$id_article] > 0 && $_POST['quantite'][$id_article] > 0) {
            $quantite = $_POST['quantite'][$id_article];
            $taux_tva = $mapping_tva[$_POST['tva'][$id_article]];
            $prix_ht = round($_POST['prix'][$id_article], 2);
            // On calcule les arrondis ici pour ne pas avoir de problème d'arrondi dans AtHome à cause des champs de type money
            $prix_ttc = round($prix_ht * (1 + ($taux_tva / 100)), 2);
            $montant_tva = $prix_ttc - $prix_ht;
     
            $lignes_livraison[$id_article] = $ms->ajouter(
              'LIGNELIVRAISON',
              'ARTICLEID, LCDEID, LIVID, LIGNELIVQTELIV, LIGNELIVDATECREATION,
               LIGNELIVQTEINITIALE, LIGNELIVMTUNITHT, LIGNELIVMTUNITTVA, LIGNELIVMTUNITTTC, LIGNELIVMTREMISE,
               LIGNELIVCODELOT, LIGNELIVDATEPEREMPTION',
              "$id_article, {$lignes_commande[$id_article]}, $id_livraison, $quantite, CONVERT(datetime, '$date_heure'),
               $quantite, $prix_ht, $montant_tva, $prix_ttc, $montant_remise,
               '$code_lot_article', CONVERT(date, '$date_peremption_article')"
            );
          }
        }


    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
     
    public function ajouter($table,$champs,$valeurs)
        {
          if(trim($champs)=="")
          {
            $req="INSERT INTO ".$table." VALUES(".$valeurs.");";
          }
          else
          {
            $req="INSERT INTO ".$table." (".$champs.") VALUES(".$valeurs.");";
          }
          $retour=-1;
          if($this->hdebug)
          {
            $this->log->logguer("INS",$req);
          }
          if($this->debug)
          {
            echo "<debug_sql>".$req."</debug_sql>";
          }
          else
          {
            if($this->calcul_temps)
            {
              $_SESSION["Temps_Execution"]->Debut_Compter("MsSQL");
            }
            //$res = @mssql_query($req,$this->lien) or $this->erreur("insert",$req,0,"");
            //$res = odbc_prepare($this->lien, $req);
            //$res_ex = odbc_execute($res);
     
            $res = odbc_exec($this->lien, $req);
     
            if (!$res) {
              //var_dump($req);
              $this->erreur("insert", $req, odbc_error($this->lien), odbc_errormsg($this->lien));
            }
     
            $id_retour=@odbc_exec($this->lien,"SELECT @@IDENTITY") or $this->erreur("insert",$req,0,"");
            $retour=odbc_result($id_retour, 1);
            if($this->calcul_temps)
            {
              $_SESSION["Temps_Execution"]->Fin_Compter("MsSQL");
            }
            //$retour=mysql_insert_id($this->lien);
          }
          //$retour=0;
          return $retour;
        }

    Quelqu'un a une idée ?
    Merci d'avance.

  2. #2
    Membre à l'essai
    Profil pro
    Développeur informatique
    Inscrit en
    Mai 2006
    Messages
    17
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Réunion

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2006
    Messages : 17
    Points : 14
    Points
    14
    Par défaut
    En complément, si je commente la partie qui fait le contrôle d'erreur (!$res), la requête fonctionne. Donc elle revoit bien un code d'erreur à tort. Désactiver ce contrôle n'est pas la bonne solution, j'ai besoin de distinguer les requêtes qui fonctionnent de celles qui plantent, quelle que soit la raison...

  3. #3
    Modérateur

    Avatar de MaitrePylos
    Homme Profil pro
    DBA
    Inscrit en
    Juin 2005
    Messages
    5 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : Belgique

    Informations professionnelles :
    Activité : DBA
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 497
    Points : 12 600
    Points
    12 600
    Par défaut
    Bonjour, avez-vous fais un dump de $req ?


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    ......
    var_dump($req);
    die();
    $res = odbc_exec($this->lien, $req);

  4. #4
    Membre à l'essai
    Profil pro
    Développeur informatique
    Inscrit en
    Mai 2006
    Messages
    17
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Réunion

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2006
    Messages : 17
    Points : 14
    Points
    14
    Par défaut
    Bonjour,

    Oui, je me suis servi du dump de $req pour vérifier que la requête fonctionne dans un éditeur de requêtes MS SQL.

Discussions similaires

  1. [XE7] Connexion à une base de données SQL Server via ODBC pour plate-forme cible OS X
    Par Ptite Développeuse dans le forum Bases de données
    Réponses: 7
    Dernier message: 08/01/2015, 15h23
  2. Réponses: 0
    Dernier message: 25/08/2010, 13h19
  3. Pb Acces a SQL server via ODBC
    Par JesusHansHuberVorme dans le forum Outils
    Réponses: 7
    Dernier message: 17/06/2010, 20h15
  4. Import dans SQL Server via ODBC PrimeBase
    Par tbruchet dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 12/05/2010, 12h38
  5. [SQL-Server] conexion sql-server via odbc impossible
    Par fasyr dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 05/05/2009, 09h13

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