Précédent   Forum des professionnels en informatique > PHP > Langage > Regex
Regex Forum d'entraide sur les expressions rationnelles PHP. Avant de poster -> FAQ regex, Cours de regex et Sources de regex
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 04/03/2006, 13h45   #1
Membre éclairé
 
Avatar de XtofRoland
 
Inscription : août 2005
Messages : 361
Détails du profil
Informations forums :
Inscription : août 2005
Messages : 361
Points : 340
Points : 340
Par défaut Extraire des informations d'une requête SQL

bonjour je cherche a extraire le nom d'une table d'un string sql.

pour le moment je pratique ainsi:
Code :
1
2
3
4
5
 
$SQL = strtoupper($SQL);
$SQL = str_replace(" FROM ", "[*%&]", $SQL );
$SQL = str_replace(" WHERE ", "[*%&]", $SQL);
list($fields,$this->table,$whereclause) = explode("[*%&]",$SQL);
mais qd il n'y a pas de where ca plante. jusqu'a present je rajoutais where 1=1 et ca ne me posait pas de problemes mais un nouvelle ecran ou je fais un select ds le dual m'impose de ne pas mettre de clause where.

j'en profite pour essayer de mettre une expression reguliere mais je cale completement... entre le regex le posix.. je patauge
quel est le nom de la fonction qui me retournerai le nom de la table? (si je lui donne le bon pattern)

merci
__________________
Le but de tout developpeur OO est de devenir une référence.
Mon avatar est un ambigramme, les curieux peuvent le retourner ;-)
Aider <> Faire a la place de!!!
XtofRoland est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2006, 19h48   #2
Rédacteur
 
Avatar de Yogui
 
Homme Guillaume Rossolini
Directeur technique
Inscription : février 2004
Messages : 13 720
Détails du profil
Informations personnelles :
Nom : Homme Guillaume Rossolini
Localisation : France

Informations professionnelles :
Activité : Directeur technique

Informations forums :
Inscription : février 2004
Messages : 13 720
Points : 17 355
Points : 17 355
Salut

Si tu cherches un truc vraiment béton, tu vas te prendre la tête, je te le promets...

Voici une piste :
Code :
/(?:SELECT|UPDATE|INSERT)[[:space:]](?:FROM|INTO)?([[:space:]])?`?([^` ]+)`?/i
PS : Je n'ai pas testé...
__________________
Mes articles - Zend Certified Engineer (PHP + Zend Framework)
Ressources PHP - Ressources Zend Framework
Yogui est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2006, 21h24   #3
Expert Confirmé
 
Avatar de Maxoo
 
Maxime Pasquier
Expert PHP
Inscription : novembre 2004
Messages : 2 126
Détails du profil
Informations personnelles :
Nom : Maxime Pasquier
Âge : 28
Localisation : France, Loire Atlantique (Pays de la Loire)

Informations professionnelles :
Activité : Expert PHP
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : novembre 2004
Messages : 2 126
Points : 2 602
Points : 2 602
Code :
preg_match(/^.*(FROM|INTO)\s+(\w)+/,$SQL,$resultat)
le tout etant de faire et de voir si ca te donne ce qu'il faut.

Si ca marche pas, donne moi un exemple de requete SQL que tu peux avoir et je te dirai ou le regexp merde.
__________________
Pour une bien meilleur lisibilité, utilisez la balise [code], c'est le [#] dans votre éditeur.
Mon espace Développez : mes Créations.


Rencontre & Carte des Membres de Developpez.com, version 3.0
Maxoo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/03/2006, 11h47   #4
Rédacteur
 
Avatar de Yogui
 
Homme Guillaume Rossolini
Directeur technique
Inscription : février 2004
Messages : 13 720
Détails du profil
Informations personnelles :
Nom : Homme Guillaume Rossolini
Localisation : France

Informations professionnelles :
Activité : Directeur technique

Informations forums :
Inscription : février 2004
Messages : 13 720
Points : 17 355
Points : 17 355
maxoo : Ton expression semble passer mais il mettre le + dans la parenthèse.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$sql = 'SELECT truc FROM table1 WHERE INSERT INTO table2() VALUES () UPDATE table3 SET ';
 
preg_match_all('/(?:SELECT|UPDATE|INSERT)\s([a-z0-9_]+)?\s?(?:FROM\s|INTO\s|SET\s)`?([a-z0-9_]*\s?)/i', $sql, $matches, PREG_SET_ORDER);
echo '<pre>';
print_r($matches);
echo '</pre>';
 
foreach($matches as $match){
   if(!empty($match[2])){
      $tablename = $match[2];
   }
   else{
      $tablename = $match[1];
   }
 
   echo $tablename.'<br />';
}
J'ai testé mon code, cette fois, et ça fonctionne.
Parcours $matches : pour chaque élément, ton nom de table est en première position. Tu peux enlever des ?: pour avoir plus d'infos.

[Edit] Correction : ça ne fonctionnait pas correctement pour les UPDATE.
Pour avoir les résultats, tu dois tester chaque $match : si $match[2] est non vide, alors c'est ton nom de table, sinon tu le trouveras dans $match[1].
__________________
Mes articles - Zend Certified Engineer (PHP + Zend Framework)
Ressources PHP - Ressources Zend Framework
Yogui est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/03/2006, 12h22   #5
Expert Confirmé
 
Avatar de Maxoo
 
Maxime Pasquier
Expert PHP
Inscription : novembre 2004
Messages : 2 126
Détails du profil
Informations personnelles :
Nom : Maxime Pasquier
Âge : 28
Localisation : France, Loire Atlantique (Pays de la Loire)

Informations professionnelles :
Activité : Expert PHP
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : novembre 2004
Messages : 2 126
Points : 2 602
Points : 2 602
Citation:
Envoyé par Kirkis
maxoo : Ton expression semble passer mais il mettre le + dans la parenthèse.
exact !!!

une question : pourquoi tu t'embete a définir des trucs avant le FROM et apres le nom de la TABLE ... ca ne sert a rien ici.

il faut optimiser (le code et la comprehension !!)
__________________
Pour une bien meilleur lisibilité, utilisez la balise [code], c'est le [#] dans votre éditeur.
Mon espace Développez : mes Créations.


Rencontre & Carte des Membres de Developpez.com, version 3.0
Maxoo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/03/2006, 12h29   #6
Rédacteur
 
Avatar de Yogui
 
Homme Guillaume Rossolini
Directeur technique
Inscription : février 2004
Messages : 13 720
Détails du profil
Informations personnelles :
Nom : Homme Guillaume Rossolini
Localisation : France

Informations professionnelles :
Activité : Directeur technique

Informations forums :
Inscription : février 2004
Messages : 13 720
Points : 17 355
Points : 17 355
C'est pour les requêtes UPDATE. Comment les gères-tu si tu ne mets rien ?

De plus, il est plus performant d'ancrer les regex et de les faire commencer par une chaîne littérale. Dans mon exemple, il n'y a pas d'ancrage car on peut parser une chaîne complète pour plusieurs requêtes.

[Edit] Tiens, pour la compréhension :
Code :
1
2
3
4
5
6
7
preg_match_all('/'
   .'(?:SELECT|UPDATE|INSERT)\s'
   .'([a-z0-9_,` ]+)?'        // Maybe a tablename, maybe a list of fields
   .'(?:FROM\s|INTO\s|SET\s)'
   .'`?'
   .'([a-z0-9_]*\s?)'         // If present, assuredly a tablename
   .'/i', $sql, $matches, PREG_SET_ORDER);
__________________
Mes articles - Zend Certified Engineer (PHP + Zend Framework)
Ressources PHP - Ressources Zend Framework
Yogui est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/03/2006, 13h06   #7
Expert Confirmé
 
Avatar de Maxoo
 
Maxime Pasquier
Expert PHP
Inscription : novembre 2004
Messages : 2 126
Détails du profil
Informations personnelles :
Nom : Maxime Pasquier
Âge : 28
Localisation : France, Loire Atlantique (Pays de la Loire)

Informations professionnelles :
Activité : Expert PHP
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : novembre 2004
Messages : 2 126
Points : 2 602
Points : 2 602
Code :
preg_match(/(FROM|INTO|UPDATE)\s+(\w+)/i,$SQL,$resultat)
mais avec ca, ca marche pour tout les SQL aussi
__________________
Pour une bien meilleur lisibilité, utilisez la balise [code], c'est le [#] dans votre éditeur.
Mon espace Développez : mes Créations.


Rencontre & Carte des Membres de Developpez.com, version 3.0
Maxoo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/03/2006, 13h41   #8
Rédacteur
 
Avatar de Yogui
 
Homme Guillaume Rossolini
Directeur technique
Inscription : février 2004
Messages : 13 720
Détails du profil
Informations personnelles :
Nom : Homme Guillaume Rossolini
Localisation : France

Informations professionnelles :
Activité : Directeur technique

Informations forums :
Inscription : février 2004
Messages : 13 720
Points : 17 355
Points : 17 355
Ouaip...
/me va se pendre
__________________
Mes articles - Zend Certified Engineer (PHP + Zend Framework)
Ressources PHP - Ressources Zend Framework
Yogui est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/03/2006, 09h49   #9
Membre éclairé
 
Avatar de XtofRoland
 
Inscription : août 2005
Messages : 361
Détails du profil
Informations forums :
Inscription : août 2005
Messages : 361
Points : 340
Points : 340
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?
$SQL = "select * from table where qqq = 111";
preg_match(/(FROM|INTO|UPDATE)\s+(\w+)/i,$SQL,$resultat); //line 3
foreach($resultat as $brol) echo $brol.'<br />'; 
 
//Parse error: parse error, expecting `')'' in h:\easyphp1-8\www\index.php on line 3
 
 
$sql = 'SELECT truc FROM table1  '; 
 
preg_match_all('/(?:SELECT)\s([a-z0-9_]+)?\s?(?:FROM\s)`?([a-z0-9_]*\s?)/i', $sql, $matches, PREG_SET_ORDER); 
 
echo $matches[0][2].'<br />'; 
 
?>
la deuxième solution marche impecc ;-)
__________________
Le but de tout developpeur OO est de devenir une référence.
Mon avatar est un ambigramme, les curieux peuvent le retourner ;-)
Aider <> Faire a la place de!!!
XtofRoland est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/03/2006, 11h10   #10
Membre éclairé
 
Avatar de XtofRoland
 
Inscription : août 2005
Messages : 361
Détails du profil
Informations forums :
Inscription : août 2005
Messages : 361
Points : 340
Points : 340
Code :
1
2
3
4
5
//$msSQL = "SELECT top 20 WO_NUM, TASK, TYPE, STATUS ,'detail.php?num=' + cast( wo_num as char ) from TASKS WHERE TYPE IS NOT NULL AND STATUS = 'TERMINÉ' ";
 
$msSQL = strtoupper($msSQL);
 
preg_match_all('/(?:SELECT)\s([a-z0-9_]+)?\s?(?:ORDER BY\s)`?([a-z0-9_]*\s?)/i', $msSQL, $matches, PREG_SET_ORDER);
me retourne un tableau vide, vous savez pourquoi?
__________________
Le but de tout developpeur OO est de devenir une référence.
Mon avatar est un ambigramme, les curieux peuvent le retourner ;-)
Aider <> Faire a la place de!!!
XtofRoland est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/03/2006, 11h53   #11
Rédacteur
 
Avatar de Yogui
 
Homme Guillaume Rossolini
Directeur technique
Inscription : février 2004
Messages : 13 720
Détails du profil
Informations personnelles :
Nom : Homme Guillaume Rossolini
Localisation : France

Informations professionnelles :
Activité : Directeur technique

Informations forums :
Inscription : février 2004
Messages : 13 720
Points : 17 355
Points : 17 355
Arf, tu voudrais pas utiliser la balise code stp ?

Sinon, ne serait-ce pas parce que tu as mis ta chaîne en commentaires ?


Tu n'aimes pas la solution de maxoo ?

[Edit] La vraie réponse : la classe qui matche ce qui suit SELECT est "[a-z0-9_]", or tu utilises également d'autres signes comme "?", "+", etc.
Modifie la classe ou utilise la solution de maxoo (plus simple, c'est évident).

[Edit 2] Tu mets également une obligation de trouver "ORDER BY" alors qu'il n'y en a pas...
__________________
Mes articles - Zend Certified Engineer (PHP + Zend Framework)
Ressources PHP - Ressources Zend Framework
Yogui est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/03/2006, 13h59   #12
Membre éclairé
 
Avatar de XtofRoland
 
Inscription : août 2005
Messages : 361
Détails du profil
Informations forums :
Inscription : août 2005
Messages : 361
Points : 340
Points : 340
mon select est :
Code :
SELECT WO_NUM, TASK, TYPE, STATUS ,'DETAIL.PHP?NUM=' + CAST( WO_NUM AS CHAR ) FROM TASKS WHERE TYPE IS NOT NULL AND STATUS <> 'TERMINÉ' ORDER BY WO_NUM DESC
j'ai rajouté les caracteres manquants:

Code :
preg_match_all('/(?:SELECT)\s([a-z0-9_\'\?\+\.\=\(\)]+)?\s?(?:ORDER BY\s)`?([a-z0-9_]*\s?)/i', $msSQL, $matches, PREG_SET_ORDER);
mais ca ne va pas..

la solution de maxoo me donne tjrs :
Citation:
Parse error: parse error, expecting `')'' in h:\easyphp1-8\www\tfe\OO\msmaster.inc on line 16
l'adaptation qui me donne le resultat le plus proche est :
Citation:
preg_match_all('/(ORDER BY)\s+?([a-z0-9_]*\s?)/i',$msSQL,$resultat);

foreach($resultat as $brol) foreach( $brol as $r)echo $r."<br />";
elle m'affiche:
Citation:
ORDER BY WO_NUM
ORDER BY
WO_NUM
le DESC manque...
__________________
Le but de tout developpeur OO est de devenir une référence.
Mon avatar est un ambigramme, les curieux peuvent le retourner ;-)
Aider <> Faire a la place de!!!
XtofRoland est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/03/2006, 15h32   #13
Expert Confirmé
 
Avatar de Maxoo
 
Maxime Pasquier
Expert PHP
Inscription : novembre 2004
Messages : 2 126
Détails du profil
Informations personnelles :
Nom : Maxime Pasquier
Âge : 28
Localisation : France, Loire Atlantique (Pays de la Loire)

Informations professionnelles :
Activité : Expert PHP
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : novembre 2004
Messages : 2 126
Points : 2 602
Points : 2 602
Code :
1
2
3
4
<?
$SQL = "select * from table where qqq = 111";
preg_match(/(FROM|INTO|UPDATE)\s+(\w+)/i,$SQL,$resultat); //line 3
foreach($resultat as $brol) echo $brol.'<br />';
//Parse error: parse error, expecting `')'' in h:\easyphp1-8\www\index.php on line 3

Citation:
preg_match(/'(FROM|INTO|UPDATE)\s+(\w+)/i',$SQL,$resultat);
une parse error ca se trouve facilement quand même ... t'aurais pu chercher un peu
__________________
Pour une bien meilleur lisibilité, utilisez la balise [code], c'est le [#] dans votre éditeur.
Mon espace Développez : mes Créations.


Rencontre & Carte des Membres de Developpez.com, version 3.0
Maxoo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/03/2006, 15h59   #14
Membre éclairé
 
Avatar de XtofRoland
 
Inscription : août 2005
Messages : 361
Détails du profil
Informations forums :
Inscription : août 2005
Messages : 361
Points : 340
Points : 340
j'ai cherché! la preuve .... dans mon post precedent en mélangeant les deux preg j'ai essayé de faire ca:

l'adaptation qui me donne le resultat le plus proche est :
Citation:
preg_match_all('/(ORDER BY)\s+?([a-z0-9_]*\s?)/i',$msSQL,$resultat);

foreach($resultat as $brol) foreach( $brol as $r)echo $r."<br />";
__________________
Le but de tout developpeur OO est de devenir une référence.
Mon avatar est un ambigramme, les curieux peuvent le retourner ;-)
Aider <> Faire a la place de!!!
XtofRoland est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 20h36.


 
 
 
 
Partenaires

Hébergement Web