EXTRACTION/INSERTION DE CONDITIONS SQL DANS UNE REQUÊTE

neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 - 28 févr. 2008 à 15:49
cs_8Tnerolf8 Messages postés 30 Date d'inscription vendredi 25 novembre 2005 Statut Membre Dernière intervention 17 novembre 2009 - 2 mars 2008 à 15:07
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/45887-extraction-insertion-de-conditions-sql-dans-une-requete

cs_8Tnerolf8 Messages postés 30 Date d'inscription vendredi 25 novembre 2005 Statut Membre Dernière intervention 17 novembre 2009
2 mars 2008 à 15:07
Tout d'abord un grand merci à NEIGEDHIVER, YOMAN64 et MALALAM pour leurs suggestions et critiques constructives.
J'ai entièrement remanié le code en fonction de leurs indications afin de l'optimiser.
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
1 mars 2008 à 10:37
Hello,

j'ai aussi des soucis quant à la façon de coder.
En effet, il y a bcp de redondances : si tu dois utiliser un strtoupper ou un strpos sur une même variable plusieurs fois, autant le faire une fois et stocker la valeur.
Ensuite, ton 1er tableau...
Tu crées un tableau qui a TOUJOURS 4 entrées, et dont chaque entrée à une valeur entière. Bon.
Ensuite tu boucles sur ce tableau...avec un for()...et un $a ui ira donc de 0 à 3 de toute manière.
Puis tu fais une condition pour voir si la valeur de $tableau[$a] est supérieure à 0, PUIS tu fais un switch sur...$a...qui, tu le SAIS, sera égal à 0 d'abord, puis à 1, 2 et enfin 3...
Pardonne-moi, mais boucler sur un tableau pour ensuite tester chacune de ses clefs de manière séquentielle, ça n'a pas de sens.
Puisque tu CONNAIS les clefs, autant faire un accès direct :
if($tableau[0] > 0) {$var = valeur}
Ou utiliser un foreach :
foreeach($tableau as $val) {if ($val > 0){$var = valeur}}
Ou encore plus logique : quand tu crées ce même tableau.
Bref, en réflêchissant 2mn, voilà à quoi peut se résumer toute cette partie de ton code en le condensant et en l'optimisant; sans compter qu'on peut ainsi ajouter facilement de nouveaux mots clefs et poids :
<?php
$Source = strtoupper($source);
$Pds_Mot = 0;
$aPds = array(3, 7, 9, 11);
$aNeedles = array('WHERE', 'GROUP BY', 'HAVING', 'ORDER BY');
foreach($aNeedles as $iK => $sNeedle) {if(false !($iPos strpos($Source, $sNeedle))) {
$_Pos_Mot_Clef[] = $iPos;
$Pds_Mot += $aPds[$iK];
} else {
$_Pos_Mot_Clef[] = 0;
}
}
?>
A mon avis, c'est nettement plus rapide. Et on pourrait en effet condenser encore en utilisant les PCRE.
Ceci dit, comme Neige, je pense que les opérateurs binaires seraient plus appropriés (pour la suite du code, mais cela implique évidemment de ne pas procéder ainsi pour la 1ère partie de ton code).

Bref, ton code me semble bien trop compliqué et dans le code, ET dans son utilisation en fait. Je préfère pour ma part avoir des requêtes claires que je peux relire facilement quand je mate mon code. Crois-moi, c'est vital en entreprise : on gagne du temps sur les corrections.
Mais ça reste un avis personnel.
cs_yoman64 Messages postés 592 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 4 décembre 2008
29 févr. 2008 à 09:17
Salut,
Bien que je sois d'accord avec neigedhiver à propos des PCRE, si tu souhaite garder tes strpos tu devrais le faire un peu mieu... en effet tu utilise 8 fois strtoupper pour rien, c'est anti-performance. Soit tu crée une variable tampon avec la chaine Upper, soit tu utilise stripos à la place de strpos.

Ensuite tu utilise 8 fois strpos alors que 4 suffierait.

Ça serait bien que tu déclare tes variables avant de les utiliser. tu incrémente $Pds_Mot , mais tu ne la déclare null part, c'est une mauvaise chose.

Au risque de démarrer un débat interminable, je crois que les ' devrait être utilisé au lieu des " puisque tu n'utilises aucune chaine n'ayant besoin d'être parser.

Ensuite de la méthode que tu le fais il peut se passer des erreurs d'interprétation si j'insère une comparaison avec un string "WHERE", il va croire qu'il y a un where même si ce n'est pas le cas.

Je crois que ce code aurait besoin d'amélioration, mais ça peut être utile...

Bonne chance
cs_8Tnerolf8 Messages postés 30 Date d'inscription vendredi 25 novembre 2005 Statut Membre Dernière intervention 17 novembre 2009
28 févr. 2008 à 19:11
Bonsoir NEIGEDHIVER

L'idée de conception par strpos repose sur la détermination de la présence des mots clés par $Pds_Mot. Après, en fonction de la valeur de cette variable, je ne garde que ce qui n'est pas en rapport avec une condition de filtrage.

Ton idée d'utiliser les PCRE est bonne, mais on devrait quand même faire une structure de "case" identique à celle présente dans ma fonction afin de savoir qu'elle sous chaîne capturer en fonction des mots clé SQL présents.

Tu parles de constructeur complet de requêtes. Ce n'est pas le but premier de cette fonction qui est surtout utilisée pour exploiter les valeurs choisies par l'internaute en fonction d'un SQL "racine".

Toujours dans le domaine des contructeurs complets de requêtes, je suis en train de mettre au point une fonction qui génèrera le SQL complet pour des INSERT ou des UPDATE.

Dès que cette fonction sera écrite, je la publierai. Et, "Place_cond_SQL" trouvera toute sa complémentarité car ma fonction de création de requête s'appuiera sur celle-ci afin de générer les clause de conditions de filtrage pour les UPDATE.
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
28 févr. 2008 à 15:49
Salut,

J'ai pas regardé en détails, mais à vue de nez, tu te compliques la tâche, pour ce qui est des correspondances des mots clés recherchés.
Tu donnes des valeurs, tu testes la somme de, tout ça... C'est bien laborieux.
Tu gagnerais peut-être à utiliser des constantes et des opérateurs binaires :

if ($presence_mots & MOT_WHERE) {

}
elseif ($presence_mots & MOT_HAVING) {

}

quelque chose dans le genre.
Non seulement ce serait plus facile à lire, mais tu gagnerais probablement en performances et en nombre de lignes.

Toujours dans un soucis de gain de performances, je suis persuadé que des expressions régulières compatibles Perl (PCRE) seraient plus appropriées qu'une série de strpos. Et ce serait plus facile à utiliser avec ce dont je te parle plus haut.

Sinon, pour ce qui est de l'idée... Pas mauvaise. Mais quitte à avoir un moteur qui fait des remplacements dans une requête, autant faire un constructeur complet de requêtes.
Pour ma part, je les construit moi-même, en mettant des conditions et en concaténant. Je pense que j'y gagne encore en perfs...
Rejoignez-nous