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

WinDev Discussion :

Intercepter une requête SQL


Sujet :

WinDev

  1. #1
    R&B
    R&B est déconnecté
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Mars 2005
    Messages : 571
    Points : 1 263
    Points
    1 263
    Par défaut Intercepter une requête SQL
    Bonjour,

    Dans une classe, je lance une requête avec l'option d'interruption disponible.
    Ainsi, quand la requête prends trop de temps l'utilisateur peut utiliser la touche Echap. pour stopper la lecture et affiner le critère de sélection.

    J'ai toutefois encore un problème, c'est que cette méthode est utilisée dans une fenêtre avec un bouton de type "abandon" aussi déclenché par la touche Echap.

    Devinez ! La touche d'interruption de la requête suspend bien son exécution, libère la méthode car je sort et... déclenche le bouton de type abandon (qu'il soit visible, grisé ou dans un autre plan...).

    C'est à croire que l'interruption est traitée par le processus de la requête, mais que l'entrée dans le buffer clavier n'est pas supprimée, ce qui lance l'évènement de la fenêtre appelante (j'ai testé plusieurs fenêtre).

    Savez vous, à défaut, supprimer la dernière touche dans le buffer clavier pour éviter le déclenchement de l'évènement associé ?
    Sinon je suis dans une impasse.

    NB : l'erreur HErreur()=70299 (interruption utilisateur) est bien déclenchée et peut servir de placement de code qui intercepte cette touche dans la fenêtre appelante

  2. #2
    Membre expérimenté
    Inscrit en
    Août 2010
    Messages
    732
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 732
    Points : 1 653
    Points
    1 653
    Par défaut
    Bonjour,

    Et bien dans le code du bouton d'abandon vous pouvez simplement tester un booléen, non ?

    Sinon vous pourriez intercepter WM_KEYDOWN et renvoyer 0 dans le cas où vous voulez inhiber la touche (renvoyer une valeur arrête la transmission du message). Mais ça serait plus compliqué.

  3. #3
    R&B
    R&B est déconnecté
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Mars 2005
    Messages : 571
    Points : 1 263
    Points
    1 263
    Par défaut
    Merci Hibernatus.

    Le truc c'est de ne pas modifier toutes les fenêtres utilisant la méthode ce cette classe qui lance la requête interruptible.

    Le WM_keydown doit justement être disponible pour envoyer l'interruption au moteur HF.
    Le hic c'est que le moteur HF ne supprime pas la touche dans le buffer clavier et la laisse ainsi... qui se trouve alors traitée par la fenêtre ayant le focus.

    Nous avons trouvé une parade efficace mais qui ne me plait en rien (car le pb de ne pas libérer la touche dans le buffer demeure un souci) : utiliser une fenêtre fille avec un joli libellé de patience et un bouton de type abandon. on ouvre la fenêtre fille et lui donne le focus avant de lancer la requête.
    l'interruption se fait, le bouton Echapp est traité par la fenêtre fille et on rends la main à la fenêtre parente. Efficace mais peut satisfaisant.

  4. #4
    Membre confirmé Avatar de jimmypage
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    314
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2006
    Messages : 314
    Points : 474
    Points
    474
    Par défaut
    Salut,

    En effet tu peux ajouter l'evenement WM_KEYDOWN sur ta fenetre.
    Du coup tu met un bouton normal (pas abandon) avec ton code de fermeture de fenetre.
    et dans la procedure de l'evenement tu met :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SI requeteEncours=vrai ALORS
       RENVOYER vrai
    SINON
       //Appel du bouton quitter
    FIN
    ca ne marcherait pas ?

  5. #5
    Membre expérimenté
    Inscrit en
    Août 2010
    Messages
    732
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 732
    Points : 1 653
    Points
    1 653
    Par défaut
    Je n'utilise pas HF donc je n'utilise pas les requêtes "interruptibles".
    Mais est-ce que vous les exécutez en parallèle ou en bloquant ?

    Je trouve que l'intrusion est faible avec le booléen dans le code du bouton, il s'agit de rajouter ceci au début :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SI gbReqInterrompue ALORS
    	gbReqInterrompue = Faux
    	RETOUR
    FIN
    Il y aussi un peu de code à l'exécution de la requête (que vous pouvez factoriser)

    Autrement, j'ai testé l'interception de WM_KEYDOWN et malheureusement ça passe avant l'interruption de la requête. Je ne sais pas si un HAnnuleDéclaration est alors aussi "propre" que l'interruption par Esc.
    Si vous êtes prêt à faire de la bidouille (je déconseille), voici une solution non intrusive :
    Dans une classe ou bien une collection de procédure :

    Code de déclaration :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    gbReqEnCours est un booléen	= Faux
    gsNomReqEnCours est une chaîne
    Fonction 1 :
    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
    PROCEDURE ExecReqInterrupt(sdReq, sCodeSQL, bBloquant = Faux)
    SI gbReqEnCours ALORS
    	RENVOYER Faux
    FIN
    nEvt est un entier = Evénement(EVENT_KeyDown, "*.*", 0x0100)
    SI HExécuteRequêteSQL(sdReq, hRequêteInterruptible,sCodeSQL) ALORS
    	gbReqEnCours = Vrai
    	gsNomReqEnCours = sdReq..Nom
    	TANTQUE PAS sdReq..ExécutionTerminée
    		Multitâche(bBloquant ? 0 SINON -1)
    	FIN
    	RENVOYER HErreur() = 0
    FIN
    RENVOYER Faux
     
    FIN:
    FinEvénement(nEvt)
    gbReqEnCours = Faux
    gsNomReqEnCours = ""
    Fonction 2 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    PROCEDURE EVENT_KeyDown(nMsg <utile>, nWParam, nLParam <utile>)
    SI nWParam = 0x1B ALORS
    	SI gbReqEnCours ALORS
    		HAnnuleDéclaration(gsNomReqEnCours)
    		RENVOYER 0
    	FIN
    FIN
    C'est un code quick & dirty, à vous de le corriger.
    Moi je n'aimerais pas avoir ça dans mon projet.

    Donc après il suffit d'utiliser ExecReqInterrupt à la place de HExecuteRequêteSQL.


    PS. Oubliez ce que vous appelez "buffer", il ne s'agit pas de ça, mais de la transmission d'un seul message au sein de l'appli.

    PS2. Peut-être avez-vous une solution plus simple dans le cas d'une exécution bloquante avec un simple MaFenêtre..Etat = AffichageSeulement avant et MaFenêtre..Etat = Actif après par exemple.
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    MaFenêtre..Etat = AffichageSeulement
    HExécuteRequêteSQL(sdReq, hRequêteInterruptible, "SELECT * FROM toto")
    HNbEnr(sdReq) // Bloquant
    Multitâche(-1) // Vide les messages
    MaFenêtre..Etat = Actif
    Tout ça peut être dans une fonction globale.

  6. #6
    R&B
    R&B est déconnecté
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Mars 2005
    Messages : 571
    Points : 1 263
    Points
    1 263
    Par défaut
    j'ai compris l'idée et je tâche de la mettre en place avec un bémol : l'interception de l'évènement des touches me stoppe la validation du champ qui déclenche la saisie...

    en gros, depuis le début de mes recherches sur ce sujet : à chaque solution un problème survient... ça me suffit pour ce soir. Autant dormir un coup et y voir plus clair demain.

    Merci

  7. #7
    Membre expérimenté
    Inscrit en
    Août 2010
    Messages
    732
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 732
    Points : 1 653
    Points
    1 653
    Par défaut
    Je ne comprends pas.
    Avec la solution de WM_KEYDOWN je n'intercepte que VK_ESCAPE et que dans un seul cas, tout le reste fonctionne comme d'habitude, et je ne bloque que le la réentrance dans la fonction qui lance la requête.

    J'ai testé ce code et pendant l'exécution de la requête l'IHM fonctionne normalement : saisie dans un champ, boutons etc.
    D'ailleurs ça pose un souci : si l'utilisateur clique sur un bouton qui ferme la fenêtre exécutrice, vous aurez un plantage.

    Ensuite, pouvez-vous préciser explicitement si l'IHM doit être accessible pendant l'exécution ou pas ?

    Si la seule action possible pendant l'exécution est l'annulation de la requête, alors vous pouvez créer une fenêtre d'attente dédiée, qui est modale, exécute la requête qu'on lui passe, et dispose d'un bouton d'annulation.

    Pour finir, j'ai un peu testé HAnnuleDéclaration et ça ne semble pas pire que la touche Echap. On peu voir un thread se créer à l'exécution d'une première requête, il n'est pas détruit à l'interruption, ni par Echap ni par HAnnuleDéclaration. Mais le nombre de thread n'augmente pas pour autant lors des exécutions suivantes.
    La doc ne dit rien à ce sujet.

  8. #8
    Membre confirmé Avatar de jimmypage
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    314
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2006
    Messages : 314
    Points : 474
    Points
    474
    Par défaut
    Bizarre.. vous avez bien le ?

    normalement tu ne dois intercepter que la touche echap ..

  9. #9
    Membre expérimenté
    Inscrit en
    Août 2010
    Messages
    732
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 732
    Points : 1 653
    Points
    1 653
    Par défaut
    Citation Envoyé par jimmypage Voir le message
    Bizarre.. tu as bien le ?

    normalement tu ne dois intercepter que la touche echap ..
    VK_ESCAPE = 0x1B
    http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx

  10. #10
    Membre confirmé Avatar de jimmypage
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    314
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2006
    Messages : 314
    Points : 474
    Points
    474
    Par défaut
    Citation Envoyé par Hibernatus34 Voir le message
    Oui, c'est bien ce que je dis .. que le fait que l'on n'intercepte que la touche echap donc c'est bizarre que ca lui coupe ses autres traitements.. Je me suis surement mal axprimé

  11. #11
    R&B
    R&B est déconnecté
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Mars 2005
    Messages : 571
    Points : 1 263
    Points
    1 263
    Par défaut
    OK,

    on a fini par lancer une fenêtre style info() quand, dans la méthode qui lance la requête on a l'erreur HF 70299 ou la propriété d'exécution terminée de la requête a vrai :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SI HErreur()=70299 _OU_ sSQL..ExécutionTerminée ALORS
    	Info("Arrêt de la recherche en cours .....!") // fenêtre surchargée
    	HAnnuleDéclaration(sSQL)
    	RENVOYER ""
    FIN
    on a donc un effet visuel qui affiche la petite fenêtre avec un message qui indique l'arret (et occasionnellement pends en compte le Esc rémanent) pour rendre la main tout proprement.

    Vu qu'avant l'ouverture de la fenêtre info le Esc qui lance sa fermeture est déjà pret, on a a peine le temps de voir la fenêtre et tout revient en ordre.

    le tout sans ajout de booléen, ni modif des fenêtre utilisant la méthode de la classe.

    Autre solution évoquée et viaualisée juste en tappant ces lignes :

    Ouvrir une fenêtre invisible avec un bouton esc + message, multitache(100), puis fermeture si la fenêtre est encore active...

    on n'a plus l'effet visuel et le Esc est traité.

Discussions similaires

  1. Intercepter une requête SQL d'un client vers un serveur
    Par AndroJex dans le forum Développement
    Réponses: 3
    Dernier message: 13/12/2012, 15h15
  2. Intercepter une requête SQL sous Oracle 9i
    Par cch02 dans le forum Oracle
    Réponses: 4
    Dernier message: 21/07/2010, 15h03
  3. Utilisation de MAX dans une requête SQL
    Par Evil onE dans le forum Langage SQL
    Réponses: 7
    Dernier message: 15/06/2004, 19h38
  4. Résultat d'une requète SQL
    Par camino dans le forum Bases de données
    Réponses: 2
    Dernier message: 21/02/2004, 16h22
  5. A propos d'une requête SQL sur plusieurs tables...
    Par ylebihan dans le forum Langage SQL
    Réponses: 2
    Dernier message: 14/09/2003, 17h26

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