1. #1
    Nouveau membre du Club
    Profil pro
    Retraité
    Inscrit en
    avril 2004
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : avril 2004
    Messages : 29
    Points : 29
    Points
    29

    Par défaut Petits soucis de transmission de requête

    Bonjour;

    Je désire transmettre à une requête SQL le résultat d'un composant dbedit, cependant ma rédaction ( anciennement Delphi) ne fonctionne pas

    datamodule1.ZQuery_films.SQL.Add('where NUM_ENT =" ' + dbedit1.Text + ' " ' ) ;
    J'ai toujours une erreur, surement une histoire de guillemets

    Pour le moment j'ai contourné la difficulté en intercalant un Edit.text avec comme code

    edit1.Text:='where NUM_ENT =' + dbedit1.Text;
    with datamodule1.Zquery_films do
    datamodule1.Zquery_films.Close;
    datamodule1.ZQuery_films.SQL.Clear;
    datamodule1.ZQuery_films.SQL.LoadFromFile('query2.sql');
    datamodule1.ZQuery_films.SQL.Add (edit1.Text);

    Mais ce n'est pas top , merci de me corriger

  2. #2
    Membre averti
    Homme Profil pro
    Chef de projets retraité
    Inscrit en
    juillet 2011
    Messages
    188
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Chef de projets retraité
    Secteur : Transports

    Informations forums :
    Inscription : juillet 2011
    Messages : 188
    Points : 413
    Points
    413

    Par défaut

    Bonjour,

    Ce que je remarques comme différences entre les deux c'est l'utilisation de guillemets (") dans ta première expression et pas dans la seconde.

    Si ton champ n'est pas de formate texte, c'est probablement l'explication.

    NB. Tu ne vérifies rien dans ton champ est ce fait avant? Sinon attention aux injections SQL.

    Cordialement

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    avril 2010
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : avril 2010
    Messages : 153
    Points : 331
    Points
    331

    Par défaut

    Bonjour,

    En SQL une chaîne de caractères doit être encadrée de simples apostrophes. Mais pour transmettre une apostrophe en Pascal, cette apostrophe doit être doublée. Donc dans votre première forme, vous devriez remplacer vos guillemets par 2 simples apostrophes.
    Par ailleurs, pouvez-vous être sûr que dans votre champ dbedit1, le texte ne comprendra pas lui-même une apostrophe? QuotedStr(dbedit1.text) se charge d'encadrer le texte de simples apostrophes et de doubler celles qui s'y trouvent.
    Il existe aussi la possibilité de remplacer votre chaîne par un paramètre :machaine dans le texte de votre requête puis avant d'exécuter la requête de définir ParamByName('machaine').asstring qui se charge d'encadrer et doubler les apostrophes.

    André

  4. #4
    Membre expert
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    mai 2002
    Messages
    2 388
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : mai 2002
    Messages : 2 388
    Points : 3 735
    Points
    3 735

    Par défaut

    salut

    pour eviter ce genre d'ecueuille je recommende d'utiliser la fonction format

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DM.ZQuery_films.SQL.Add(Format('where NUM_ENT = %s ',[dbedit1.Text ]) ) ;
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  5. #5
    Membre expert Avatar de Jon Shannow
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    avril 2011
    Messages
    2 240
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : avril 2011
    Messages : 2 240
    Points : 3 566
    Points
    3 566

    Par défaut

    Bonjour,

    Tout ce qui dit avant est juste, mais, quid du type de champ NUM_ENT. Si c'est un numérique, ça explique que la seconde syntaxe fonctionne et pas la première.

    JS

    PS : Dans tous les cas, je préfère passer par des paramètres, comme l'a dit alanglet
    Au nom du pèze, du fisc et du St Estephe
    Au nom du fric, on baisse son froc...

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    avril 2010
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : avril 2010
    Messages : 153
    Points : 331
    Points
    331

    Par défaut

    Bonjour,

    Citation Envoyé par Jon Shannow Voir le message
    Tout ce qui dit avant est juste, mais, quid du type de champ NUM_ENT. Si c'est un numérique, ça explique que la seconde syntaxe fonctionne et pas la première.
    Effectivement, comme JCD59 cherchait dbEdit1.Text je pensais que NUM_ENT était du type VARCHAR. Si la deuxième forme proposée fonctionne, c'est que "hasard fait bien les choses", et que NUM_ENT est sans doute un entier. Mais pourquoi compliquer les choses en modifiant dbEdit1.Text? d'autant plus qu'il faut alors que ce champ soit éditable, et ça ne fonctionnera qu'une fois...

    Citation Envoyé par anapurna Voir le message
    pour éviter ce genre d'écueil je recommande d'utiliser la fonction format
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DM.ZQuery_films.SQL.Add(Format('where NUM_ENT = %s ',[dbedit1.Text ]) ) ;
    Ne fonctionnera également que si NUM_ENT est un entier, car la fonction format n'ajoute pas les apostrophes nécessaires si c'est une chaîne de caractères.

    André

  7. #7
    Membre expert
    Avatar de e-ric
    Homme Profil pro
    Traqueur de tritons et autres bestioles
    Inscrit en
    mars 2002
    Messages
    1 442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Traqueur de tritons et autres bestioles

    Informations forums :
    Inscription : mars 2002
    Messages : 1 442
    Points : 3 474
    Points
    3 474

    Par défaut

    Salut

    Deux remarques:
    - l'emploi d'un paramètre n'est pas vraiment une option et est largement préconisé (éviter les problèmes rencontrés ici), en outre, cela sécurise le code en rendant difficile une injection SQL (volontaire ou non)
    - le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    datamodule1.ZQuery_films.SQL.Add('where NUM_ENT =" ' + dbedit1.Text + ' " ' );
    pourrait être remplacé par quelques chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    datamodule1.SetPrmNumFilm(dbedit1.Text);
    méthode dans laquelle tu affectes le paramètre, afin de rendre le client du DataModule indépendant de l'implémentation de la recherche dans ce dernier. en effet, si dans le futur, tu dois remplacer Zeos par SQLdb, il te faudra revoir le DataModule, mais aussi tous les clients de ce DataModule.

    Voilà pour ma contribution de début de semaine.

    @+

    M E N S . A G I T A T . M O L E M
    Debian 8.x 64bit, Lazarus 1.6 (FPC 3.0), Python 3

    "La théorie, c'est quand on sait tout, mais que rien ne marche. La pratique, c'est quand tout marche, mais qu'on ne sait pas pourquoi. En informatique, la théorie et la pratique sont réunies: rien ne marche et on ne sait pas pourquoi!".
    Mais Emmanuel Kant disait aussi : "La théorie sans la pratique est inutile, la pratique sans la théorie est aveugle."

  8. #8
    Membre éprouvé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    septembre 2003
    Messages
    524
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : septembre 2003
    Messages : 524
    Points : 1 124
    Points
    1 124
    Billets dans le blog
    5

    Par défaut

    Bonjour,

    1 - Le premier point le plus important, il a été soulevé, à juste titre, par Jon Shannow, concerne le type de la colonne NUM_ENT tel qu'elle est est définie au niveau de la base de données. Quel est le type de la colonne NUM_ENT (s'agit-il d'un Integer, d'un Varchar, D'une Date, d'une Datetime, d'une Image etc. ? .
    NB : le type Image est là la juste pour la provocation ! Ceci dit tout est possible.

    Sinon on peut supposer que la colonne NUM_ENT est de type Integer, mais encore faut-il que cela soit confirmé (?)

    2 - Le 2ème point aussi important est l'utilisation des paramètres. Cela a été très bien rappelé par e-ric (L'utilisation des paramètres n'est pas une simple option, il y a là des considérations de sécurité, se prémunir des injections SQL etc..).

    3 - Le 3ème point hyper important, non évoqué ! il concerne les problèmes de performance dus aux éventuels transtypages implicites effectués au niveau de la base de données, lorsque l'argument ou le type du paramètre ne correspond pas ou n'est pas en cohérence avec le type de la colonne.

    Imaginons que la colonne NUM_ENT est de type INT (Integer) et que le développeur, lors de la construction de la requête SQL , n'a pas respecté le type de la colonne dans la clause de la restriction WHERE, et que, la requête finale exécutée sur le Serveur de base de données est la suivante
    SELECT Col1, Col2, ...
    FROM MaTable
    WHERE NUM_ENT = '1754'

    Certains Serveur de base de données ne vont 'brancher' et considéreront que la requête est syntaxiquement correcte. Ils vont toutefois effectuer un Transtypage implicite pour convertir la chaine '1754' en un integer 1754 . Le Transtypage implicite est généralement très néfaste pour les performances. Dans des cas extrêmes, l'expression de la clause WHERE, peut devenir "NON-SARG" (NON Searchable ARGument) c.à.d. aucun index existant, censés optimiser l'accès aux données, ne pourra être utilisé (1) ! un FULL SCAN sera effectué sur la table et si par "chance" la table contient plusieurs dizaines de millions de lignes la requête SQL au lieu de mettre quelque millisecondes, mettra plusieurs dizaines de minutes (exemple 30 ou 40 minutes !)
    PS : Je ne dis pas que dans le cas présent on passerait de quelques millisecondes à quelques dizaines de minutes, mais plus généralement, l'expérience montre que dès lors que l'on ne respecte pas le type des colonnes dans les expressions WHERE, il n'est pas rare que l'on s'expose à ce genre de situation catastrophique en terme de performance.

    (1) : En effet, l'optimiseur de requête, avant de décider de l'utilisation de tel ou tel index, se base sur les statistiques. Les statistiques établissent des échantillonnages sur les valeurs brutes des colonnes (et non pas sur des valeurs transformées par une quelconque fonction scalaire), et ce, pour en déterminer la densité et la sélectivité. Le Transtypage implicite est assimilable à une transformation par une fonction scalaire (Exemple sous ORACLE : TO_NUMBER( ... ) ou SQL Server : CAST( ... AS INT ) et donc les statistiques établies sur des valeurs brutes ne seront d'aucune utilité : CQFD.

    A+
    "Une idée mal écrite est une idée fausse !"
    http://hamid-mira.blogspot.com

  9. #9
    Nouveau membre du Club
    Profil pro
    Retraité
    Inscrit en
    avril 2004
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : avril 2004
    Messages : 29
    Points : 29
    Points
    29

    Par défaut

    Bonjour,

    Après quelques jours d'absence, je prends connaissance de vos réponses ce dont je vous remercie.

    Je viens d'en faire un rapide survol, et je vais approfondir.

    Comme certains l'ont supposé, NUM_ENT est bien de type integer, et c'est une clé primaire.

    J'avais transposé ma requête que j'avais utilisée avec une base Paradox sous Delphi 7

Discussions similaires

  1. Petit soucis de requête
    Par Lookoum dans le forum HyperFileSQL
    Réponses: 1
    Dernier message: 03/11/2009, 11h30
  2. Petit souci sur requête mysql
    Par Kisa-chan dans le forum Langage SQL
    Réponses: 8
    Dernier message: 03/02/2009, 21h07
  3. [Prototype] Petit souci avec une requête
    Par spy74 dans le forum Bibliothèques & Frameworks
    Réponses: 2
    Dernier message: 14/01/2009, 18h54
  4. Petit soucis avec une requête
    Par Jeetiz dans le forum Requêtes
    Réponses: 4
    Dernier message: 01/02/2007, 14h53
  5. Réponses: 3
    Dernier message: 17/03/2006, 11h18

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