2008-11-11 11 views
3

Il semble que lorsque j'ai une fonction mysql_real_query() dans une boucle while continue, la requête sera exécutée OK. Cependant, si plusieurs mysql_real_query() sont dans la boucle while, l'une après l'autre. En fonction de la requête, il arrive que ni la première requête ni la deuxième requête ne s'exécutent correctement.multiple mysql_real_query() dans while loop

Cela me semble être un problème de threading. Je me demande si le mysql c api a une façon de gérer cela? Est-ce que quelqu'un sait comment faire face à cela? mysql_free_result() ne fonctionne pas car je ne stocke pas les résultats.

//keep polling as long as stop character '-' is not read 
while(szRxChar != '-') 
{ 
    // Check if a read is outstanding 
    if (HasOverlappedIoCompleted(&ovRead)) 
    { 
     // Issue a serial port read 
     if (!ReadFile(hSerial,&szRxChar,1, 
       &dwBytesRead,&ovRead)) 
     { 
      DWORD dwErr = GetLastError(); 
      if (dwErr!=ERROR_IO_PENDING) 
       return dwErr; 
     } 
    } 

    // Wait 5 seconds for serial input 
    if (!(HasOverlappedIoCompleted(&ovRead))) 
    { 
     WaitForSingleObject(hReadEvent,RESET_TIME); 
    } 

    // Check if serial input has arrived 
    if (GetOverlappedResult(hSerial,&ovRead, 
      &dwBytesRead,FALSE)) 
    { 
     // Wait for the write 
     GetOverlappedResult(hSerial,&ovWrite, 
      &dwBytesWritten,TRUE); 

     //load tagBuffer with byte stream 
     tagBuffer[i] = szRxChar; 
     i++; 
     tagBuffer[i] = 0; //char arrays are \0 terminated 

     //run query with tagBuffer 
     if(strlen(tagBuffer)==PACKET_LENGTH) 
     { 
      sprintf(query,"insert into scan (rfidnum) values ('"); 
      strcat(query, tagBuffer); 
      strcat(query, "')"); 
      mysql_real_query(&mysql,query,(unsigned int)strlen(query)); 

      i=0; 
     } 

     mysql_real_query(&mysql,"insert into scan (rfidnum) values ('2nd query')",(unsigned int)strlen("insert into scan (rfid) values ('2nd query')")); 

     mysql_free_result(res); 
    } 
} 
+0

est votre deuxième requête vraiment un autre insert? – Alnitak

+0

Oui, j'ai essayé à la fois d'insérer et de sélectionner. Si c'est un select, il semble que rien ne soit inséré à partir de la première requête. S'il s'agit d'un insert, un seul tuple sera inséré. – Steve

+0

mysql_free_res ne doit être utilisé que sur le résultat d'une requête qui produit des données de ligne. "inserts" ne le font pas. – Alnitak

Répondre

0

OK, à des fins de test, prenez votre variable tagBuffer de la première mysql_real_query appel et le remplacer par une constante, comme votre deuxième requête de test.

À ce stade, vous insériez simplement deux chaînes constantes. Que devrait vraiment devrait fonctionner.

Si cela ne fonctionne pas, alors nous devons déterminer ce qui ne va pas avec tagBuffer. Pourrait-il recevoir des caractères inhabituels qui, d'une manière ou d'une autre, déroutent MySQL mais qui ne sont pas détectés dans l'unique cas de requête?

+0

Je viens d'essayer votre suggestion. Malheureusement, j'ai eu le même résultat avec tagBuffer qu'avec une constante. La seule différence est que maintenant ma constante '1st' ne réapparaît pas lorsque j'ajoute la deuxième requête. – Steve

+0

ok, alors allez avec la réponse de Bill suivant et vérifiez les codes d'erreur MySQL. – Alnitak

1

Toujours vérifier la valeur de retour d'un appel d'API.

mysql_real_query() renvoie un nombre entier. La valeur est zéro si l'appel a fonctionné, et non zéro s'il y a une erreur.

Vérifiez la valeur de retour et de faire rapport si elle est non nulle:

if ((err = mysql_real_query(&mysql,"insert into scan (rfidnum) values ('2nd query')", 
    (unsigned int)strlen("insert into scan (rfid) values ('2nd query')"))) != 0) 
{ 
    // report err here, get additional information from these two API calls: 
    errno = mysql_errno(&mysql); 
    errmsg = mysql_error(&mysql); 
} 

mise à jour: Si vous obtenez un résultat non nul, vous devez vérifier mysql_error() pour savoir quelle erreur. Puisque vous avez dit que vous obtenez une erreur si la deuxième requête est SELECT, je suppose que c'est CR_COMMANDS_OUT_OF_SYNC, ce qui signifie que l'API pense qu'il y a des résultats en attente (même si le résultat est constitué de zéro lignes). Vous ne pouvez pas démarrer la requête SQL suivante tant que vous n'avez pas fini d'extraire les résultats d'un SELECT (ou d'appeler une procédure stockée), même si le résultat de cette requête est vide.

Voici une brève explication dans la documentation MySQL: « Commands out of sync »

Vous devez utiliser mysql_free_result() avant de pouvoir exécuter une autre requête. Et cela signifie que vous devez utiliser mysql_use_result() avant de pouvoir le libérer.

Voici un extrait de mysql_use_result() doc:

Après avoir invoqué mysql_query() ou mysql_real_query(), vous devez appeler mysql_store_result() ou mysql_use_result() pour chaque déclaration qui produit avec succès un résultat définir (SELECT, SHOW, DESCRIBE, EXPLAIN, CHECK TABLE, et ainsi de suite). Vous devez aussi appeler mysql_free_result() après ( ) vous avez terminé avec le jeu de résultats.

+0

OK, il a renvoyé un '1' pour la deuxième requête. Quels fichiers d'en-tête dois-je inclure pour mysql_errno et mysql_error? – Steve

+0

Il semble que j'obtiendrai un code d'erreur 1 pour la première requête d'insertion si j'ai une deuxième requête qui est une instruction select – Steve

+0

Merci. J'ai juste essayé cela: res = mysql_use_result (& mysql); mysql_free_result (res); mais toujours pas de succès. Je vais continuer à travailler dessus et je vous ferai savoir si je trouve une solution. Merci – Steve