Jump to content

[RESOLU] Probleme avec classe MySQL.php


Recommended Posts

Bonjour, :mellow:

je viens d'installer un module pour effectuer des requêtes depuis le BO.

La plupart des requêtes simples fonctionnent sans problème, mais j'ai un souci avec une requête INSERT un peu plus "poussée" :

INSERT INTO ps_order_history (id_employee, id_order, id_order_state, date_add)
SELECT 2,oh1.id_order, 5, NOW()
FROM ps_order_history oh1
INNER JOIN ps_order_history oh2 ON oh1.id_order = oh2.id_order
WHERE oh1.id_order_state = 4
AND (oh1.id_order BETWEEN 305 AND 308) AND (oh1.id_order NOT IN (306,307))
GROUP BY oh1.id_order, oh1.date_add
HAVING oh1.date_add = MAX (oh2.date_add)
ORDER BY oh1.id_order

Cette requête a pour but de changer le statut de plusieurs commandes simultanément (en excluant si besoin certaines commandes).

Cette requête fonctionne sans problème car je l'ai testée dans PhpMyAdmin et je n'obtiens aucune erreur ou même warning.

Par contre, quand je la lance depuis le BO, j'obtiens le message d'erreur suivant :

Warning: mysql_fetch_assoc(): supplied argument is not a valid MySQL result resource in /home/r4avenue/www/classes/MySQL.php on line 96

Je précise que la requête a quand même été validée (dans mon exemple, 2 lignes ont été rajoutées dans la TABLE ps_order_history, ce qui est correct). Mais je ne suis pas très chaud à l'idée de laisser ce message d'erreur tel quel sans comprendre d'où vient le problème et essayer de le résoudre...

 

Visiblement, c'est la fonction mysql_fetch_assoc() qui "n'apprécie" pas cette requête mais j'aimerai savoir pourquoi ?

 

Si quelqu'un peut m'aider la dessus...

 

Merci beaucoup ;)

Link to comment
Share on other sites

Cette fonction est "dédiée" à l'affichage des données ?

Si oui, effectivement il y a un problème !!!

Voici le début du code de la fonction du module qui exécute les requêtes :

private function _executeQuery($query) {
	if (floatval(_PS_VERSION_) >= 1.4) {
		$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS($query);
	} else {
		$result = Db::getInstance()->ExecuteS($query);
	}
	$error = Db::getInstance()->getMsgError();
	$affected_rows = Db::getInstance()->Affected_Rows();
               .....

 

Est-ce qu'il faut, dans le cas de cette requête, que j'appelle plutôt la fonction

public function	Execute($query)

de la classe MySQL.php ?

 

(Pour précision, malgré le message d'erreur, il m'a bien affiché le nombre de lignes insérées... Mais j'aimerais quand même avoir quelque chose de propre, sans message d'erreur <_< )

 

Merci de ton aide ;)

Link to comment
Share on other sites

Effectivement, ça va pas mal m'aider ;)

A ce propos, tu dis dans ton article :

Il ne faut utiliser la constante _PS_USE_SQL_SLAVE_ en argument que dans le cadre de requêtes en lecture (SELECT, SHOW, etc..)

 

Alors que dans le module que j'ai installé, il utilise la constante _PS_USE_SQL_SLAVE_ seulement en fonction de la version de PS :

if (floatval(_PS_VERSION_) >= 1.4) {
		$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS($query);
	} else {
		$result = Db::getInstance()->ExecuteS($query);
	}

C'est ok ça ? Ca a une incidence (négative) importante ?

 

Merci encore

Link to comment
Share on other sites

Ca n'aura une incidence que si vous utilisez des serveurs SQL esclaves (pour cela il faut dé commenter des lignes dans la classe DB) et que vous lancez des requêtes INSERT, UPDATE ou DELETE depuis ce module. Aussi je vous recommande de remplacer les lignes citées par ceci :

if (preg_match('#^\s*(select|show)\s+#i', $query))
    $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS($query);
else
    $result = Db::getInstance()->Execute($query);

Link to comment
Share on other sites

OK, merci beaucoup.

je vais remplacer le code de suite ^_^

(la RegEx sert à contrôler s'il y a SELECT ou SHOW dans la requête, c'est ça ? En cas de requête INSERT...SELECT... ça la prendra donc quand même en compte ? )

Link to comment
Share on other sites

Bonjour,

J'ai fait la modif' dans le fichier.

Et je viens de tester ma requête à nouveau : j'obtiens un nouveau message d'erreur :

FUNCTION bdd_test.MAX does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual

(bdd_test est le nom de ma base de données de test en local )

 

(pour rappel, voici la requête :

INSERT INTO ps_order_history (id_employee, id_order, id_order_state, date_add)
SELECT 2,oh1.id_order, 5, NOW()
FROM ps_order_history oh1
INNER JOIN ps_order_history oh2 ON oh1.id_order = oh2.id_order
WHERE oh1.id_order_state = 4
AND oh1.id_order BETWEEN 312 AND 315
GROUP BY oh1.id_order, oh1.date_add
HAVING oh1.date_add = MAX (oh2.date_add)
ORDER BY oh1.id_order

)

Link to comment
Share on other sites

Autant pour moi :wacko:

Ca vient de l'espace entre MAX et la ( :(

En virant cet espace c'est bon.

J'ai testé avec une requête INSERT et une requête SELECT, et selon le cas il passe bien soit par :

$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS($query);

soit par :

$result = Db::getInstance()->Execute($query);

 

Donc tout est nickel :D

 

Merci beaucoup Raphaël ;)

Link to comment
Share on other sites

Autant pour moi :wacko:

Ca vient de l'espace entre MAX et la ( :(

En virant cet espace c'est bon.

J'ai testé avec une requête INSERT et une requête SELECT, et selon le cas il passe bien soit par :

$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS($query);

soit par :

$result = Db::getInstance()->Execute($query);

 

Donc tout est nickel :D

 

Merci beaucoup Raphaël ;)

 

 

En fait ce qui fait la différence , essentiellement ici , c'est l'usage des methodes Execute et ExecuteS de la classe Db.

 

Execute n'attend pas de résultat , et est donc adaptée aux alter, drop, create... et autres inserts

 

ExecuteS attend un résultat , d'ou le mysql_fetch derrière pour formater le tableau de retour.

 

Il me semble que c'est plus cette modif qui a rendu ton code 'propre' et a moins que j'ai mal lu , je trouvais que ça pouvait servir de préciser la différence (bien que cela ait été déja fait hein ;) )

Mais bon , si j'ai lu trop vite j'aurais juste perdu une occase de me taire :D

 

Edit : je crois bien que c'est ce que Raphaël voulait dire ici :

 

Bonjour, de quel module s'agit il ? Est il gratuit ? Visiblement ce module semble avoir un bug, cette fonction de PHP est destinée à afficher les résultats après une requête de type SELECT, et il doit croire à cause de votre INSERT ... SELECT qu'il y a des données à afficher.

 

Ceci dit ce qui motive mon post , c'est en fait ton code dans ton dernier post , ou peut être sans le vouloir , je ne sais pas ExecuteS() est remplacé par Execute()

Link to comment
Share on other sites

Salut Broceliande, oui c'est exactement ça les requêtes qui retournent un résultat à afficher doivent passer par ExecuteS(), et celles qui ne retournent rien (insert, delete, update, create, alter, etc.) doivent passer par Execute(), c'est ce que fait le code que j'ai posté plus haut. D'ailleurs on pourrait ajouter EXPLAIN à la liste des types de requêtes retournant quelque chose.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...