MySqlDataReader - Fatal error encountered during data read. [Résolu]

Signaler
Messages postés
4270
Date d'inscription
samedi 8 septembre 2007
Statut
Membre
Dernière intervention
4 mars 2021
-
Messages postés
4270
Date d'inscription
samedi 8 septembre 2007
Statut
Membre
Dernière intervention
4 mars 2021
-
Bonjour à tous.


je me tourne vers vous car j'ai un soucis avec mon reader qui déclenche l'exeption
Fatal error encountered during data read.
sans (à prioris) raison valable ...

Dans un premier temps, ce qui concerne la connexion fonctionne, ainsi que le query. Par contre, durant la lecture (donc pas dès que je lis mais au bout d'un moment), l'exception apparaît.

voici la fonction qui effectue la requête :
 
	public int Query(string sQuery)
		{
			Erreur = "";
			if (!(reader == null) && !reader.IsClosed ) reader.Close();
			bIsOk = false;
			MySqlCommand cmdMySQL = pMySQL.CreateCommand();
			cmdMySQL.CommandText = sQuery;

			try
			{
				reader = cmdMySQL.ExecuteReader();
			}
			catch (MySqlException e)
			{
				cmdMySQL.Dispose();
				Erreur = e.Message.ToString();
				return 2;
			}
			catch (Exception)
			{
				cmdMySQL.Dispose();
				checkAndReconnect();
				return Query(sQuery);
			}
			finally
			{
			}
			bIsOk = reader.HasRows;

			if (bIsOk) return 1;
			else return 0;
		}


et celle qui me permet de lire les résultats :
		public IEnumerable<string> getRes()
		{

			if (!bIsOk)
			{
				#region gestion
				if (Erreur != "")
				{
					Exception e = new Exception(Erreur);
					throw e;
				}
				else
				{
					Exception e = new Exception("PAS DE REQUETE");
					throw e;
				}
				#endregion
			}

			string res = "";
			int nbChamps = reader.FieldCount - 1;
			while (reader.Read())
			{
				res = "";
				for (int i = 0; i <= nbChamps; i++)
					res += reader.GetValue(i) + ";";
				yield return res;
			}
			reader.Dispose();
			reader.Close();
			bIsOk = false;
			Erreur = "";			
		}


l'exception apparait au niveau du while :
while (reader.Read())
mais, je me répète, pas lors de la première itération.

Deux points à rajouter :
- j'utilise ces méthodes dans d'autres parties sans soucis
- ma requête récupère deux éléments : une chaine de 10 caractère et un identifiant

si quelqu'un à une idée ... ou si d'autre infos vous seraient nécessaires, demandez =)

merci d'avance.

naga

5 réponses

Messages postés
834
Date d'inscription
samedi 15 novembre 2008
Statut
Membre
Dernière intervention
14 janvier 2017
30
Bonsoir
Lorsque tu dis "Pas lors de la première itération" veux-tu dire que ça plante pendant la première boucle While{} ou lors d'un second appel ?
Dans le deuxième cas cela serait normal si entre temps tu n'as pas rappelé un ExecuteReader() pour remplir de nouveau le DataReader.
Si non quelle est le message exact de l'exception ?
Messages postés
4270
Date d'inscription
samedi 8 septembre 2007
Statut
Membre
Dernière intervention
4 mars 2021
16
salut,
non je lit sur le même reader (une seule requête), et l'exception se déclenche ensuite, au bout d'un certain nombre de lecture.
je n'ai moyen de te refaire l'exception ce week end, je lancerai mon appli lundi mais je ne sais pas combien de temps ca va prendre. Enfin il n'y avait pas plus d'info que le message que j'ai donné il me semble, je te redirai.

merci
Messages postés
4270
Date d'inscription
samedi 8 septembre 2007
Statut
Membre
Dernière intervention
4 mars 2021
16
salut

j'ai donc tout démarré ce matin, actuellement ca tourne. J'ai quand même ajouté, au départ de ma fonction
query
la fermeture du reader si'il ne l'est pas. Normalement il doit être fermé par la lecture des éléments, mais le cas où je n'avais pas de résultat, laissait le reader ouvert (et bien sûr je ne lisais pas).

L'exception que j'avais donné ne correspond pas à ce problème, mais en résolvant celui ci, peu être que celui de départ était en relation avec lui.

Bref je redirai.

naga
Messages postés
4270
Date d'inscription
samedi 8 septembre 2007
Statut
Membre
Dernière intervention
4 mars 2021
16
Salut !

J'ai réussi à récupérer l'exception (après 48 h de traitement, dont 90% concerne du requêtage avec ce même connecteur qui pose problème).

Le message complet est donc celui que j'avais donné :


Fatal error encountered during command execution.

le stack :

at connBaseSQL.cMySql.<getRes>d__0.MoveNext()
at pFusionFicVin.cImportFicVinSQL.finalize()
at pFusionFicVin.cImportFicVinSQL.import()
at pFusionFicVin.f_main.th_import()
at pFusionFicVin.f_main.<btn_fusion_Click>b__0()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()

il n'y a pas plus d'info. Ce que je peux rajouter c'est que l'exception est créé lors du
ExecuteReader
et qu'elle est ensuite remontée par ma méthode getRes => c'est donc à l'interrogation qu'il y a un soucis.

si tu as une idée, je seche un peu =/

merci.
naga
Messages postés
834
Date d'inscription
samedi 15 novembre 2008
Statut
Membre
Dernière intervention
14 janvier 2017
30
Pas vraiment d'idée, il semblerait que l'exception provienne du connecteur ou de la base, pas de ton code; les moteurs de bases de données prennent parfois des décisions impitoyables lorsqu'ils ont besoin d'espace

Si le nombre d'enregistrements retournés par la requête n'est pas important il vaudrait mieux faire une fonction "tout-en-un", pour éviter d'avoir des connexions ouvertes, par ailleurs je n'aime pas trop l'utilisation du "yield" pour les mêmes raisons.
genre:
public IEnumerable<string> getRes(string sQuery, string connectionString)
{
 List<string> StringResults = new List<string>();
 Erreur = string.Empty;
   
 try
 {
  using (DbConnection connection = new MySqlConnection(connectionString))
  {
   connection.Open();
   DbCommand command = new MySqlCommand();
   command.CommandText=sQuery;
   command.Connection=connection;
   using (DbDataReader reader = command.ExecuteReader())
   {
    if (!reader.HasRows)
     return null;
    while (reader.Read())
    {
     string res = string.Empty;
     for (int i = 0; i < reader.FieldCount; i++)
      res += reader.GetValue(i) + ";";
     StringResults.Add(res);
    }
    return StringResults;
   }
  }
 }
 catch (Exception ex)
 {
  Erreur = ex.Message.ToString();
  return null;
 }

}


Bob.
C# is amazing, enjoy it!
Messages postés
4270
Date d'inscription
samedi 8 septembre 2007
Statut
Membre
Dernière intervention
4 mars 2021
16
ok donc je n'aurai à prioris pas le main là dessus =/

Bon mon appli à un système de sauvegarde histoire de libérer le poste si besoin, j'ai donc rajouté mon exception pour pouvoir reprendre mon travail.

Dans mon cas j'utilise le yield pour plusieurs raisons, la première étant que je ne peux pas stocker les resultat dans la ram vu que je traite un nombre très important de données . La seconde raison étant que je préfère avoir mon objet et ne pas traiter en direct afin de pouvoir gérer une seule fois certaines exceptions.

merci en tout cas, tant pis je me débrouillerai avec ma sauvegarde donc =)

bne aprem ;)
naga
Messages postés
4270
Date d'inscription
samedi 8 septembre 2007
Statut
Membre
Dernière intervention
4 mars 2021
16
ah oui, et au départ je stockai justement les résultats dans des fichiers temporaire afin d'éviter les dépassement de mémoire (pour rendre transparent le fait de récupérer dans un fichier ou la liste).