Problème de type avec OleDbParameters et Access

MGD Software Messages postés 186 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 23 avril 2022 - 4 mai 2018 à 14:54
MGD Software Messages postés 186 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 23 avril 2022 - 4 mai 2018 à 19:00
Bonjour,

Je développe un programme de comptabilité en C#, utilisant une base de données Access.
La base a été créée avec Access 2010.
Elle comporte une table "Operations" ayant entre autres un champ "DateOps" de type Date/Heure et un champ "Montant" de type "Réel simple".

Lorsque j'exécute le code ci-dessous, j'ai une erreur "Type de données incompatible dans l'expression du critère." au niveau du ExecuteReader().
J'ai tenté de créer des objets OleDbParameter distincts puis de les ajouter à la commande avec Cmd.Parameters.Add, même résultat.
J'ai tenté aussi de remplacer AddWithValue(nom, valeur) par Add(new OleDbParameter(nom, valeur)), même résultat.

J'ai vérifié avec un point d'arrêt que Cmd.Parameters[0].Value.GetType().Name donnait bien "DateTime". Idem pour le second.
Pourquoi un paramètre DateTime en C# est incompatible avec un champ Date/Heure Access ???
Et je ne veux pas me passer des paramètres pour éviter une injection SQL avec le contenu des champs de date (encore qu'ils sont filtrés à la validation).

Le problème ne vient probablement pas du Sum(Montant) puisque si j'enlève la clause WHERE cela fonctionne.
Et d'autre part, dans une autre requête SELECT où je n'utilise pas de paramètre de date mais qu'un des champs est une date, la fonction GetDateTime() de l'OleDbDataReader ne provoque pas d'erreur.

[...]
            OleDbCommand Cmd;
            OleDbDataReader Rs;

            DateTime dtDateDu = new DateTime(0);
            DateTime dtDateAu = DateTime.Now;
            DateTime dtDummy = new DateTime();
            if (txtDateDu.Text != "" && DateTime.TryParse(txtDateDu.Text, out dtDummy)) dtDateDu = dtDummy;
            if (txtDateAu.Text != "" && DateTime.TryParse(txtDateAu.Text, out dtDummy)) dtDateAu = dtDummy;

            ReopenBase();

            // Calcul du total utilisable (ne tient pas compte des dates de valeur)
            // Si date de début vide (depuis début), le montant initial est pris en compte
            Cmd = new OleDbCommand("SELECT Sum(Montant) AS Total FROM Operations WHERE DateOps BETWEEN @DateDu AND @DateAu", mCnx);
            Cmd.Parameters.AddWithValue("@DateDu", dtDateDu);
            Cmd.Parameters.AddWithValue("@DateAu", dtDateAu);
            try
            {
                Rs = Cmd.ExecuteReader();
                if (Rs.HasRows)
                {
                    Rs.Read();
                if (Rs.GetValue(0).GetType() == typeof(DBNull))
                    txtTotalUtil.Text = ((int)0).ToString("0.00");
                else
                    txtTotalUtil.Text = (Rs.GetDouble(0) + (txtDateDu.Text != "" ? InitVal : 0)).ToString("#,##0.00");
                }
                Rs.Close();
            }
            catch (Exception ex) { Console.WriteLine(Cmd.CommandText + " => " + ex.Message); txtTotalUtil.Text = "Erreur"; }
[...]


Quelqu'un a une solution? Merci.

2 réponses

vb95 Messages postés 3472 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 13 avril 2024 169
Modifié le 4 mai 2018 à 16:56
Bonjour
Sans certitude mais peut-être une solution vue ici : https://stackoverflow.com/questions/3168529/sql-access-how-to-return-between-dates


Cmd = new OleDbCommand("SELECT Sum(Montant) AS Total FROM Operations WHERE DateOps BETWEEN #DateDu#  AND #DateAu#", mCnx);


0
MGD Software Messages postés 186 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 23 avril 2022 2
4 mai 2018 à 19:00
Merci pour la réponse, mais elle est hors sujet.
J'ai précisé que je ne voulais pas placer les dates dans le texte de la requête, mais utiliser des paramètres.
L'article cité n'utilise pas de paramètres (dont les nom commencent obligatoirement par un "@" en C#)
Il suffit d'entrer des guillemets dans le texte de la date pour effectuer une injection SQL qui peut être très dangereuse pour la base de données. L'utilisation des valeurs dans le texte de la requête est une pratique dangereuse qu'il ne faut utiliser que quand on ne peut pas faire autrement (ou que les valeurs sont internes au programme et ne proviennent pas d'une saisie utilisateur).
Merci quand même pour t'être penché sur la question.
0
Rejoignez-nous