[C99] MySQL C API mit Prepared Statements

Bratkartoffel

gebratene Kartoffel
Premium-User
Hi Leute,

sitze gerade an einer Loginfunktion für mein C-Programm. Leider komm ich nicht weiter, die Datenbankabfrage schlägt immer fehl.

Die Datenbanktabelle exisitert, es ist auch ein Eintrag vorhanden der eigentlich gefunden werden müsste.

Hier der Codeausschnitt für die Loginfunktion:
C:
/*
Aus dem Header:
  #define MYSQL_QUERY_LOGIN \
      "SELECT ID FROM users WHERE user = ? AND pass = ?"

e: Eigene Struktur mit der Datenbankverbindung und diversen Parametern
u: Benutzername, Parameter der Funktion
p: Passwort, Parameter der Funktion
*/

  /* statement erstellen */
  stmt = mysql_stmt_init(e->connection);
  if(stmt == NULL) {
    logger_write(log, LOGLEVEL_ERROR, "MySQL: (login) Unable to "
        "initialize statement: %u: %s", mysql_errno(e->connection),
        mysql_error(e->connection));
    pthread_mutex_unlock(&e->mutex);

    return false;
  }

  /* statement vorbereiten */
  if(mysql_stmt_prepare(stmt, MYSQL_QUERY_LOGIN,
        strlen(MYSQL_QUERY_LOGIN)) != 0) {
    logger_write(log, LOGLEVEL_ERROR, "MySQL: (login) Unable to "
        "prepare statement: %u: %s", mysql_errno(e->connection),
        mysql_error(e->connection));
    mysql_stmt_close(stmt);
    pthread_mutex_unlock(&e->mutex);

    return false;
  }

  /* parameter initialisieren */
  memset(params, 0, sizeof(params));
  memset(result, 0, sizeof(result));

  /* parameter initialisieren */
  params[0].buffer_type    = MYSQL_TYPE_STRING;
  params[0].buffer         = &u;
  params[0].is_unsigned    = true;

  params[1].buffer_type    = MYSQL_TYPE_STRING;
  params[1].buffer         = &p;
  params[1].is_unsigned    = true;

  result[0].buffer_type    = MYSQL_TYPE_LONG;
  result[0].buffer         = &erg;
  result[0].is_unsigned    = true;

  /* parameter binden */
  if(mysql_stmt_bind_param(stmt, params) != 0) {
    logger_write(log, LOGLEVEL_ERROR, "MySQL: (login) Unable to "
        "bind params: %u: %s", mysql_errno(stmt->mysql),
        mysql_error(stmt->mysql));
    mysql_stmt_close(stmt);
    pthread_mutex_unlock(&e->mutex);

    return false;
  }

  /* statement ausführen */
  if(mysql_stmt_execute(stmt) != 0) {
    logger_write(log, LOGLEVEL_ERROR, "MySQL: (login) Unable to "
        "execute statement: %u: %s", mysql_errno(stmt->mysql),
        mysql_error(stmt->mysql));
    mysql_stmt_close(stmt);
    pthread_mutex_unlock(&e->mutex);

    return false;
  }

  /* ergebnis binden */
  if(mysql_stmt_bind_result(stmt, result) != 0) {
    logger_write(log, LOGLEVEL_ERROR, "MySQL: (login) Unable to "
        "bind result: %u: %s", mysql_errno(stmt->mysql),
        mysql_error(stmt->mysql));
    mysql_stmt_close(stmt);
    pthread_mutex_unlock(&e->mutex);

    return false;
  }

  /* ergebnis holen */
  if(mysql_stmt_fetch(stmt) != 0) {
    logger_write(log, LOGLEVEL_ERROR, "MySQL: (login) Unable to "
        "fetch result: %u: %s", mysql_errno(stmt->mysql),
        mysql_error(stmt->mysql));
    mysql_stmt_close(stmt);
    pthread_mutex_unlock(&e->mutex);

    return false;
  }


  /* result aufräumen */
  mysql_stmt_free_result(stmt);
  mysql_stmt_close(stmt);

  /* mutex entsperren */
  pthread_mutex_unlock(&e->mutex);

  return (erg > 0);

Er verlässt mir die Funktion mit der Fehlermeldung dass er das Result nicht holen kann. Ich verstehe es nicht, weil mysql_errno eine 0 zurückgibt.

Jemand einen Ansatz, wie ich das weiter debuggen / lösen kann? Oder ein Beispiel für Prepared Statements in C mit Strings als Parametern?

Gruß
BK
 
Hi deepthroat,

Danke für den Link, werd mich da mal durchlesen. Konnte aber soeben das Problem finden, auch wenns für mich keinen Sinn macht:

Im obigen Beispiel:
C:
params[0].buffer         = u;
params[1].buffer         = p;

Ich darf die Strings u und p nicht per Referenz übergeben, ich muss die direkt übergeben. Bekomme damit zwar von meinem GCC Warnungen, aber so gehts zumindest.

Gruß
BK
 
Zurück