1. #1
    Membre du Club
    Profil pro
    Inscrit en
    octobre 2004
    Messages
    118
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2004
    Messages : 118
    Points : 44
    Points
    44

    Par défaut ExecuteNonQuery renvoie toujours 0

    Bonjour

    J'ai une requête sur une base Access définie de la façon suivante:

    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    var query = "UPDATE tblLR " +
                            "SET Location = @location " +
                            ", SortedLocation = @sortedLocation" +
                            ", Latitude = @latitude" +
                            ", Longitude = @longitude " +
                            " WHERE IDLR = @idLr";
     
                var dBcon = new OleDbConnection(Legacy.ConString);
                var cmd = new OleDbCommand(query, dBcon);
     
                cmd.Parameters.Add("@location", OleDbType.VarChar).Value = topLegacy.Location.Replace("'", "''");
                cmd.Parameters.Add("@sortedLocation", OleDbType.VarChar).Value = topLegacy.Location.Replace("'", "''");
                cmd.Parameters.Add("@shortName", OleDbType.VarChar).Value = topLegacy.ShortName.Replace("'", "''");
                cmd.Parameters.Add("@latitude", OleDbType.Double).Value = topLegacy.Latitude;
                cmd.Parameters.Add("@longitude", OleDbType.Double).Value = topLegacy.Longitude;
                cmd.Parameters.Add("@idLr", OleDbType.BigInt).Value = topLegacy.Idlr;
     
                var result = 0;
                using (dBcon)
                {
                    try
                    {
                        dBcon.Open();
                        result = cmd.ExecuteNonQuery();
                        if (result <= 0)
                        {
                            string msg = "Erreur dans MettreAJourLegacy avec comme arguments: " +
                            "\n topLegacy =  " + topLegacy.Idlr + " " + topLegacy.ToString() +
                             "\n topGeoDB = " + topGeoDb.ToString();
                            MessageBox.Show(msg, "Erreur fatale dans la méthode MettreAJourLegacy()", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
     
                        }
                        return result <= 0 ? false : true;
                    }
                    catch (OleDbException ex)
                    {
                        string msg = ex.Message + "\n Erreur dans MettreAJourLegacy avec comme arguments: " +
                            "\n topLegacy =  " + topLegacy.Idlr + " " + topLegacy.ToString() +
                             "\n topGeoDB = " + topGeoDb.ToString();
                        //  Program.ReportCrash(ex, msg);
                        // ToponymeNonTraite.ListeToponymesNonTraites.Add(topLegacy);
                        MessageBox.Show(msg, "Erreur fatale dans la méthode MettreAJourLegacy()", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                        return false;
                    }
     
                }
    La ligne result=cmd.ExecuteNonQuery();
    renvoie systématiquement 0 et la requête n'est pas exécutée.

    J'ai cherché sur le web mais n'ai pas trouvé la solution.

    Merci pour votre aide

    Bernard

  2. #2
    Expert éminent
    Homme Profil pro
    Développeur Freelance
    Inscrit en
    janvier 2009
    Messages
    3 440
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur Freelance

    Informations forums :
    Inscription : janvier 2009
    Messages : 3 440
    Points : 7 272
    Points
    7 272

    Par défaut

    Bonjour,
    A mon avis il manque les quotes autours des valeurs de type chaine dans la requête, par exemple autour de @location.
    Accessoirement, je pense qu'il serait utile (au moins en phase de debug) d'ajouter l'erreur retournée par Access dans le message d'erreur.
    Tu auras ainsi des pistes dans ce genre de blocage.

    Tatayo.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    octobre 2004
    Messages
    118
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2004
    Messages : 118
    Points : 44
    Points
    44

    Par défaut

    Bonjour

    Je n'ai aucune erreur fournie par la requête!
    Je suppose que si la syntaxe de la requête était erronée j'aurai une erreur.

    Bernard

  4. #4
    Membre chevronné
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    mars 2005
    Messages
    1 140
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : mars 2005
    Messages : 1 140
    Points : 1 815
    Points
    1 815

    Par défaut

    Citation Envoyé par tatayo Voir le message
    Bonjour,
    A mon avis il manque les quotes autours des valeurs de type chaine dans la requête, par exemple autour de @location.
    Accessoirement, je pense qu'il serait utile (au moins en phase de debug) d'ajouter l'erreur retournée par Access dans le message d'erreur.
    Tu auras ainsi des pistes dans ce genre de blocage.

    Tatayo.
    L'un des avantages des requêtes paramétrées est justement de se passer des quotes et des problèmes de format.

    BernardBouree,
    ExecuteNonQuery va déclencher une InvalidOperationException
    OleDbException se produira si tu ne parviens pas a établir une connexion lors du Open().

    Si tu passe dans le catch, cela signifie que la connexion ne s'est pas effectuée et dans ce cas, il est normal que la requête ne soit pas jouée.
    Donc, en premier lieu :
    - vérifie la chaine de connexion,
    - vérifie la présence du lien ODBC (si ça existe toujours, il y a bien longtemps que j'ai pas tenté de me connecter à Access)
    - regarde ce que te dis l'exception remontée.

    Une fois cette étape passée et corrigée et seulement à ce moment, on pourra intervenir dans le code.
    La façon dont tu codes ça est bizarre, j'essaierai plutôt comme ceci :
    Code C# : 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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    using (var dBcon = new OleDbConnection(Legacy.ConString))
    {
      using (var cmd = new OleDbCommand(query, dBcon))
      {
        cmd.Parameters.Add("@location", OleDbType.VarChar).Value = topLegacy.Location.Replace("'", "''");
        cmd.Parameters.Add("@sortedLocation", OleDbType.VarChar).Value = topLegacy.Location.Replace("'", "''");
        cmd.Parameters.Add("@shortName", OleDbType.VarChar).Value = topLegacy.ShortName.Replace("'", "''");
        cmd.Parameters.Add("@latitude", OleDbType.Double).Value = topLegacy.Latitude;
        cmd.Parameters.Add("@longitude", OleDbType.Double).Value = topLegacy.Longitude;
        cmd.Parameters.Add("@idLr", OleDbType.BigInt).Value = topLegacy.Idlr;
     
        try
        {
          dBcon.Open();
          var result = cmd.ExecuteNonQuery();
          if (result <= 0)
          {
             string msg = "Erreur dans MettreAJourLegacy avec comme arguments: " +
                            "\n topLegacy =  " + topLegacy.Idlr + " " + topLegacy.ToString() +
                             "\n topGeoDB = " + topGeoDb.ToString();
             MessageBox.Show(msg, "Erreur fatale dans la méthode MettreAJourLegacy()", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
             return false;
           }
           return true;
        }
        catch (OleDbException ex)
        {
            string msg = ex.Message + "\n Erreur dans MettreAJourLegacy avec comme arguments: " +
                            "\n topLegacy =  " + topLegacy.Idlr + " " + topLegacy.ToString() +
                             "\n topGeoDB = " + topGeoDb.ToString();
     
            MessageBox.Show(msg, "Erreur fatale dans la méthode MettreAJourLegacy()", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);         
         }
      }
      return false;
    }

  5. #5
    Membre éclairé
    Homme Profil pro
    x
    Inscrit en
    juin 2007
    Messages
    468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : x

    Informations forums :
    Inscription : juin 2007
    Messages : 468
    Points : 713
    Points
    713

    Par défaut

    Je suppose que les Replace("'", "''") servent à échapper les ', mais vous êtes sûrs que c'est nécessaire ? Est-ce-que ce n'est pas directement pris en charge par le constructeur de requête ?

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    octobre 2004
    Messages
    118
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2004
    Messages : 118
    Points : 44
    Points
    44

    Par défaut

    Bonjour à tous et merci pour votre aide.

    Non dans la version avec paramètres, je ne passe pas dans le catch, il n'y donc pas d'erreur fatale.
    Mais j'ai systématiquement un result = cmd.ExecuteNonQuery qui me renvoit un 0 au lieu du 1 attendu qui est le nombre d'enregistrements concernés.
    Je vais essayer votre proposition de code.

    Pour les '' oui c'est obligatoire car sinon la requête est erronée.

    Bernard

  7. #7
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    avril 2007
    Messages
    13 127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : avril 2007
    Messages : 13 127
    Points : 23 932
    Points
    23 932

    Par défaut

    arretez de dire n'importe quoi
    le but des DbParameters est entre autre de ne pas avoir de problème avec les ' donc faire des replaces ne peut que causer des problèmes
    (et les dbparameters ne modifient pas la requete, ils sont passés comme variable, par exemple une date reste une date sur 8 octets au lieu d'être transformée en string)

    outre le fait que se baser sur le retour d'executenonquery n'est pas toujours une bonne idée (sur access ca doit aller encore)
    si ca te retourne 0 et que rien n'est modifié dans la base c'est que ta requete est mal écrite ou les valeurs que tu passes ne sont pas celles que tu penses ou les données dans la base ne sont pas celles que tu penses
    donc y a juste à mettre un point d'arrêt pour vérifier, et tester la requete sur access, voire en select
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    octobre 2004
    Messages
    118
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2004
    Messages : 118
    Points : 44
    Points
    44

    Par défaut

    Dois-je comprendre que je dois retirer les replaces("'","''") ?

    Si la commande UPDATE était erronée j'aurai une erreur, or je n'en ai pas.
    Un point d'arrêt sur ExecuteNonQuery ne me donne rien et me renvoit juste 0.

    Bernard

  9. #9
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    avril 2007
    Messages
    13 127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : avril 2007
    Messages : 13 127
    Points : 23 932
    Points
    23 932

    Par défaut

    Citation Envoyé par BernardBouree Voir le message
    Dois-je comprendre que je dois retirer les replaces("'","''") ?
    oui


    Citation Envoyé par BernardBouree Voir le message
    Si la commande UPDATE était erronée j'aurai une erreur, or je n'en ai pas.
    la syntaxe est correcte oui sinon tu irais dans un catch
    par contre si ta requete exécute update table set col = valeur where id = 0 et qu'aucun id 0 n'existe parce que 0 c'est pas bon ou id c'est pas la bonne colonne alors la requete s'exécute bien mais ne fait rien de visible
    c'est pour ca que je dis de vérifier entre autres les valeurs des dbparameters avant exécution
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  10. #10
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    avril 2007
    Messages
    13 127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : avril 2007
    Messages : 13 127
    Points : 23 932
    Points
    23 932

    Par défaut

    j'ai trouvé ton problème en relisant le code, et il est légèrement ailleurs (même s'il faut en effet retirer les replace)

    tu as 5 paramètres dans ta requete et tu en ajoutes 6 dans la collection de paramètre du cmd

    sur un vrai sgbdr comme sql server ca ne poserait pas de problème, mais access n'utilise pas les noms des paramètres (certains utilisent toujours ? pour tous les paramètres d'ailleurs), mais il fait le lien entre l'ordre d'apparation dans la requete et l'ordre d'ajout dans la collection de paramètre
    donc pour @idlr il va utiliser la valeur de longitude
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    octobre 2004
    Messages
    118
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2004
    Messages : 118
    Points : 44
    Points
    44

    Par défaut

    Pol63 avait raison!
    Une erreur peut en cacher une autre!

    En supprimant les replaces j'obtiens une erreur de la requête.
    En fait il manquait un paramètre !!!

    Maintenant cela tourne mais j'ai de façon aléatoire une erreur fatale m'indiquant qu'il "faut utiliser une requête qui peut être mise à jour" !!??
    Ce qui est bizarre c'est que cette erreur n'intervient que sur quelques enregistrements et de façon aléatoire car ceux ne sont pas les même à chaque run!

  12. #12
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    avril 2007
    Messages
    13 127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : avril 2007
    Messages : 13 127
    Points : 23 932
    Points
    23 932

    Par défaut

    après si tu peux passer sur quelque chose d'autre qu'access ca t'éviterait bien des soucis ...
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    octobre 2004
    Messages
    118
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2004
    Messages : 118
    Points : 44
    Points
    44

    Par défaut

    Oui sauf que la base vient d'un tiers qui pour le moment ne veut pas changer!

Discussions similaires

  1. fopen renvoi toujours NULL
    Par kissmytoe dans le forum C
    Réponses: 6
    Dernier message: 01/11/2006, 20h01
  2. socket send renvoi toujours (-1)
    Par tkwebch dans le forum Réseau
    Réponses: 8
    Dernier message: 30/08/2006, 17h24
  3. isdigit() renvoie toujours 0
    Par gangsoleil dans le forum C
    Réponses: 30
    Dernier message: 07/08/2006, 13h42
  4. Mon SELECT COUNT me renvoie toujours 1
    Par diaboloche dans le forum PHP & MySQL
    Réponses: 14
    Dernier message: 11/07/2006, 11h53
  5. Réponses: 2
    Dernier message: 16/04/2005, 20h24

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