Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1725 connectés 

  FORUM HardWare.fr
  Programmation
  Perl

  Perl: afficher le résultat d'une requête sql

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Perl: afficher le résultat d'une requête sql

n°2125108
furil
Posté le 06-02-2012 à 21:59:59  profilanswer
 

Bonsoir,
 
Je suis un débutant en Perl depuis 2 semaines environ et je dois dire que je suis bloqué sur un point. Tous d'abord l'OS sur lequel je suis est Debian squeeze, et mon problème provient du résultat que je veux obtenir. je n'arrive pas à l'afficher, pire je n'ai aucune erreur :s  
 
Le but est qu'a partir des données d'un fichier texte je remplisse les champs manquant de ma requête sql, que je l’exécute autant de fois qu'il y a de lignes.
 
Voici la requête SQL :
 

Code :
  1. my $requete_rrd = <<"SQL";
  2.         SELECT metrics.metric_id as metrique
  3.         FROM index_data, metrics
  4.         WHERE metrics.index_id = index_data.id
  5.         AND index_data.host_name = ?
  6.         AND index_data.service_description = ?


 
Et la partie du code Perl sur lequel j'ai des difficultés :
 

Code :
  1. je prépare la requête
  2. my $prep = $dbd->prepare($requete_rrd) or die $dbd->errstr;
  3. #je divise chaque ligne en 2 pour stocker le contenu dans
  4. #chacune des variables déclarées ci-dessous
  5. foreach $tabelement (@tab) {
  6.     my ( $nom_host, $nom_interface_choisie ) = split( ",", $tabelement );
  7.     $prep->execute( $nom_host, $nom_interface_choisie );
  8.     #je classe les résultats de la requête  dans un tableau
  9.     while ( my $ref_donnees = $prep->fetchrow_hashref ) {
  10.         push( @tab2, $ref_donnees->{metrique} );
  11.     }
  12.     print $tab2[0];
  13. }
  14. $prep->finish();
  15. close(FILE);


 
Admettons que le fichier texte contient ces deux lignes :
 
Supervision, ping
ServDNS, mémoire
 
La requête sql s’exécute et prends pour valeur :
index_data.host_name = Supervision
index_data.service_description = ping
 
Après l’exécution de la requête le résultat renvoyé est stocké dans un tableau, repart dans la boucle pour effectuer la même chose avec la seconde ligne puis affiche la "metric_id" correspondante à chaque "service_description".

Je vous remercie d'avance et bonne soirée :)

mood
Publicité
Posté le 06-02-2012 à 21:59:59  profilanswer
 

n°2125161
gilou
Modérateur
Modzilla
Posté le 07-02-2012 à 11:34:01  profilanswer
 

Bonjour,  
Le retour du $prep->execute est défini, et vaut une valeur non nulle?
Que donne un appel à $prep->err() après le $prep->fetchrow_hashref?
A+,


Message édité par gilou le 07-02-2012 à 11:34:20

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2125265
furil
Posté le 07-02-2012 à 21:13:42  profilanswer
 

Bonsoir,
 
Tout d'abord merci de votre réponse, ensuite j'ai choisi au final la méthode array et le problème venait du fichier texte en lui-même  :ange:  .
En effet, la particularité est qu'il y a retour chariot et j'ai complétement oublié donc de supprimer le dernier caractère pour la variable $nom_interface_choisie.
Pour répondre à ta question, oui pour prep -> execute la valeur est non nulle :)
 
Cependant je fais face à un nouveau problème (hé oui mais promis c'est le dernier pour ce script  :D ) . je vais détailler chaque partie pour faire simple :  
 

Code :
  1. foreach $tabelement (@tab) {
  2.  
  3.    #je vide d'abord le tableau avant le passage à la prochaine ligne#
  4.    @tab_donnees = ();
  5.  
  6.    my ( $nom_host, $nom_interface_choisie ) = split( ",", $tabelement );
  7.  
  8.    #le contenu de $nom_interface choisie sera utilisé sauf son dernier caract#
  9.    $prep->execute( $nom_host, substr( $nom_interface_choisie, 0, -1 ) )
  10.      or die "blabla";


jusqu'à l'execute pas de problème, je vide le tableau pour pouvoir faire autant de graphique qu'il y a de ligne :)
 
 

Code :
  1. while ( my $donnees = $prep->fetchrow_array ) {
  2. my $result;
  3. my $result2;
  4.        push( @tab_donnees, $donnees );    #insert dans un tableau permanent
  5.        $result  = $tab_donnees[0];
  6.        $result2 = $tab_donnees[1];


J'ai remplacé ici la méthode hashref par array (difficulté à comprendre la notion encore :) ) , les résultats (2 résultat plus précisément ex: 55 correspondant au ping, 56 à la mémoire, sachant qu'un service peut être lié à 2 fichiers) renvoyée par la requête sont stockées dans le tableau @tab_donnees. Pourquoi une variable pour une cellule?
La raison est simple, car je veux l'utiliser à la suite pour créer un graphique sachant que la plupart du temps 2 fichiers correspondent à un service.
 

Code :
  1. "rrdtool graph /home/vmdebian/training_script/graph_result/'$nom_interface_choisie'.png"
  2.              ." --start \$\(date -d\'16 january 2012 12:00\' +%s\) --width 800 --height 200 --color CANVAS#000000 --color BACK#101010"
  3.              ." --color FONT#C0C0C0 --color MGRID#80C080 --color GRID#808020 --color FRAME#808080 DEF:input=/var/lib/centreon/metrics/"
  4.              . $result
  5.              . "\.rrd:traffic_in:AVERAGE DEF:output=/var/lib/centreon/metrics/"
  6.              . $result2
  7.              . "\.rrd:traffic_out:AVERAGE LINE:input#7FFF00:\"In traffic\" AREA:output#0400ff:\"Out traffic\" \'GPRINT:input:AVERAGE:MOY %.2lf %s\'"
  8.              ." \'GPRINT:output:AVERAGE:MOY %.2lf %s\' \'GPRINT:input:LAST:ACTU %.2lf %s\' \'GPRINT:output:LAST:ACTU %.2lf %s\'"
  9.        );
  10.    }
  11.  
  12. }


 
Là c'est du bash, on remarque que j'utilise les variables perl précédemment citées. Le script bash a déjà été testé auparavant, il fonctionne, sauf pour le nom de l'image ce sera la première fois. Lorsque je lance tout ce jolie petit script perl il m'affiche une erreur, celle que $result2 n'est pas initialisé je l'ai fait une fois et cela n'a rien changé. Je suppose que si $result2 a un problème, $result aussi :x
 
Voilà si tu as une idée, tu es le bienvenu :)
Encore merci pour ton aide et bonne soirée
 
P.S : It's the only neet thing(...) = kamisama no memochou? :p


Message édité par gilou le 07-02-2012 à 23:28:35
n°2125279
gilou
Modérateur
Modzilla
Posté le 07-02-2012 à 23:24:32  profilanswer
 

A vue de nez, c'est quelque chose comme ceci que vous voulez, non?

Code :
  1. while ( my @donnees = $prep->fetchrow_array() ) {
  2. my $result;
  3. my $result2;
  4.        push( @tab_donnees, @donnees );    #insert dans un tableau permanent
  5.        $result  = @donnees[0];
  6.        $result2 = @donnees[1];


A+,
 
P.S. Tout a fait. :)


Message édité par gilou le 07-02-2012 à 23:30:21

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2125324
furil
Posté le 08-02-2012 à 10:50:19  profilanswer
 

Bonjour,
 
Encore merci pour l'aide :) .
Ensuite pour la variable "@donnees" pourrais-tu me dire pourquoi tu l'utilise de cette façon, je la déclare toujours comme "$donnees" vu que c'est la variable scalaire qui va tout récupéré afin de mettre le tout dans le tableau @tab_donnees. De plus le push, tu met un tableau dans un autre, cela n'en revient-il pas au-même?
j'ai essayé ta solution, lors de l'éxécution du script on me conseille de passer "@donnees" à "$donnees" et je te remercie de prendre le temps de répondre à mes questions :)  
Enfin j'ai trouvé une chose j'ai fais un print de $result et $result2 et j'ai remarqué que le tableau n'a pas été vidé, je pensais qu'il n'y aurait qu'à le réinitialiser au debut de la boucle (sachant qu'il est déclaré en dehors)  
D'où le problème de création du graphique si on met 2valeurs collées ensemble pour créer le graphique c'est sûr que ça marchera pas  :D .

Code :
  1. $tableau =();

cela ne suffit il pas pour vider le tableau?
 
Je cherche actuellement d'autres solutions pour vider le tableau, aprés avoir trouvé cette solution je pense que le script fonctionnera mieux .
 
Merci et bonne journée

n°2125370
gilou
Modérateur
Modzilla
Posté le 08-02-2012 à 12:44:21  profilanswer
 

$prep->fetchrow_array renvoie des choses distinctes selon que l'on l'utilise en contexte scalaire ou array, c'est dans la doc:

Citation :

@ary = $sth->fetchrow_array ();
When called in a list context, fetchrow_array() returns an array containing column values for the next row of the result set, or an empty array if there are no
more rows or an error occurred.To distinguish between normal exhaustion of the
result set and an error, check $sth->err() or $DBI::err.A value of zero indicates
that you’ve reached the end of the result set without error.
In a scalar context, fetchrow_array() returns one element of the array, or undef if
there are no more rows or an error occurred. However, it is undefined which element is returned; you can tell for sure only for statements that select a single column.Also, an undef return value in the absence of an error is ambiguous; it may
represent either a NULL column value or the end of the result set.

et ce me semble être le tableau que vous voulez exploiter.

Citation :

De plus le push, tu met un tableau dans un autre, cela n'en revient-il pas au-même?

Non, si c'est un scalaire que vous mettez dans le tableau, ça ne va y mettre qu'une seule valeur, pas plusieurs. Pour mettre un tableau dans un autre avec push, il faut que le second argument soit un tableau.
En Perl, un tableau ne peut pas être représenté par un scalaire. Tout au plus vous pouvez représenter une référence a un tableau par un scalaire.
my @tab; #un tableau
my $tabref = \@tab;  #une reference à @ tab, auquel on peut accéder comme @{$tabref}

Citation :

$tableau =();
cela ne suffit il pas pour vider le tableau?

vu que $tableau ne peut pas être un tableau (vu le $ initial), je ne sais pas comment perl comprends cela, mais il y a rien à vider.
 
Vous avez bien mis  
use strict;
use warnings;
en debut de script afin que l'interpréteur vous signale les erreurs?
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2125417
furil
Posté le 08-02-2012 à 14:47:02  profilanswer
 

Concernant :
 

Code :
  1. $tableau =();


faute de frappe
 

Code :
  1. @tableau = ();


 
bien sûr @tableau étant un exemple :)
 
Ensuite lors du parcours d'un tableau, je suis obligé d'utiliser le $
 

Code :
  1. while ( my @donnees = $prep->fetchrow_array ) {
  2.          my $result;
  3.          my $result2;
  4.          push( @tab_donnees, @donnees );    #insert dans un tableau permanent
  5.          $result  = $donnees[0];
  6.          $result2 = $donnees[1];
  7.          print $result;
  8.          print $result2;


 
puis concernant le print je remarque que $donnees[0] prend deux valeur , $donnees[1] n'en prend aucune alors que je veux que la première valeur soit dans $donnees[0] et la seconde valeur dans $donnees[1]
Par exemple :
J'ai le service interface il est composé de deux choses : le traffic entrant et le traffic sortant.
Chacun de ces traffics correspondent à une "metric_id" particulière(ex: metrics_id du traffic entrant =54, et sortant = 55), la méthode est bonne, cependant je retrouve les 2 metric_id de l'interface dans $donnees[0]  ( 5455) alors que je veux la metric_id du traffic entrant dans $donnees[0] (54) et la metric_id du traffic sortant (55) dans $donnees[1].
Je dois certainement utiliser une méthode de type split pour arranger ça mais comment l'utiliser s'il n'y a rien pour les séparés :x
Encore merci et bonne journée :)


Message édité par furil le 08-02-2012 à 14:53:47
n°2125433
furil
Posté le 08-02-2012 à 15:16:42  profilanswer
 

Si je fais comme ça :
 

Code :
  1. while ( my $donnees = $prep->fetchrow_array ) {
  2.           my $result;
  3.         my $result2;
  4.         push( @tab_donnees, $donnees );  #insert dans un tableau permanent
  5.         $result  = $tab_donnees[0];
  6.         $result2 = $tab_donnees[1];
  7.         print $result;


 
cela stocke (en reprenant l'exemple d'au-dessus) 5454 dans $tab_donnees[0] (aucune idée pourquoi 2 fois la même valeur uniquement pour cette cellule) et 55 dans $tab_donnees[1]
 
aprés la méthode est-elle la bonne par rapport à l'autre? ^^"
 
Maj: La méthode pour vider le tableau était mauvaise j'ai remplacé par :
 

Code :
  1. @nomdutableau=undef;  #juste aprés la création du graphique


 
Résultat le coup de la valeur noté deux fois dans la 1ere cellule a disparu :)
 
Malgré le bon affichage, j'ai cette erreur pour chaque cellule que je met en print :
 
Use of uninitialized value $result in print at fifi.pl line 68, <FILE> line 2
 
La ligne 68 correspondant a l'affichage du contenu de la cellule (ici $result)
 
Merci d'avance pour ton aide :)


Message édité par furil le 08-02-2012 à 15:31:52
n°2125444
gilou
Modérateur
Modzilla
Posté le 08-02-2012 à 15:44:45  profilanswer
 

Citation :

Maj: La méthode pour vider le tableau était mauvaise j'ai remplacé par :

Non non,  
@nomdutableau=undef; ça met l'objet tableau à null
@nomdutableau=undef; ça met l'objet tableau à une liste vide.
Dans les deux cas, ça vide le tableau.
 

Citation :

puis concernant le print je remarque que $donnees[0] prend deux valeur , $donnees[1] n'en prend aucune alors que je veux que la première valeur soit dans $donnees[0] et la seconde valeur dans $donnees[1]

Si le résultat d'un fetchrow_array renvoie tout dans un seul élémént, alors il va falloir splitter le contenu de cet élément selon ce qui vous arrange.
Tout je que je sais, c'est que ce qui est renvoyé est le champ metrics.metric, je ne sais pas ce qu'il y a dans ce champ, c'est vous qui devez connaitre la structure des données et savoir si le contenu d'un champ doit être splitté.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2125464
furil
Posté le 08-02-2012 à 17:42:12  profilanswer
 

Bon grâce à toi je sais comment avancer dans le script correctement et j'ai pu apprendre quelques notions. Je posterai la partie du script corrigé lorsqu'il sera terminé.
Donc merci, bonne soirée et à la prochaine. :)

mood
Publicité
Posté le 08-02-2012 à 17:42:12  profilanswer
 

n°2125468
gilou
Modérateur
Modzilla
Posté le 08-02-2012 à 18:06:08  profilanswer
 

Bonsoir :)
 
Note: je pense que $prep->fetchrow_array ca renvoie ses données dans un array quand le select renvoie plusieurs champs, chacun étant dans un element de l'array.
Quand le select renvoie un seul champ, il est probable que ca doit aussi marcher avec un scalaire, mais il faut tester.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2125787
furil
Posté le 10-02-2012 à 09:06:15  profilanswer
 

Bonjour,
 
Comme promis voici le script :)  
 
 

Code :
  1. while ( my @donnees = $prep->fetchrow_array ) {
  2.           #tout le contenu présent dans @donnees est stocké dans @tab_donnees
  3.           push( @tab_donnees, @donnees );    #insert dans un tableau permanent
  4.       }
  5.       my $result  = '';
  6.       my $result2 = '';
  7.       $result  = $tab_donnees[0];
  8.       $result2 = $tab_donnees[1];


 
Pour la répétition de la même valeur, c'était juste le mauvais tableau qui a été utilisé : @tab_donnees au lieu de @donnees
Ensuite le graphique était placé au mauvais endroit, il fallait effectuer l'éxécution en dehors de la boucle while et déclarer(+ initialiser) les variables $result et $result2 aussi.
Tout ce jolie script dont la boucle while se trouve dans la boucle foreach citée plus haut. Car l'execution concerne chaque ligne du fichier copier dans le tableau.
Enfin pour le problème du nom du graphique créer, c'était juste un problème de casse, il fallait donc substituer la partie du nom qui ne passait pas avec la méthode suivante :
exemple : remplacer london par London
 
 

Code :
  1. $nomdelavariable=~ s/london/London/;


 
Voilà j'espère que cela sera utile aux gens qui ont des problèmes de ce genre :)
 
Bonne journée et encore merci pour l'aide apportée :)


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Perl

  Perl: afficher le résultat d'une requête sql

 

Sujets relatifs
Performances Curseur / Complexité requête SQLAfficher une UserForm en fonction de la valeur de "Listindex"
[bash] ajouter le résultat d'une commande à une ligne dans un fichierGestion d'une Requête SQL grâce à JCBD
recherche logiciel libre pour formulaire, retour requêteRequête SQL
Que renvoi une requête SQL en C++ ?[PERL] supprimer unicode \\u0003
Besoin d'aide pour création d'une requête complexe (MySQL)[resolue] impossible d'afficher des images sur un spring MVC
Plus de sujets relatifs à : Perl: afficher le résultat d'une requête sql


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR