PDO UPDATE : Syntax error or access violation

Résolu/Fermé
rjl Messages postés 543 Date d'inscription mardi 16 mars 2004 Statut Membre Dernière intervention 25 mai 2019 - 28 juil. 2012 à 23:56
rjl Messages postés 543 Date d'inscription mardi 16 mars 2004 Statut Membre Dernière intervention 25 mai 2019 - 30 juil. 2012 à 00:03
Bonjour,

J'ai fait au mieux mais n'ai pas su trouver la réponse à certaines questions, même pour la syntaxe du SELECT en requête préparée !
De même, je mets à jour un enregistrement que je viens de lire... Dois-je rappeler ses caractéristiques sous la forme WHERE et alors comment le cibler... puisque je change justement l'argument qui a permis sa sélection (je connais cependant sa clé primaire.
mais ça me conduit à citer 2 fois la Table (dans UPDATE et dans FROM ; est-ce correct ?
Je suis conscient de ne pas avoir fait de CATCH, ni de TRY ; je les mets lors de la connexion ; où les insère t'on pour un SELECT ou comme ici un UPDATE ?
Bref, je marche sur des oeufs.
Merci d'un appui indispensable pour résoudre ce flop.
Merci aussi d'une réponse à mes interrogations dont je suis confus du nombre. @bientôt RJL2728

Erreur renvoyée :
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM adh WHERE cle = '442'' at line 1' in /web/utlsudgoelo/www/pgUTL/AdhSup.php:29 Stack trace: #0 /web/utlsudgoelo/www/pgUTL/AdhSup.php(29): PDOStatement->execute(Array) #1 {main} thrown in /web/utlsudgoelo/www/pgUTL/AdhSup.php on line 29

Code du programme (l'erreur se situant à la mise à jour à partir de la ligne 22 : /* Préparation de la requête préparée UPDATE */ (précédée d'une ligne blanche) :

<?php              // MàJ RJL2728 
session_start();   // Ouvrir la session (venant de IdentifK)
	$nomresp = 		$_SESSION['Login'];
	$cdpw = 		$_SESSION['MotPasse'];
	$MajPossible =  $_SESSION['Initiales'];
	If (empty ($MajPossible)) 
		{Header("Location:/pgUTL/identifA.php");		// Retour Identification
		exit;
		}		
	$numcart = 		$_SESSION['numcart'];
	include_once("ConnectBDutl.php"); 			// Connexion à la base de données MySQL (users enregistrés)
/* Création de la requête préparée */	
	$query = 'SELECT cart, civil, nomadh, prenom, ville, excart, MaJ, qui, cle FROM adh WHERE cart = :toto';
	$param = array(':toto' => $numcart);
	$sth = $connexion->prepare($query);
	$sth->execute($param);    
	$a_results = $sth->fetch();	  
/* Récup sélection actualisation contenu */
	$wcle = $a_results[cle];             /* Cle primaire enreg dont doit évoluer le n° cart */
	$excart = $a_results[cart]; 
	
/* Préparation de la requête préparée UPDATE */
	$sql = 'UPDATE adh SET cart=:wcart, excart=:wexcart, qui=:wqui  FROM adh WHERE cle = :wcle';
	$param = array( 'wcle' => $wcle,		/* Enreg à modifier  */
					'wcart'=> 0,			/* RàZ zone  n° cart */
					'wexcart' => $excart,	/* Changement de zone (en excart) pour n° cart */
					'wqui' => $MajPossible	/* Indication Intervenant */
				  );  
	$sth = $connexion->prepare($sql);
	$sth->execute($param);    
var_dump ($param,"   ", $sth,"    ",$wcle,"      ");
	if(!$a_results)         
		{  
		echo "Aucun résultat";               // La requète n'a pas retournée de résultat
		} 
	exit;    /* PROVISOIRE  */
?>

A voir également:

6 réponses

Autumn`Tears Messages postés 1054 Date d'inscription samedi 14 mars 2009 Statut Membre Dernière intervention 23 octobre 2013 144
29 juil. 2012 à 01:15
Salut,

Pour faire ton try/catch tu peux faire :

$stsh->prepare($query);
try
{
$stsh->execute($param)
}
catch (PDOException $e)
{
echo $e->getMessage();
}

Mais le réel souci vient juste de ton UPDATE. Tu ne dois JAMAIS mettre de FROM dans UPDATE (Sauf dans le cas de requêtes imbriquées...).
0
rjl Messages postés 543 Date d'inscription mardi 16 mars 2004 Statut Membre Dernière intervention 25 mai 2019 49
Modifié par rjl le 29/07/2012 à 10:29
Bonjour Adrien,

Je ne m'attendais pas à une réponse vu l'heure de publication de mon message mais ce fut une bonne surprise de la trouver ce matin.
Eh, bien c'est OK et donc merci pour tes indications.
J'ai pataugé un peu pour la mise à jour de la date courante pensant que ça pouvait fonctionner automatiquement comme en INSERT INTO mais je n'ai pas trouvé !
J'ai donc ajouté un champ que j'alimente avec la fonction date et ça fonctionne.
J'ai aussi mis en place la fonction Try/Catch mais ne l'ai pas essayée (alors qu'il me suffit de tenter de viser une clé primaire inexistante) !
J'ai bien sûr supprimé le FROM d'autant que j'arrivais à mettre 2 fois le nom de la table ce qui me gênait mais je n'avais pas vu ou pas prêté assez attention à la structure de UPDATE que je cherchais en format pour PREPARE !
Cette mise à jour me réconforte un peu pour l'avenir car pour moi, c'était là une "Suppression" mais je conserve les données "désactivées".
Alors, encore merci et bon dimanche. RJL2729
0
Autumn`Tears Messages postés 1054 Date d'inscription samedi 14 mars 2009 Statut Membre Dernière intervention 23 octobre 2013 144
29 juil. 2012 à 11:54
Merci pareillement, au plaisir !

D'ailleurs tu devrais peut-être créer une classe qui utilise PDO, ça te permettrait de ne pas avoir à tout recopier, et à avoir un modèle plus fixe au final
0
rjl Messages postés 543 Date d'inscription mardi 16 mars 2004 Statut Membre Dernière intervention 25 mai 2019 49
29 juil. 2012 à 12:07
Oui, oui,
Sauf que créer une classe PDO, je vois mal mais vais peut-être trouver sur les tuto...
Pour ma suppression, ça marche trop bien...
Je me retrouve sur ma page d'appel... sans avoir conscience que ça a fonctionné !
J'ai ajouté 10sec de sleep... mais les 10 secondes passent avant le retour de mon écran (bloqué) et je ne vois pas le message 'Suppression réussie' !
Je joins cette partie du code pour le cas où tu aurais un truc pour permettre l'affichage en echo avant la libération du programme.
Merci d'avance RJL2729
/* Récup sélection actualisation contenu */
	$wcle = $a_results[cle];             /* Cle primaire enreg dont doit évoluer le n° cart */
	$excart = $a_results[cart]; 
	$datx = date("Y-m-j");
/* Préparation de la requête préparée UPDATE */
	$sql = 'UPDATE adh SET cart=:wcart, excart=:wexcart, qui=:wqui, MaJ=:wMaJ WHERE cle = :wcle';
	$param = array( 'wcle' => $wcle,		/* Enreg à modifier  */
					'wcart'=> 0,			/* RàZ zone  n° cart */
					'wexcart' => $excart,	/* Changement de zone (en excart) pour n° cart */
					'wqui' => $MajPossible,	/* Indication Intervenant */
					'wMaJ' => $datx			/* Date du Jour de modif */
				  );  
	$sth = $connexion->prepare($sql);
	try	
		{
		$sth->execute($param);    
		}
	catch (PDOException $e)
		{
		$e.="<br />Revenir par la flèche à la page précédente et corriger le N° carte";	
		echo $e->getMessage();
		exit;
		} 	
	echo "Suppression réussie";
	sleep(10);
	Header("Location:/pgUTL/identifK.php");
	exit
?>
0
rjl Messages postés 543 Date d'inscription mardi 16 mars 2004 Statut Membre Dernière intervention 25 mai 2019 49
Modifié par rjl le 29/07/2012 à 15:00
Je "réponds" car je n'avais plus accès à la modif du précédent message ;
depuis que j'ai ajouté la gestion des erreurs (sans doute mal ficelée), je n'ai plus de problème pour mettre à jour des enregistrements inexistants ! La MàJ ne se fait pas, bien entendu, car l'enregistrement aux caractéristiques demandées n'existe plus mais je sors de la page avec un message "Suppression réussie", les caractères incorrects compris !

Mécanisme : je supprime un enregistrement n°666, par exemple ;
je vérifie : traitement correct ; ceci implique que le champ cart a été transféré dans excart et 2 autres champs renseignés.
Immédiatement, je demande le même traitement qui doit impérativement échouer en SELECT puisque 'cart' a été transformé en 0 et donc ne peut accepter une interrogation pour 666; or, à ma grande surprise je passe par une boucle "réussi".
Je pense que le traitement exception de l'UPDATE est aussi mauvais ?
Merci d'une analyse qui m'échappe vraiment !
Dans le cadre de mon message précédent, ne peut-il y avoir de solution de blocage de l'affichage en lançant in formulaire fictif avec acceptation de continuer dés l'affichage communiqué pris en compte ?
@bientôt RJL2729
Code :
<?php              // MàJ RJL2729 
session_start();   // Ouvrir la session (venant de IdentifK) 
 $nomresp =   $_SESSION['Login']; 
 $cdpw =   $_SESSION['MotPasse']; 
 $MajPossible =  $_SESSION['Initiales']; 
 If (empty ($MajPossible))  
  {Header("Location:/pgUTL/identifA.php");  // Retour Identification 
  exit; 
  }   
 $numcart =   $_SESSION['numcart']; 
 include_once("ConnectBDutl.php");    // Connexion à la base de données MySQL (users enregistrés) 
/* Création de la requête préparée */  
 $query = 'SELECT cart, civil, nomadh, prenom, ville, excart, MaJ, qui, cle FROM adh WHERE cart = :toto'; 
 $param = array(':toto' => $numcart); 
 $sth = $connexion->prepare($query); 
 try  
  { 
  $sth->execute($param);     
  } 
 catch (PDOException $e) 
 { 
 print "Erreur !: " . $e->getMessage() . "<br/>Revenir par la flèche à la page précédente et corriger le N° carte"; 
 die(); 
// $messagR .= "<br />Revenir par la flèche à la page précédente et corriger le N° carte"; 
// $e .= "     ".$messagR;  
// var_dump($e,$messagR); 
// echo $e->getMessage(); 
// exit; 
 }       
 $a_results = $sth->fetch();    
/* Récup sélection actualisation contenu */ 
 $wcle = $a_results[cle];             /* Cle primaire enreg dont doit évoluer le n° cart */ 
 $excart = $a_results[cart];  
 $datx = date("Y-m-j"); 
/* Préparation de la requête préparée UPDATE */ 
 $sql = 'UPDATE adh SET cart=:wcart, excart=:wexcart, qui=:wqui, MaJ=:wMaJ WHERE cle = :wcle'; 
 $param = array( 'wcle' => $wcle,  /* Enreg à modifier  */ 
     'wcart'=> 0,   /* RàZ zone  n° cart */ 
     'wexcart' => $excart, /* Changement de zone (en excart) pour n° cart */ 
     'wqui' => $MajPossible, /* Indication Intervenant */ 
     'wMaJ' => $datx   /* Date du Jour de modif */ 
      );   
 $sth = $connexion->prepare($sql); 
 try  
  { 
  $sth->execute($param);     
  } 
 catch (PDOException $e) 
  { 
  print "Erreur !: " . $e->getMessage() . "<br/>Revenir par la flèche à la page précédente et corriger le N° carte"; 
  die(); 
//  $e.="<br />Revenir par la flèche à la page précédente et corriger le N° carte";  
//  echo $e->getMessage(); 
// var_dump($e); 
//  exit; 
  }    
 echo "Suppression réussie"; 
 sleep(4); 
 exit; 
?>
0
Autumn`Tears Messages postés 1054 Date d'inscription samedi 14 mars 2009 Statut Membre Dernière intervention 23 octobre 2013 144
29 juil. 2012 à 15:47
Immédiatement, je demande le même traitement qui doit impérativement échouer en SELECT puisque 'cart' a été transformé en 0 et donc ne peut accepter une interrogation pour 666; or, à ma grande surprise je passe par une boucle "réussi".

C'est tout à fait logique : le try/catch ne va pas retourner d'erreur sur ce genre d'élément, mais plutôt sur des erreurs de communication avec la base (connexion, requête mal construite, doublon dans une insertion, etc...)

Après, je te propose de faire un var_dump de ta variable $wcle par exemple, afin de vérifier son contenu, car en effet la requête d'UPDATE devrait, quant à elle, échouer
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
rjl Messages postés 543 Date d'inscription mardi 16 mars 2004 Statut Membre Dernière intervention 25 mai 2019 49
Modifié par rjl le 29/07/2012 à 18:35
J'ai, juste, après la lecture théoriquement impossible de l'enregistrement supprimé (cart ramené à 0), ajouté :
Print_r;print $numcart;       
 var_dump($numcart);     
 $a_results = $sth->fetch();    
/* Récup sélection actualisation contenu */ 
 $wcle = $a_results[cle];             /* Cle primaire enreg dont doit évoluer le n° cart */

Des résultats 666int(666) NULL Suppression réussie (pour lesquels je n'arrive jamais à faire de changements de ligne), je déduis que j'ai 666 en $wnumcart et l'équivalent int(666) par le var_dump($numcart);
Néanmoins, la lecture n'a pu trouver un WHERE correspondant et je dois sans doute tester manuellement (en sortie du Catch) pour savoir si la clé trouvée est la bonne ?

Pour les tests après le UPDATE, j'ai ajouté
var_dump($wcle);
Print_r;print $wcle;
echo "Suppression réussie"; // cette 3ème instruction étant en place préalablement.</code>
Les résultats pour cet ensemble sont alors : NULL Suppression réussie

Pour être clair, j'ai refait 2 passages (un avec enregistrement restauré et un après l'avoir "supprimé") :

666 régénéré ; une suppression normale réussie : 666int(666) string(3) "447" 447Suppression réussie
447 est la cle de l'enregistrement que je récupère pour le UPDATE (ayant supprimé cart) ! Le traitement est parfait avec des initiales différentes puisque j'ai testé avec d'autres codes.

Second test de suppression ensuite ; résultats identiques au premier jet : 666int(666) NULL Suppression réussie

Dans le SELECT, cle est demandé ; l'enregistrement est trouvé au premier passage et peut donc délivrer cle (ici égal à 447) pour cart 666).
A la seconde demande de suppression, l'enregistrement n'existe plus avec cle ncart demandé et ne peut donc être trouvé (délivrant ou non une erreur de SELECT).
Il est donc normal de ne pas disposer de la cle (NULL) et de ne pouvoir trouver un enregistrement NULL en cle (sauf fin de fichier ?).

Tout se joue donc avec des tests complémentaires en SELECT (cart cherché trouvé) mais aussi en UPDATE (wcle trouvée).

Merci de me préciser si tu partages cette analyse et de me corriger y compris dans les tests.

@bientôt et merci d'avance RJL2729
0
rjl Messages postés 543 Date d'inscription mardi 16 mars 2004 Statut Membre Dernière intervention 25 mai 2019 49
30 juil. 2012 à 00:03
J'ai pris en charge mes tests complémentaires en SELECT (cart cherché trouvé) mais aussi en UPDATE (wcle trouvée).

Au passage, j'ai fini par découvrir que dans ma page purement PHP, mes messages d'erreur ou information étaient bien en UTF8 mais considérés comme au format ISO-8859-1 ! A ma grande surprise, c'est un utf8_decode( ) qui a résolu ces problèmes d'affichage !

Tout est donc clair sur cette page PHP... Je te joins des résultats :
Après réactivation de l'adhérent 666 :
---------------> Suppression réussie pour l'adhérent 666

En demandant une seconde fois sa suppression :
---------------> Adhérent 666 absent avec ce n° carte
========>cRevenir par la flèche à la page précédente et corriger le N° carte

Il me reste (pour demain) à bloquer le déroulement de la machine pour laisser le temps de lire à l'utilisateur (le sleep() n'étant pas efficace à ce titre...) ;
Javais imaginé un formulaire fictif mais je crois avoir trouvé une meilleure solution

Je vais passer mes messages entre pages par une variable Session et les afficherai par la page réceptrice où je me rends.
Ainsi je bénéficierai en général du HTML pour un affichage amélioré puis effacerai le message Session pour ne pas le réutiliser à tort.

@la prochaine... page et encore merci. RJL2729
0