Problème de type avec OleDbParameters et Access

Messages postés
98
Date d'inscription
vendredi 1 septembre 2006
Dernière intervention
24 octobre 2018
- 4 mai 2018 à 14:54 - Dernière réponse :
Messages postés
98
Date d'inscription
vendredi 1 septembre 2006
Dernière intervention
24 octobre 2018
- 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.
Afficher la suite 

Votre réponse

2 réponses

Messages postés
1710
Date d'inscription
samedi 11 janvier 2014
Statut
Contributeur
Dernière intervention
20 novembre 2018
- Modifié par vb95 le 4/05/2018 à 16:56
0
Merci
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);


Commenter la réponse de vb95
Messages postés
98
Date d'inscription
vendredi 1 septembre 2006
Dernière intervention
24 octobre 2018
- 4 mai 2018 à 19:00
0
Merci
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.
Commenter la réponse de MGD Software

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.