IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Requêtes MySQL Discussion :

Requête SQL dans un script Perl


Sujet :

Requêtes MySQL

  1. #1
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 103
    Par défaut Requête SQL dans un script Perl
    Bonjour,

    J'ai un script Perl sous la main qui est censé prendre certaines informations de 2 tables en même temps et les retranscrire dans une autre table (vide en l'occurrence). Cependant, cette requête comporte une erreur de syntaxe MySQL. La voici ci-dessous :

    Code perl : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    eval { $dbh->do("REPLACE INTO userlog (id, raw_mac, ip_saddr, ip_daddr, ip_protocol, tcp_sport, tcp_dport, 
    udp_sport, udp_dport, timestamp, username) (SELECT u.'id', r.'callingstationid' AS raw_mac, 
    INET_NTOA(u.'ip_saddr') AS ip_saddr, INET_NTOA(u.'ip_daddr') AS ip_daddr, u.'ip_protocol', u.'tcp_sport', u.'tcp_dport', 
    u.'udp_sport', u.'udp_dport', u.'timestamp', r.'username' FROM ulog u, radacct r 
    WHERE (u.'timestamp' = r.'acctstarttime' OR u.'timestamp' > r.'acctstarttime') 
    AND ((u.'timestamp' = r.'acctstoptime') OR (u.'timestamp' < r.'acctstoptime') OR (r.'acctstoptime' IS NULL)) 
    AND (u.'ip_saddr' = INET_ATON(r.'framedipaddress'))) 
    AND (TO_DAYS(NOW()) - TO_DAYS(u.'timestamp') < 7)") };

    L'erreur que me signale MySQL se trouverait apparemment près de la dernière ligne au niveau de :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AND (TO_DAYS(NOW()) - TO_DAYS(u.'timestamp') < 7)") };
    J'ai tenté de changer la position d'une parenthèse fermante mais phpMyAdmin a planté après cela ... (en indiquant la table userlog "marked as crashed").

    Quelqu'un voit-il ce qui cloche ?

  2. #2
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 814
    Billets dans le blog
    14
    Par défaut
    Isole le texte de la requête, indente la correctement et trouveras l'erreur : il semble qu'il y ait une parenthèse en trop. Voilà ce que c'est de vouloir mettre des parenthèses partout !

    Les jointures s'écrivent depuis 20 ans avec l'opérateur JOIN ; il serait temps de s'y mettre !

    Ce qui m'étonne aussi c'est que les noms de colonnes sont entourés d'apostrophes (alors qu'elles sont ici presque inutiles car les colonnes sont correctement nommées, sauf "timestamp" qui doit être entourée d'apostrophes inversées). MySQL interprétera ça comme un texte et donnera probablement une autre erreur.

    Pas terrible cette requête ! Pour ne pas dire pire !

    D'ailleurs, j'ai du mal à la comprendre.
    Il semble qu'il y ait une condition de jointure u.`timestamp` = r.acctstarttime mais dans le WHERE on trouve OR u.`timestamp` > r.acctstarttime ainsi que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    OR (u.`timestamp` < r.acctstoptime)
    !
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  3. #3
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 103
    Par défaut
    Autant le dire tout de suite : la présente requête n'est en aucun cas le fruit d'un de mes travaux ! Je suis chargé de la reprendre car le script Perl contenant cette requête est lancé chaque jour à minuit mais ne fais strictement rien si ce n'est planter phpMyAdmin.

    Aussi, pour la condition de jointure, il faut bien distinguer "acctSTARTtime" et "acctSTOPtime"

    J'ai quand même du mal à comprendre en quoi la dernière ligne est louche pour l'interpréteur MySQL ...

  4. #4
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 814
    Billets dans le blog
    14
    Par défaut
    Citation Envoyé par Gannox Voir le message
    Aussi, pour la condition de jointure, il faut bien distinguer "acctSTARTtime" et "acctSTOPtime"
    Oups ! Au temps pour moi !

    J'ai quand même du mal à comprendre en quoi la dernière ligne est louche pour l'interpréteur MySQL ...
    Comme je l'ai dit, il y a une parentèse en trop, juste avant je crois. Je n'ai pas réeesayé de remettre en forme cette requête mais il me semble me souvenir que la dernière condition se retrouve en dehors de la sous-requête à cause de cette parenthèse en trop.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  5. #5
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 103
    Par défaut
    Bonjour,

    J'ai compté et il y a autant de parenthèses ouvrantes que de parenthèses fermantes visiblement. J'ai essayé de modifier l'emplacement d'une parenthèse fermante (coloriée en rouge) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    eval { $dbh->do("REPLACE INTO userlog (id, raw_mac, ip_saddr, ip_daddr, ip_protocol, tcp_sport, tcp_dport, 
    udp_sport, udp_dport, timestamp, username) (SELECT u.'id', r.'callingstationid' AS raw_mac, 
    INET_NTOA(u.'ip_saddr') AS ip_saddr, INET_NTOA(u.'ip_daddr') AS ip_daddr, u.'ip_protocol', u.'tcp_sport', u.'tcp_dport', 
    u.'udp_sport', u.'udp_dport', u.'timestamp', r.'username' FROM ulog u, radacct r 
    WHERE (u.'timestamp' = r.'acctstarttime' OR u.'timestamp' > r.'acctstarttime') 
    AND ((u.'timestamp' = r.'acctstoptime') OR (u.'timestamp' < r.'acctstoptime') OR (r.'acctstoptime' IS NULL)) 
    AND (u.'ip_saddr' = INET_ATON(r.'framedipaddress'))) 
    AND (TO_DAYS(NOW()) - TO_DAYS(u.'timestamp') < 7)") };
    Je l'ai mise instinctivement à cet endroit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    eval { $dbh->do("REPLACE INTO userlog (id, raw_mac, ip_saddr, ip_daddr, ip_protocol, tcp_sport, tcp_dport, 
    udp_sport, udp_dport, timestamp, username) (SELECT u.'id', r.'callingstationid' AS raw_mac, 
    INET_NTOA(u.'ip_saddr') AS ip_saddr, INET_NTOA(u.'ip_daddr') AS ip_daddr, u.'ip_protocol', u.'tcp_sport', u.'tcp_dport', 
    u.'udp_sport', u.'udp_dport', u.'timestamp', r.'username' FROM ulog u, radacct r 
    WHERE (u.'timestamp' = r.'acctstarttime' OR u.'timestamp' > r.'acctstarttime') 
    AND ((u.'timestamp' = r.'acctstoptime') OR (u.'timestamp' < r.'acctstoptime') OR (r.'acctstoptime' IS NULL)) 
    AND (u.'ip_saddr' = INET_ATON(r.'framedipaddress')) 
    AND (TO_DAYS(NOW()) - TO_DAYS(u.'timestamp') < 7))") };
    Cette modification a fait planté phpmyadmin et ma table ! Le temps de chargement de la requête est interminable et n'aboutit pas.

  6. #6
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 814
    Billets dans le blog
    14
    Par défaut
    Il ne suffit pas de compter les aprenthèses !
    bis repetita :
    Isole le texte de la requête, indente la correctement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    REPLACE INTO userlog (id, raw_mac, ip_saddr, ip_daddr, ip_protocol, tcp_sport, tcp_dport,
    udp_sport, udp_dport, `timestamp`, username)
    (
    	SELECT u.id, r.callingstationid AS raw_mac,
    		INET_NTOA(u.ip_saddr) AS ip_saddr,
    		INET_NTOA(u.ip_daddr) AS ip_daddr,
    		u.ip_protocol, u.tcp_sport, u.tcp_dport,
    		u.udp_sport, u.udp_dport, u.`timestamp`, r.username
    	FROM ulog u, radacct r
    	WHERE
    	(
    		u.`timestamp` = r.acctstarttime
    		OR u.`timestamp` > r.acctstarttime
    	)
    	AND
    	(
    		(u.`timestamp` = r.acctstoptime)
    		OR
    		(u.`timestamp` < r.acctstoptime)
    		OR
    		(r.acctstoptime IS NULL)
    	)
    	AND
    	(u.ip_saddr = INET_ATON(r.framedipaddress))
    )
    -- C'EST LÀ QUE ÇA COINCE !!
    AND (TO_DAYS(NOW()) - TO_DAYS(u.'timestamp') < 7)
    Mais cette requête reste horrible !
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  7. #7
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 103
    Par défaut
    Heu ... ce post ne fait que répéter ce que je sais déjà

    J'ai signalé que j'ai pensé à changer de place la parenthèse fermante du select mais sans résultat car ça plante. J'ai également changé de syntaxe pour avoir les 7 derniers jours :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    REPLACE INTO userlog (id, raw_mac, ip_saddr, ip_daddr, ip_protocol, tcp_sport, tcp_dport,
    udp_sport, udp_dport, `timestamp`, username)
    (
    	SELECT u.id, r.callingstationid AS raw_mac,
    		INET_NTOA(u.ip_saddr) AS ip_saddr,
    		INET_NTOA(u.ip_daddr) AS ip_daddr,
    		u.ip_protocol, u.tcp_sport, u.tcp_dport,
    		u.udp_sport, u.udp_dport, u.`timestamp`, r.username
    	FROM ulog u, radacct r
    	WHERE
    	(
    		u.`timestamp` = r.acctstarttime
    		OR u.`timestamp` > r.acctstarttime
    	)
    	AND
    	(
    		(u.`timestamp` = r.acctstoptime)
    		OR
    		(u.`timestamp` < r.acctstoptime)
    		OR
    		(r.acctstoptime IS NULL)
    	)
    	AND
    	(u.ip_saddr = INET_ATON(r.framedipaddress))
            AND 
            (u.`timestamp` BETWEEN DATE_SUB(CURDATE(), INTERVAL 7 DAY) AND CURDATE())
    )
    Mais sans résultats car ça continue de planter ... La requête n'arrive pas à s'exécuter, le temps de chargement est interminable et je ne sais pas ce qui provoque cela.

  8. #8
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 814
    Billets dans le blog
    14
    Par défaut
    Les tables sont-elles correctement indexées ?
    Quel est leur volume ?
    As-tu essayé d'OPTIMIZEr les tables ?
    Le serveur est-il suffisamment dimensionné ?
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  9. #9
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 103
    Par défaut
    Les tables sont correctement indexées, aucun problème de ce côté-là.

    La table ulog comporte plusieurs millions d'enregistrements et la table radacct en possède 20 000 grossomodo.

    Je n'ai pas essayé la commande OPTIMIZE car je ne la connaissais pas.

    Le serveur est suffisamment dimensionné (source : mon tuteur).

  10. #10
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 814
    Billets dans le blog
    14
    Par défaut
    Dans la mesure où c'est une requête qui ne comporte aucun paramètre, as-tu essayé de la lancer directement dans MySQL, hors du script Perl ?
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  11. #11
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 103
    Par défaut
    C'est ce que je fais depuis le début, même erreur pour les 2 manières de faire et temps de chargement interminable pour les 2 si je modifie la condition de date.

  12. #12
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 814
    Billets dans le blog
    14
    Par défaut
    Donne la structure complète des tables (résultat complet de SHOW CREATE TABLE la_table).
    Donne aussi le résultat de l'EXPLAIN de la sous-requête SELECT.

    Essaie avec cette sous-requête écrite avec la jointure moderne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    SELECT u.id, r.callingstationid AS raw_mac,
    	INET_NTOA(u.ip_saddr) AS ip_saddr,
    	INET_NTOA(u.ip_daddr) AS ip_daddr,
    	u.ip_protocol, u.tcp_sport, u.tcp_dport,
    	u.udp_sport, u.udp_dport, u.`timestamp`, r.username
    FROM ulog u
    INNER JOIN radacct r
    	ON u.`timestamp` >= r.acctstarttime
    	AND
    	(
    		u.`timestamp` <= r.acctstoptime
    		OR r.acctstoptime IS NULL
    	)
    WHERE u.ip_saddr = INET_ATON(r.framedipaddress)
    	AND u.`timestamp` BETWEEN DATE_SUB(CURRENT_DATE, INTERVAL 7 DAY) AND CURRENT_DATE
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  13. #13
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 103
    Par défaut
    On dirait que ta chère jointure moderne fait des miracles ! J'ai un résultat dans ma base de données à l'aide de ta proposition de sous-requête. Le temps d'exécution a été très long mais les ajouts ont été effectués.

    Merci pour le coup de main, le problème semble être résolu.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [MySQL] Requête SQL dans un script
    Par brunochp dans le forum PHP & Base de données
    Réponses: 27
    Dernier message: 20/03/2009, 09h19
  2. [SQL] PB requête SQL dans un script php et sous phpmyadmin
    Par badboys46 dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 22/06/2007, 11h36
  3. [MySQL] Requête sql dans un script php
    Par ceaser dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 25/05/2007, 14h01
  4. [SQL] Traitement de plusieurs requêtes .SQL dans un script PHP?
    Par M4x dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 19/03/2006, 19h59
  5. [MySQL] Problème de requêtes SQL dans un script
    Par Nefret dans le forum PHP & Base de données
    Réponses: 8
    Dernier message: 08/09/2005, 15h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo