Mysql embedded Server von VCC 7.0 läuft nicht an



  • Squeegee schrieb:

    Die lib ist ja bei der noinstall-Windows Version von mysql schon dabei, die dll soll man sich selber machen.

    ??
    eher umgekehrt, z. B. kann der Borland Compiler oder auch der MinGW mit
    der libmyslq(d).lib nix anfangen, da die nur für's VS da ist.
    In diesem Fall gibts für Borland "implib.exe" fürn gcc das "dlltool.exe" zum
    Erstellen der Importlibrary aus der libmysql(d).dll

    Für's VS gibts glaub ich "lib.exe", aber keine Ahnung, wie man das verwendet.
    Aber wie gesagt, die lib die dabei ist sollte schon funktionieren.

    Squeegee schrieb:

    Hat vielleicht jemand diese beiden Dateien (libmysqld.lib und libmysqld.dll) in getesteter Version und kann sie mir zukommen lassen?

    Lad dir doch einfach MySQL neu runter und verwende dann die dll + lib von der
    grade runtergeladenen.
    Dann passen die in jedem Fall zusammen.

    Was auch noch sein kann:
    Existiert evtl. das Verzeichnis, in dem der embedded Server seine Dateien
    ablegt nicht? Dann steigt das server_init auch aus.
    Das Verzeichnis ist zu finden unter "datadir=..." in der config
    (entweder bei den serverargs oder in der config-Datei in der entsprechenden Gruppe)

    @Unix-Tom:
    oder hast du das mit "datenfiules" gemeint?



  • Ja hab ich. War nur ein Tipfehler.
    Datenfiles sind für mich alles was der Server braucht.



  • Hi,
    hmmm, my.ini...
    Frage: Ich hab nur die, die beim Windows-Installer automatisch mitinstalliert wurde und die liegt in meinem Installationsverzeichnis.
    Findet die der Server die an der Stelle?



  • Hi,
    ich bins schon wieder!
    Hatte wohl tatsächlich einen Versionskonflikt zwischen meiner dll und meiner lib...
    Bin zugegebenermaßen nie auf die Idee gekommen, dass es die DLL auch fertig gibt.
    Bei der Version mit dem Installationstool für Windows ist sie nämlich nicht dabei, nur bei der noinstall-Version. 🙂
    Irgendwie stell ich mich wohl etwas an, aber ich hab jetzt noch ein Problemchen, nämlich folgende Fehlermeldung:

    ...Can't find messagefile '*C:\mysql\share\english\errmsg.sys'

    Den Pfad geb ich ja in der my.ini ab, aber:
    Kann ich den Pfad, wo die my.ini liegen soll, anpassen, bzw. warum findet er meine my.ini im windows-Verzeichnis nicht, da soll sie doch eigentlich laut Referenzhandbuch hin?
    Slash oder Backslash, laut Referenzhandbuch Slash in der Fehlermeldung aber Backslash?

    Dann hab jetzt einfach einen Dateipfad so angelegt, wie es in der Fehlermeldung verlangt wird und das File dorthin kopiert. Jetzt steigt er schon wieder kommentarlos aus 😡

    Danke für eure Geduld mit mir

    Gruß Squeegee



  • ich geb dir jetzt einfach mal meine Config für den mysql_embedded_server:

    static char *server_args[] = {
      "myNiceProgram", // program
      "--defaults-extra-file=my.ini"
    };
    
    static char *server_groups[] = {
      "embedded",
      "server",
      "myNiceProgram_settings",
      (char *)NULL
    };
    
    mysql_server_init(sizeof(server_args) / sizeof(char *),  server_args, server_groups);
    

    das "--defaults-extra-file=my.ini" gibt ihm an, dass er die my.ini im selben Verzeichnis wie die exe suchen soll (bzw. vermutlich auch alle Verzeichniss der
    path-Umgebungsvariablen)

    Und hier noch die my.ini selber:

    [embedded]
    basedir="."
    datadir="./data"
    default-character-set=latin1
    default-storage-engine=INNODB
    language="."
    

    die errmsg.sys sucht er dort, wo's ihm mit "language=" gezeigt wird.
    In diesem Fall also im selben Verzeichnis wie die exe Datei.
    => einfach mal im mysql Installationsverzeichnis danach suchen und rüberkopiern



  • Hi,

    hab dein Skript ausgetestet, erzeugt wieder die Fehlermeldung, dass er die errmsg.sys nicht findet, wenn ich diese im gleichen Verzeichnis wie die exe habe.
    Dort hab ich auch die my.ini mit deinen Änderungen.
    Kopiere ich die errmsg.sys wieder nach C:\mysql\share\english\, steigt er wieder kommentarlos aus. 😡
    Kann es sein, dass er die my.ini einfach nicht findet (warum auch immer) und dann mit Standarwerten zu starten versucht, was logischerweise nicht funktioniert? 😕

    Falls jemand noch ne Idee hat, bin für alles zu haben. Ich werds jetzt mal auf nem anderen Rechner testen, auf dem überhaupt kein MySQL installiert ist, ob da dasselbe Problem besteht.

    Gruß Squeegee



  • mal eine blöde Frage:
    Was ist eigentlich VCC 7.0?
    Hab bisher nur schnell drübergeschaut und bin von Visual Studio
    ausgegangen.
    Google bringt für "VCC 7.0" nur wirres Zeug.

    Egal.

    Habs jetzt grad mal ausprobiert mit Dev-C++ (eigentlich wxDev-C++, aber sollte
    eigentlich egal sein).
    Ausserdem dürfte es auch in anderen Compilern ähnlich funktioniern,
    der Unterschied liegt in der Importlib für die libmysqld.dll.
    (
    Erstellung der importlib für gcc: siehe hier:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-100731-and-highlight-is-.html#719609

    für Borland Compiler:
    http://www.c-plusplus.net/forum/viewtopic.php?t=88356

    für Visual Studio:
    die libmysqld.lib wird mit mysql schon mitgeliefert
    )

    #include <iostream>
    #include <stdexcept>
    #include <winsock.h>
    
    #include "../include/mysql/mysql.h"
    
    int run();
    
    int main()
    {
        try
        {
        run();      
        std::cin.get();
        return 0;
        }
    
        catch (std::exception & Ex)
        {
        std::cerr<<Ex.what()<<std::endl;
        std::cin.get();
        return 1;
        }
    
        catch (...)
        {
        std::cerr<<"unknown exception detected"<<std::endl;
        std::cin.get();
        return 2;      
        }
    }
    
    int run()
    {
    
    static char *server_args[] = 
    {
    "myNiceProgram", // program
    "--defaults-extra-file=my.ini"
    };
    
    static char *server_groups[] = {
    "embedded",
    "server",
    "myNiceProgram_settings",
    (char *)NULL
    };
    
    // Server initialisieren
    mysql_server_init(sizeof(server_args) / sizeof(char *),  server_args, server_groups);
    
    // Datenbankhandle initialisieren
    
    MYSQL *  m_dbHandle = mysql_init(NULL);
    
    // Verbindung herstellen
    mysql_real_connect(m_dbHandle, "", "", "", "", 0, NULL, 0);
    
        // Fehler abfangen
    	if (mysql_errno(m_dbHandle) > 0)
    	{
    	std::string errorMsg = mysql_error(m_dbHandle);
    	throw std::runtime_error(errorMsg.c_str());
    	}
    
    int errorNumber;
    std::string query = "create database if not exists myDatabase";
    errorNumber = mysql_real_query(m_dbHandle, query.c_str(), query.length());
    
        // Fehler abfangen
    	if (errorNumber > 0)
    	{
    	std::string errorMsg = mysql_error(m_dbHandle);
    	throw std::runtime_error(errorMsg.c_str());
    	}
    
    query = "use myDatabase";
    errorNumber = mysql_real_query(m_dbHandle, query.c_str(), query.length());
    
        // Fehler abfangen
    	if (errorNumber > 0)
    	{
    	std::string errorMsg = mysql_error(m_dbHandle);
    	throw std::runtime_error(errorMsg.c_str());
    	}
    
    query = "create table if not exists myTable (id int not null primary key auto_increment, name varchar(255))";	
    errorNumber = mysql_real_query(m_dbHandle, query.c_str(), query.length());
    
        // Fehler abfangen
    	if (errorNumber > 0)
    	{
    	std::string errorMsg = mysql_error(m_dbHandle);
    	throw std::runtime_error(errorMsg.c_str());
    	}
    
    query = "insert into myTable (name) values('Huaba'), ('Meier')";
    errorNumber = mysql_real_query(m_dbHandle, query.c_str(), query.length());
    
        // Fehler abfangen
    	if (errorNumber > 0)
    	{
    	std::string errorMsg = mysql_error(m_dbHandle);
    	throw std::runtime_error(errorMsg.c_str());
    	}
    
    query = "select name from myTable";
    errorNumber = mysql_real_query(m_dbHandle, query.c_str(), query.length());
    
        // Fehler abfangen
    	if (errorNumber != 0)
    	{
    	std::string errorMsg = mysql_error(m_dbHandle);
    	throw std::runtime_error(errorMsg.c_str());
    	}
    
    // Abfrageergebnis
    // Vorsicht: hier normalerweise mysql_store_result verwenden
    // näheres siehe Doku der mysql c-api
    MYSQL_RES * result = mysql_use_result(m_dbHandle);
    errorNumber =  mysql_errno(m_dbHandle);
    
        // Fehler abfangen
    	if (errorNumber != 0)
    	{
    	std::string errorMsg = mysql_error(m_dbHandle);
    	throw std::runtime_error(errorMsg.c_str());
    	}
    
    	// Wenn ein Ergebnis vorliegt
        if (result != NULL)
        {
        int numberCols = mysql_num_fields(result);
    
            // über alle Zeilen drüberlaufen
            while (MYSQL_ROW row = mysql_fetch_row(result))
            {
            // die Datenlängen der einzelnen Felder
            // (für Binärdaten?)
            unsigned long * lengths = mysql_fetch_lengths(result);
    
                     // über alle Spalten drüberlaufen
                     for (int col = 0; col < numberCols; col ++)
                     {
                     std::cout<<row[col]<<", ";
                     }
    
            std::cout<<std::endl;
            }
        }
    
    // Ergebnis freigeben
    mysql_free_result(result);
    
    // Verbindung trennen
    mysql_close(m_dbHandle);
    
    // embedded server beenden
    mysql_server_end();
    
    return EXIT_SUCCESS;
    }
    

    Zwei Anmerkungen:
    War grad zu faul, mir ne neue Importlib zu erstellen,
    drum wird oben mysql_real_query() und mysql_use_result() anstatt
    mysql_query() und mysql_store_result() verwendet.

    Weiteres vorgehen:
    eine my.ini erstellen und ins selbe Verzeichnis wie die entstandene exe kopieren
    (Inhalt: siehe Beitrag oben)

    im mysql-Installationsverzeichnis nach errmsg.sys und errmsg.txt suchen, beide Dateien auch zu der exe ins Verzeichnis kopieren

    Im Verzeichnis mit der exe einen Unterordner "data" erstellen

    Fertig.



  • Hi,
    es tut 😃 😃
    Ich kanns noch nicht ganz glauben, aber es tut! So lang hab ich noch selten gebraucht, um ein Problem zu lösen. Und wie erwartet, wars was ganz Banales:
    Das Data-Verzeichnis hat gefehlt! Steht aber irgendwie auch nix davon in meinem Buch oder sonstwo, wo ich geschaut hab. Na, egal.
    Vielen Dank für eure ausdauernde Hilfe.

    Gruß Squeegee



  • anonymus schrieb:

    Zwei Anmerkungen:
    War grad zu faul, mir ne neue Importlib zu erstellen,
    drum wird oben mysql_real_query() und mysql_use_result() anstatt
    mysql_query() und mysql_store_result() verwendet.

    Das will mir jetzt nicht einleuchten...
    Die MySQL-Hilfe sagt zu mysql_real_query nur:

    You must use mysql_real_query() rather than mysql_query() for queries that contain binary data, because binary data may contain the ‘\0’ character. In addition, mysql_real_query() is faster than mysql_query() because it does not call strlen() on the query string.

    und ob mysql_use_result und mysql_store_result ist auch eine Frage dessen, was mach machen möchte/welche Umstände gegeben sind:

    mysql_store_result() reads the entire result of a query to the client, allocates a MYSQL_RES structure, and places the result into this structure.

    mysql_use_result() initiates a result set retrieval but does not actually read the result set into the client like mysql_store_result() does. Instead, each row must be retrieved individually by making calls to mysql_fetch_row(). This reads the result of a query directly from the server without storing it in a temporary table or local buffer, which is somewhat faster and uses much less memory than mysql_store_result(). The client allocates memory only for the current row and a communication buffer that may grow up to max_allowed_packet bytes.

    On the other hand, you shouldn't use mysql_use_result() if you are doing a lot of processing for each row on the client side, or if the output is sent to a screen on which the user may type a ^S (stop scroll). This ties up the server and prevent other threads from updating any tables from which the data is being fetched.

    When using mysql_use_result(), you must execute mysql_fetch_row() until a NULL value is returned, otherwise, the unfetched rows are returned as part of the result set for your next query. The C API gives the error Commands out of sync; you can't run this command now if you forget to do this!

    You may not use mysql_data_seek(), mysql_row_seek(), mysql_row_tell(), mysql_num_rows(), or mysql_affected_rows() with a result returned from mysql_use_result(), nor may you issue other queries until the mysql_use_result() has finished. (However, after you have fetched all the rows, mysql_num_rows() accurately returns the number of rows fetched.)



  • Hallo Squeegee
    Ist zwar schon ne Weile her, dass du die Fragen hier gestellt hast, aber vielleicht antwortest du ja noch mal 😕
    Wie ich gelesen habe, hast du dir vor einiger Zeit genau die selbe Frage gestellt wie ich. Und zwar das Problem mit den Linkererrors beim Versuch die C API in Visual Studio einzubinden.

    Ich habe MySQL ganz normal installiert, die lymaysql.dll ins system32 Verzeichnis kopiert und die Libs und Header eingebunden. Trotzdem ne lange Liste voller Headerfehler. Was hast du damals für #defines eintragen müssen um das los zu bekommen?

    Gruß Curry



  • Hi Curry,
    was genau willst du denn machen? Über die C-Api Zugriff auf einen laufenden Mysql-Server realisieren (dazu benötigst du die von dir beschriebene libmysql.dll und die libmysql.lib) oder willst du einen embedded Server erstellen, also einen mysql-Server mit in dein Programme integrieren (dazu benötigst du die libmysld.dll und die libmysld.lib). Was für Fehlermeldungen bekommst du denn genau? Ich hatte da ne ganze Reihe von verschiedenen Fehlern. 😃
    Defines hab ich allerdings gar keine gebraucht.
    Welche Version von Visual benützt du? .net?

    Gruß Squeegee



  • Squeegee schrieb:

    Das Data-Verzeichnis hat gefehlt! Steht aber irgendwie auch nix davon in meinem Buch oder sonstwo, wo ich geschaut hab.

    Dann hast du also das hier
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-119360-and-postdays-is-0-and-postorder-is-asc-and-start-is-0.html#862525

    oder auch das hier (untere Hälfte)
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-119360-and-postdays-is-0-and-postorder-is-asc-and-start-is-0.html#862591

    nicht angeschaut 😮

    @ -=]xXx[=-:
    hast schon recht, es kommt drauf an, was man machen möchte.
    Aber ich denk mal, dass ein mysql_store_result() die besser Lösung
    ist, wenn man nicht vorhat, das ganze Recordset selber zu verwalten...
    (Wiederverwendung von Speicher...)



  • Nimm mysql_store_result wenn es nichts ausmacht die ganze Ergebnismenge in den Speicher des Clients zu lesen.
    Dadurch hat man auch bestimmte feature (mysql_funktionen) die weitere Infos liefern. (Anzahl der Datensätze aus der Ergebnismenge, Spalteninfos, man kann selbst vor und zurück durch das Ergebnis gehen). Das geht mit use__result nicht.
    Es gibt sicher Fälle wo use_result verwendung findet. use_reult kann aber den Server blockieren.



  • Hi anonymos,
    das Datadir hatte ich, aber da war wohl ein Fehler im Syntax / und \ ...
    siehe einen meiner ersten Beiträge...

    Gruß Squeegee



  • Ich hatte vor den Server mit ins Programm einzubinden. Leider bekamm ich hunderte von Linkererrors. Vermute, das er die Bibliothek gar nicht oder Fehlerhaft einbindet. Habe aber absolut keine Ahnung was ich da machen sollte. Erst hatte ichs unter Visual Studie 2003 .Net probiert, dann unter Visual Studio 6. Muss man da außer dem MySQL Server noch was anderes Installieren und wenn ja, muss man da noch irgendwelche Datein umherkopieren? Und zu guter letzt, wo binde ich in Visual die Datein ein? Bin mir sicher das bei mir bei einem falschen Vorgehen hier irgendwas durcheinander gekommen ist.
    Jo, und weil das alles nicht lief, hab ich erst mal angefangen den ganzen schmarrn unter Dev C++ zu schreiben. Und dort hab ich jetzt ähnliches Prob wie Sqeegee. Ich muss eine txt auslesen, in der das Verzeichnis zur Tabelle liegt. Muss das also irgendwie über mysql_server_init() machen.

    Kurze Frage noch an dich Sqeegee. Mich verdutzt es, dass ich in letzter Zeit genau die selben Fragen wie mich beschäftigen. Du studierst nicht zufälliger Weise unter Prof. Eisenecker in Leipzig Winf oder?



  • Vermutlich hast du die importlib nicht dazugelinkt.

    Im VisualStudio .Net 2k3:
    Rechts in der Projektmappe rechtsklick auf den Projektnamen
    ->Hinzufügen->Vorhandenes Element hinzufügen

    Im Dateiauswahldialog umstellen auf "Alle Dateien (.)" und dann im
    MySQL Installationsverzeichnis->Embedded->DLL->debug(bzw. release)->libmysqld.lib
    (siehe hierzu auch http://www.c-plusplus.net/forum/viewtopic-var-t-is-117543-and-highlight-is-.html#851179

    unter Dev-CPP
    die Importlib von oben geht nur im Visual Studio.
    Der gcc kann damit nix anfangen.
    Drum die importlib selber erstellen,
    siehe hier: http://www.c-plusplus.net/forum/viewtopic-var-t-is-100731-and-highlight-is-.html#719609
    Anstatt die def-Datei mit pexport zu erstellen, sollte auch die def-Datei funktionieren, die bei den ganzen Mysql-include Dateien dabei ist funktionieren
    (libmysqld.def), aber hab ich ned getestet. Allerdings muss auch diese mit den @XX angepasst werden.

    Wenn die importlib erstellt ist, muss diese zum Projekt hinzugelinkt werden:
    Project->Project Options->Parameters
    da sind drei listboxen; unter der rechten gibt's einen Button "Add Library or Object". Da draufklicken und die oben erstellte importlib auswählen.



  • Hi curry,
    so machen, wie anonymos es schrieb, so hab ichs bei Visual auch gemacht. Dann halt das Data-Verzeichnis in dem Verzeichnis wo deine Exe liegt nicht vergessen und die my.ini wie in einem der vorigen Beiträge dieser Diskussion beschrieben verändern, dann sollte es tun.
    Ach so, die libmysqld.dll sollte natürlich unter windows\system32 zu finden sein...

    Evtl. bekommst du dann in der mysgl.h und/oder der mysql_com.h noch ein paar Compilerfehler, schau dir den Code dort mal an, das müssten dann Codeteile sein, die für andere Betriebssysteme sind, diese Teile einfach auskommentieren, dann sollte es tun

    Ich studier nicht in Leipzig, versuch mich aber grade an ner Diplomarbeit an der FHT Esslingen und versuche mit bescheidenen MFC-Kenntnissen ein Winprog zu schreiben.

    Gruß Squeegee



  • Kurze Fage??
    Bei mir existiert im MySQL Installationsverzeichnis kein Ordner Names Embedded und somit hab ich auch keine libmysqld.dll auf meinem Rechner gefunden. Woher bekomme ich diese Datei?

    Zweites Problem: Den Rest hab ich wie benannt dazugelinkt (In dem ganzen Microsoftverzeichniswirrwar) jetzt kann ich zwar mit VS.Net kompilieren und er führt das Programm auch aus und wandert vorbildlich über den Quelltext, er fügt aber nichts in meine Datenbank ein.
    Wenn Dev nicht so nen lausigen Debugger hätte würde ich's wahrscheinlich mitlerweile lieber darüber zu ende programmieren.

    Und drittens: Da ich ja nun mitlerweile mal auf ne Gruppe von Leutchen gestoßen bin, die meine Probleme verstehen, wollte ich gleich mal noch fragen, wie ich mir zurück geben lassen kann, wieviele Zeilen bei einer Selectabfrage betroffen waren. So wie ich das programmiert habe funktionierts irgendwie nicht. Hatte mir das so gedacht, dass ich zu begin einer Datenaktualisierung (Quellcode hiervon fehlt) oder dem Hinzufügen eines neuen Datensatzes überprüfe, ob dieser schon existiert. Wenn ja, soll ein weites hinzufügen verboten werden.

    bool data_connection::check_entry(const Notice &n){
       std::stringstream check_query;
       check_query << "SELECT * FROM notice_table WHERE date = '"
                   << dateToString(n)
                   << "' AND time = '"
                   << timeToString(n)
                   << "'";
       // Anfrage an die Datenbank
       mysql_real_query(mysql, check_query.str().c_str(), check_query.str().size());
       PRUEFE_SQL_STATUS(mysql);
    
       unsigned int i = mysql_affected_rows(mysql);
       if( i == 0){
          return 0;   
       }
       else{
          return 1;
       }
    };
    
    void data_connection::notice_add(const Notice &n){
       if(check_entry(n)){
          std::stringstream insert_query;
          insert_query    << "INSERT INTO notice_table (date, time, notice_entry) VALUES ('"
                          << dateToString(n)
                          << "','"
                          << timeToString(n)
                          << "','"
                          << n.notice()
                          << "')";
        // Anfrage an die Datenbank
        mysql_real_query(mysql, insert_query.str().c_str(), insert_query.str().size());
        PRUEFE_SQL_STATUS(mysql);
       }
       else {message("Der von Ihnen eingegebene \n Datensatz existiert bereits");}
    }
    

    Danke für eure Hilfen
    Gruß Curry



    von MySQL gibts verschiedene Versionen
    (zip, kleiner und grosser Installer)

    Beim "kleinen" Installer kann's durchaus möglich sein,
    dass dorten der embedded Server nicht mit dabei ist.

    Beim "grossen" Installer muss man bei der Installation auswählen,
    dass auch der embedded Server mitinstalliert wird.

    Zip-Version weiss ich ned

    Wie kann das Programm korrekt laufen, wenn du die libmysqld.dll nicht hast?

    Schau dir mal den Unterschied zwischen
    mysql_affected_rows()
    und
    mysql_num_rows()
    an

    Nochwas:
    wenn Datensätze eindeutig sein sollen, wäre es imho sinnvoller, die entsprechende
    Spalte in der Datenbank als "unique" zu kennzeichnen.
    Dann prüft das die Datenbank automatisch und liefert einen entsprechenden Fehler, falls der Eintrag schon vorhanden ist.



  • Ohne mein dazutun und ohne libmysqld.dll läuft jetzt mysql unter .Net. Fragt mich net warum, ich hab einfach alles eingebunden und Rechner neu gestartet. Jetzt aktualisiert er auch die Daten in der Datenbank. alles nur mit der libmysql.dll die bei Visual Studio schon dabei war. Ich vermute, dass er aus dieser die unterschiede der libmysql.def und libmysqld.def schon kennt, welche im include - Verzeichnis von mysql liegen.
    Danke für den Tip mit unique. Werde ich gleich mal umsetzen. Hab mir bisweilen damit geholfen MYSQL_RS * mysql_RS = mysql_store_result() zu misbrauchen, indem ich abgefragte habe, wieviele row_count vom zurücksetzen der Abfrage betroffen waren.

    Gruß Curry


Anmelden zum Antworten