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

C++Builder Discussion :

Erreur quand j'encode un Tedit dans une bdd sql


Sujet :

C++Builder

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    593
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 593
    Par défaut Erreur quand j'encode un Tedit dans une bdd sql
    Voila je viens de trouver un bug a mon programme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    AnsiString modelchoisi=ComboBox4->Text;
    					AnsiString prixachat=Edit4->Text;
    					AnsiString prixventes=Edit5->Text;
    					AnsiString stock=Edit6->Text;
    					AnsiString sql("INSERT INTO `produits` (`Reference`,`Genres`,`Types`,`Marques`,`Model`,`PrixAchats`,`PrixVentes`,`Stock`) VALUES ('"+ref+"','"+genrechoisi+"','"+typechoisi+"','"+marquechoisi+"','"+modelchoisi+"','"+prixachat+"','"+prixventes+"','"+stock+"');");
    					SQLQuery1->Active=false;
    					SQLQuery1->Close();
    					SQLQuery1->SQL->Clear();
    					SQLQuery1 ->SQL->Add(sql);
    					SQLQuery1->ExecSQL();
    le probléme est que si je rentre une marque ou un model avec des ' il me marque une erreur et plante :s

  2. #2
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2003
    Messages
    332
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2003
    Messages : 332
    Par défaut
    Salut,

    Cette erreur est normale avec les (') et SQL.
    Je crois si je ne dis pas de bêtise, que tu devrais remplacer les (') par (\').

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    593
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 593
    Par défaut
    je vais essayer de suite

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    593
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 593
    Par défaut
    non ca ne marche pas

  5. #5
    Expert confirmé

    Avatar de pottiez
    Homme Profil pro
    Développeur C++
    Inscrit en
    Novembre 2005
    Messages
    7 152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur C++
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2005
    Messages : 7 152
    Par défaut
    Bonjour,
    déjà si tu pouvais nous donner l'intitulé de l'erreur, ça aiderais.

    Sinon il me semble que dans le debut de ta requete tu met de ' alors qu'il n'y en as pas besoin pour les noms de tables et de colonnes en SQL, seulement pour les données :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     AnsiString sql("INSERT INTO produits (Reference,Genres,Types,Marques,Model,PrixAchats,PrixVentes,Stock) VALUES ('"+ref+"','"+genrechoisi+"','"+typechoisi+"','"+marquechoisi+"','"+modelchoisi+"','"+prixachat+"','"+prixventes+"','"+stock+"');");

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    593
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 593
    Par défaut
    Voici l'erreur :

    Exception déclenchée à $7C812A7B. Classe d'exception TDBXError avec message 'Erreur de syntaxe près de 'eau de pluit,'0','0','0')' à la ligne 1'. Processus Project1.exe (3280)
    j'avais rentrer : l'eau de pluit

  7. #7
    Expert confirmé

    Avatar de pottiez
    Homme Profil pro
    Développeur C++
    Inscrit en
    Novembre 2005
    Messages
    7 152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur C++
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2005
    Messages : 7 152
    Par défaut
    Alors je peut te dire tout de suite que lorsque tu rentre tes données dans ton TEdit, lorsque tu récupère tes données, tu doit doublé tout tes caractère ' qui sont dans les TEdit sinon le SQL prend ça pour une fin de chaine et ne comprend pas ce qui suit.

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    593
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 593
    Par défaut
    oui je savais que l'erreur venez dela.. mais comment je peux faire ca pour que builder le fasse automatiquement.

  9. #9
    Expert confirmé

    Avatar de pottiez
    Homme Profil pro
    Développeur C++
    Inscrit en
    Novembre 2005
    Messages
    7 152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur C++
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2005
    Messages : 7 152
    Par défaut
    Il ne le fait pas automatiquement, c'est à toi d'utiliser des fonctions pour ajouter un caractère à l'endroit que tu souhaite dans ta chaine de caractère

  10. #10
    Membre Expert
    Avatar de bakaneko
    Profil pro
    Inscrit en
    Février 2004
    Messages
    1 268
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 1 268
    Par défaut
    Vive le méthode QuotedStr

    Citation Envoyé par Aide de Builder
    Utilisez QuotedStr pour convertir la chaîne AnsiString S en une chaîne guillemetée. Un caractère simple (') est inséré au début et à la fin de S et les guillemets simples dans la chaîne sont répétés.

  11. #11
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    593
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 593
    Par défaut
    J'ai trouver la solution avec la fonction ParamByName.

    Mais maitenant j'ai un problemes lors des recordcount

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SQLQuery1->Active=false;
      SQLQuery1->SQL->Clear();
      AnsiString sql1("SELECT * FROM `clients` WHERE `Nom` LIKE :nom ");
      SQLQuery1->SQL->Add(sql1);
      SQLQuery1->ParamByName("nom")->AsString =Trim(Edit2->Text);
      SQLQuery1->Open();
      int Resultat=SQLQuery1->RecordCount;
     
    	if (Resultat>0)
    	{
    Exception déclenchée à $7C812A7B. Classe d'exception EDatabaseError avec message '[0x0005]: Opération non supportée'. Processus Project1.exe (3084)

  12. #12
    Membre Expert
    Avatar de bakaneko
    Profil pro
    Inscrit en
    Février 2004
    Messages
    1 268
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 1 268
    Par défaut
    Question :
    Pourquoi tu mets des quottes à tes noms de tables et de champs?

  13. #13
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    593
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 593
    Par défaut
    habitude mais bon ca change rien :p

  14. #14
    Expert confirmé

    Avatar de pottiez
    Homme Profil pro
    Développeur C++
    Inscrit en
    Novembre 2005
    Messages
    7 152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur C++
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2005
    Messages : 7 152
    Par défaut
    Même si ça ne change rien dans ce cas ci, je ne suis pas sur que ce soit dans la norme SQL, je t'en avait d'ailleurs fait la remarque tout a l'heure dans l'un de mes précédents messages.

  15. #15
    Rédacteur/Modérateur
    Avatar de ero-sennin
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    2 965
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

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

    Informations forums :
    Inscription : Juillet 2005
    Messages : 2 965
    Par défaut
    Bonsoir,

    Je me pose une question ! Ne faut il pas faire le ParamByName avec d'ajouter la requête ??

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
      SQLQuery1->Active=false;
      SQLQuery1->SQL->Clear();
      AnsiString sql1("SELECT * FROM clients WHERE Nom LIKE :nom ");
      SQLQuery1->ParamByName("nom")->AsString =Trim(Edit2->Text);
      SQLQuery1->SQL->Add(sql1);
      SQLQuery1->Open();
      int Resultat=SQLQuery1->RecordCount;
     
    	if (Resultat>0)
    	{
    A+

  16. #16
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    593
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 593
    Par défaut
    non ero j'avais deja tout essayer ca marchais pas.

    Enfin j'ai utiliser cette methode :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    nom = ReplaceStr(nom,"'","''");
    Au moins je peux laisser mes requete SQL comme elles sont

    J'ai mis la solution comme ca les autres peuvent en profiter

  17. #17
    Membre émérite
    Homme Profil pro
    Consultant ERP
    Inscrit en
    Février 2004
    Messages
    644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant ERP

    Informations forums :
    Inscription : Février 2004
    Messages : 644
    Par défaut
    Désolé, mais pour moi, il ne s'agit absolument pas d'une Solution. Tu vas devoir doubler le '%' si ta chaine de caractères contient un '%' etc.... Vraiment fastidieux.

    Borland C++ Builder vient avec TSQLQuery et certaines fonctionnalités très intéressantes, surtout les PreparedStatements.

    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    /// Initialisation d'un TSQLQuery
    std::auto_ptr< TSQLQuery > query( new TSQLQuery( 0 ) );
    query->SQLConnection = sqlConnection;
     
    query->SQL->Text = "SELECT firstname, lastname, birthdate, sex FROM PEOPLE WHERE ID = :ID";
    query->ParamByName("ID")->AsInteger = id;
    query->Active = true;
      if( !query->IsEmpty() ) {
        // to do something
      }
    De cette manière, cela permet d'économiser le code suivant
    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
     
    TSQLQuery * query = 0;
    try {
      query = new TSQLQuery( 0 );
      query->SQLConnection = sqlConnection;
     
      query->SQL->Clear();
      query->SQL->Add( "SELECT firstname, lastname, birthdate, sex ");
      query->SQL->Add( "FROM PEOPLE ");
      query->SQL->Add( "WHERE ID = " + IntToStr( id ) );
      query->Active = true;
     
      if( !query->IsEmpty() ) {
        // to do something
      }
     
      query->Active = false;
     
      delete query;
    } 
    catch( Exception const & ex ) {
      if( query ) {
        delete query;
      }
      throw;
    }
    Pourquoi dans la majorité des posts que l'on peut voir à ce sujet, je ne vois pas un auto pointeur utilisé pour libérer la mémoire dans le cas d'exception ?

    La documentation du TSQLQuery explique bien que lors de la libération de l'instance, le destructeur de la classe désactive le query.

    De même, la méthode TStrings::Add( str ) de l'attribut TSQLQuery::SQL ne fait que rajouter du texte à la propriété AnsiString TSQLQuery::SQL::Text.

    Au lieu de ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    query->SQL->Clear();
    query->SQL->Add( "SELECT * " );
    query->SQL->Add( "FROM TABLE_NAME ");
    il suffit d'écrire ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    query->SQL->Text = "SELECT * FROM TABLE_NAME";
    Ce code est plus court, et réalise la même chose, il suffit de lire la documentation, voir même le code source de la VCL.

    Pour tout ce qui est paramètres de query, pourquoi ne pas utiliser la méthode ParamByName ??? Elle s'occupe elle-meme de réaliser les convertions numériques (integer, boolean), horaires ( datetime ) et/ou chaine de caractères.

    exemple
    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
     
    AnsiString firstname, lastname;
    TDateTime birthdate;
    int sex;
    bool is_actif;
     
    std::auto_ptr< TSQLQuery > query( new TSQLQuery( 0 ) );
    query->SQLConnection = sqlConnection;
    query->SQL->Text = 
      "INSERT INTO PEOPLE( FIRSTNAME, LASTNAME, BIRTHDATE, SEX, IS_ACTIF ) " 
      "VALUES( :FIRSTNAME, :LASTNAME, :BIRTHDATE, :SEX, :IS_ACTIF )";
    query->ParamByName( "FIRSTNAME" )->AsString = firstname;
    query->ParamByName( "LASTNAME" )->AsString = lastname;
    query->ParamByName( "BIRTHDATE" )->AsDateTime = birthdate;
    query->ParamByName( "SEX" )->AsInteger = sex;
    query->ParamByName( "IS_ACTIF" )>AsInteger = ( is_actif ? 1 : 0 );
    query->ExecSQL();
    De cette manière, il n'est pas nécessaire de devoir remplacer les quotes ou guillemets, de vérifier les caractères '\n' ou autres, tout cela se fait automatiquement par le système.

    Bon amusement

    PS : Mon secret ? La doc !!!

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

Discussions similaires

  1. Erreur lors de création de table dans une BD SQL Server
    Par Klemsy78 dans le forum Administration
    Réponses: 1
    Dernier message: 18/08/2009, 20h32
  2. extraction d'un fichier excel dans une BDD SQL server
    Par saraenim dans le forum Développement
    Réponses: 4
    Dernier message: 03/10/2008, 13h58
  3. [CSV] exporter un fichier excel ou word dans une BDD SQL
    Par kimcharlene dans le forum Langage
    Réponses: 5
    Dernier message: 07/04/2008, 17h28
  4. [SQL] Upload/download de fichiers ou images dans une BDD sql
    Par boniface dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 31/07/2006, 16h04
  5. Réponses: 1
    Dernier message: 12/05/2006, 17h07

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