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.