[英]SQL Server INSERT query with ODBC & PHP : weird syntax error
我有一個 PHP 網頁,在事務中運行一些 SQL 查詢,寫入 SQL Server 2008 R2 數據庫。 生產服務器使用:
在這種環境下一切正常。
I have to upgrade to PHP 7.3 64 bits on a new Windows Server 2016 server, running IIS 10 and a more recent SQL Server ODBC driver (64 bits). 我嘗試運行同一頁面,但其中一個查詢不起作用:
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'));
錯誤信息是:
代碼 37000:[Microsoft][ODBC SQL 服務器驅動程序][SQL Server]“*=”附近的語法錯誤。
如我們所見,字符“*=”不在此查詢中的任何位置。 我嘗試了多個版本的 PHP(5 或 7)、多個和更新的 ODBC 驅動程序,但是當我通過 odbc_exec() ZC1C425268E687385D1AB5074C1 運行此查詢時總是得到相同的結果我嘗試使用 PDO 或 sqlsrv 函數,但結果是一樣的。
如果我嘗試在 SQL Server Management Studio 中復制/粘貼此查詢,它可以正常工作。
我認為它可能與 ODBC 驅動程序有關,但我無法安裝目前正在生產的同一個驅動程序,因為它不適用於 Windows 2016 並且它是 32 位驅動程序。 我嘗試運行 PHP 7.3 的 32 位版本,但無濟於事。
PHP 代碼的一部分:
$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')"
);
}
}
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;
}
編輯:查詢中的 FR 日期時間格式工作正常。 我認為問題根本與它無關。
您需要傳遞正確的日期時間格式(即:MM/dd/yyyy hh:mm:ss)。 因為 SQL 服務器默認理解美國日期時間標准。
請查看下面的 select 查詢。
SELECT
CONVERT(date, '12/31/2050') LIGNELIVDATEPEREMPTION,
CONVERT(datetime, '09/27/2019 13:48:54') LIGNELIVDATECREATION
請檢查下面的插入腳本以獲得您的答案。
INSERT INTO LIGNELIVRAISON
(ARTICLEID, LCDEID, LIVID, LIGNELIVQTELIV, LIGNELIVDATECREATION, LIGNELIVQTEINITIALE, LIGNELIVMTUNITHT, LIGNELIVMTUNITTVA, LIGNELIVMTUNITTTC, LIGNELIVMTREMISE, LIGNELIVCODELOT, LIGNELIVDATEPEREMPTION)
VALUES
(1573, 44551, 35232, 3, CONVERT(datetime, '09/27/2019 13:48:54'), 3, 50, 4.25, 54.25, 0, '???', CONVERT(date, '12/31/2050'));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.