MySQL auslesen

Hallo Gemeinde

Ich versuche mittels Arduino einen einzelnen Datensatz aus einer MySQL DB auszulesen. Mit folgender Lib versuche ich dies: MySQL_Connector_Arduino

Ich brauche weder Spalten noch Zeilen, sondern möchte lediglich einen Wert auslesen. Mein Query dazu lautet:

char query[] = "SELECT val FROM ts_number WHERE ID=5 ORDER BY ts DESC LIMIT 1";

Die Connection zu rDB scheint zu klappen, jedoch erhalte ich keine Werte zurück. Vermutlich liegt das Problem beim auslesen und anzeigen des Datensatzes. Habe nur Beispiele gefunden, welche die Tabelle auslesen(Spalten/Zeilen)

Hat mir jemand einen Lösungsansatz?

Danke! pat

Die Lib hat Debugausgaben. Die solltest Du aktivieren. Ist der DB-Benutzer für den Host freigegeben? Wo liegt die DB (lokal oder beim Provider)?

Viel mehr kann man ohne Sketch und weitere Infos von Dir nicht sagen. Ich habe mit der Lib keine Probleme.

Gruß Tommy

Die DB ist beim Provider.
Diesselbe DB lese ich mit demselben User und Query mit einer anderen Anwendung ohne Probleme aus.
Also Berechtigungen stimmen.

Hier der Sketch. Ist sicher Anpassungsfähig, also bitte nicht schimpfen :smiley:
Mir ist klar, dass hier der Query vermutlich nicht funzt.

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266WiFiMulti.h>
#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>


ESP8266WiFiMulti wifiMulti;

int MySQL_Connected;


// Sample query
char query[] = "SELECT val FROM ts_number WHERE ID=5 ORDER BY ts DESC LIMIT 1";

IPAddress server_addr(x,x,x,x);       // IP of the MySQL *server* here
char user[] = "user";                      // MySQL user login username
char password[] = "pass";               // MySQL user login password

WiFiClient client;            // Use this for WiFi instead of EthernetClient
MySQL_Connection conn((Client *)&client);

void setup() 
{
  Serial.begin(115200);
  
  WiFi.mode(WIFI_STA);
  
  wifiMulti.addAP("XXXXXX", "xxxxxxxx");
  wifiMulti.addAP("xxxxxxx", "xxxxxxxx");
  

  Serial.println("Connecting Wifi...");
  
}

int MySQL_Conn ()
  {
   Serial.println("Connecting MySQL...");
   if (conn.connect(server_addr, 3306, user, password))
     {
     MySQL_Connected == 1;
     Serial.println("MySQL Conn OK ");
     Serial.println("MySQL Query..K ");
    // Initiate the query class instance
 MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);
 // Execute the query
 cur_mem->execute(query);
 // Fetch the columns (required) but we don't use them.
 column_names *columns = cur_mem->get_columns();
 
 
 delete cur_mem;

     }
   else
     Serial.println("Connection failed.");
     MySQL_Connected == 0;
     conn.close();   
   }
  
void loop() 
 {
 

      
   if (wifiMulti.run() == WL_CONNECTED) 
    {
     MySQL_Conn ();
     Serial.println("IP address: ");
     Serial.println(WiFi.localIP());
     Serial.println("SSID: ");
     Serial.println(WiFi.SSID());
     Serial.println("RSSI: ");
     Serial.println(WiFi.RSSI());  
     }
  delay(10000);  
  }

Danke
pat

Wenn Du den Cursor schon holst, musst Du ihn auch auslesen, um Deinen Wert zu erhalten.

 cur_mem->execute(query);
 // Fetch the columns (required) but we don't use them.  <<-- Das gilt nicht für Dich
 column_names *columns = cur_mem->get_columns();
     
  <<----------- hier musst Du den Wert Deiner Spalte lesen. Wie steht doch in den Beispielen z.B. Basicselect
 delete cur_mem;

Einen ungelesenen Wert kannst Du nunmal nicht auswerten.

Gruß Tommy

Hallo Tommy

Danke werde mich weiter einlesen.
Ansonsten melde ich mich wieder…

pat

Alles klar. Die Lib hat eigentlich gute Beispiele dabei.

Gruß Tommy

Hallo Tommy

Habe nun einiges probiert. Leider scheint der Cursor bei mir nichts zu finden....

// Fetch the columns (required) but we don't use them.
 column_names *columns = cur_mem->get_columns();

 // Read the row (we are only expecting the one)
  do {
    row = cur_mem->get_next_row();
    if (row != NULL) {
            head_count = atol(row->values[0]);
    }
  } while (row != NULL);
  
  // Deleting the cursor also frees up memory used

 // Show the result
  Serial.print("  DB_Eintrag = ");
  Serial.println(head_count);
 delete cur_mem;

Wo kann ich die Debug-Ausgabe aktivieren?

Danke nochmals pat

Da musst Du in die Libs rein schauen. Das habe ich auch seit 2 Jahren nicht mehr gemacht.

Hast Du die Query mal direkt in einem SQL-Tool (meine Empfehlung: Heidi SQL) gegen die DB getestet?

Das Create Table bist Du mir immer noch schuldig.

Gruß Tommy

Da gibt es 100-te Libs, die eine funktioniert, die andere nicht.
Die Uhrzeit hier im Beispiel kommt von NTP, also nicht stören lassen.
Die Zugangsdaten SQLHost, SQLPort, SQLUser und und SQLPass habe ich im Eeprom gespeichert.

#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>

function save2sql() {
  if (conn.connect(stringToIP(SQLHost), SQLPort.toInt(), stringToChar(SQLUser), stringToChar(SQLPass))) {
    Serial.println(F("Connection established"));
    char current_time[20];
    sprintf(current_time, "%04d-%02d-%02d %02d:%02d:%02d", year(local_time), month(local_time), day(local_time), hour(local_time), minute(local_time), second(local_time));

    // query
    String INSERT_SQL = "INSERT INTO " + SQLDatabase + ".tbl_data (date_time, sensor, battery_voltage, load_current, temperature, humidity, moisture, pressure, brightness) "\
      "VALUES ('" + String(current_time) + "', '" + DeviceName + "', " + LastBatteryVoltage + ", " + LastLoadCurrent + ", " + LastBmeTemperature + ", " + LastBmeHumidity + ", " + LastMoisture + ", " + LastBmePressure + ", " + LastBrightness + ")";

//      Serial.print(F("Saving Data: "));
//      Serial.println(INSERT_SQL);
  
    // Initiate the query class instance
    MySQL_Cursor *cursor = new MySQL_Cursor(&conn);
    if (cursor) {
      // Execute the query
      cursor->execute(INSERT_SQL.c_str());
    }
    // Note: since there are no results, we do not need to read any data
    // Deleting the cursor also frees up memory used
    delete cursor;
    conn.close();      
  }
  else {
    Serial.println(F("Connection failed"));
  }
}
}

Das Beispiel ist von meiner Wetterstation und funktioniert 1A.
Die Fields und Values müssen halt entsprechend angepasst werden.
ich such noch mal schnell die original Lib raus, dann poste ich den Link dazu.

Hier der Link: Arduino SQL

Hallo Tommy

Also was ich mittlerweile rausgefunden habe ist, dass die Abfrage in folgender Schleife landet:

// Read the row (we are only expecting the one)
  do {
    row = cur_mem->get_next_row();
    if (row != NULL) {
      
      head_count = atol(row->values[0]);
    }
  } while (row != NULL);
  
  -> Die Schleife wird hier abgearbeitet, also kein Eintrag gefunden! <- head_count bleibt 0

Betr. CREATE TABLE :o

Meinst Du meine best. Tabelle?
Im Anhang ein Bild davon.

Sorry, aber Stück für Stück… :wink:

Danke
patrick

freddy64:
Hier der Link:
Arduino SQL

Hallo Freddy

Ist eigentlich auch meine LIB

patrick

Ich meine das Create Table als [u]Text[/u], so dass ich die Tabelle testweise anlegen kann und Deinen Select dagegen testen kann.

Gruß Tommy

OK, hoffe dies hilft...

--
-- Tabellenstruktur für Tabelle `ts_number`
--

CREATE TABLE `ts_number` (
  `id` int(11) NOT NULL,
  `ts` bigint(20) NOT NULL,
  `val` double DEFAULT NULL,
  `ack` tinyint(1) DEFAULT NULL,
  `_from` int(11) DEFAULT NULL,
  `q` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Daten für Tabelle `ts_number`
--

INSERT INTO `ts_number` (`id`, `ts`, `val`, `ack`, `_from`, `q`) VALUES

(2, 1548011460594, 4.708, 1, 1, 0)

incl. ein Datensatz

Danke!

Ok. Die Tabelle und der Select verstehen sich erst mal formal. Wobei mit ID = 5 natürlich nichts gefunden wird.

Dein Provider läßt direkte Fremdzugriffe auf die DB zu? Baue doch mal serielle Ausgaben in die Cursor-Schleife ein.

Gruß Tommy

Tommy56: Ok. Die Tabelle und der Select verstehen sich erst mal formal. Wobei mit ID = 5 natürlich nichts gefunden wird.

Ja, war beim letzten Versuch so, ist aber aktuell die ID 2 drin.

Tommy56: Dein Provider läßt direkte Fremdzugriffe auf die DB zu?

Ja

Tommy56: Baue doch mal serielle Ausgaben in die Cursor-Schleife ein.

Gruß Tommy

Habe ich gemacht. Siehe Posts vorher.

Werd mal etwas weiter "probieren"...

// Read the row (we are only expecting the one)
  do {
    Serial.print(" schleife 1");
    row = cur_mem->get_next_row();
    if (row != NULL) {
      Serial.print(" schleife 2");
      head_count = atol(row->values[0]);
    }
  } while (row != NULL);
  Serial.print(" schleife 3");
  // Deleting the cursor also frees up memory used

 // Show the result
  Serial.print("  DB_Eintrag = ");
  Serial.println(head_count);
 delete cur_mem;

Schleife 1 und 3 werden nur durchlaufen....

Also ist row NULL.

Gruß Tommy

So wird's auch ausgegeben... ;-) obwohl was drin steht...

Schreibe mal in Deinen Sketch:

#define DEBUG 1

Das sollte evtl. die Debugausgaben der Lib einschalten.

Gruß Tommy