ODBC und MFC (Datenbank ansprechen)



  • Hallo,

    ich muss mein Thema aus dem Forum Datenbanken hier nochmal aufnehmen. Ich habe einen MySQL-Datenbank-Server (Version 5.0) auf meinem Rechner laufen und will per ODBC drauf zugreifen. Der ODBC Treiber (Version 3.51) ist korrekt installiert und dort wird auch beim Verbindungstest kein Fehler angezeigt.
    Will ich jetzt ein MFC-Projekt mit Datenbankunterstützung erstellen, kann ich irgendwie nicht auf die DB zugreifen. Ebenso ist es, wenn man eine ODBC-Consumer-Klasse einfügen will. Ich habe ein anderes ODBC-basierendes Projekt auf die MySQL-DB umgeschrieben. Bei Codeproject gibts einen Thread der die entsprechenden Connection-Strings beschreibt. Beim Starten erscheint nur ein leeres Medlungsfenster ohne Text. Im Debugfenster steht dann folgendes:

    'MySQLTest.exe': 'C:\WINNT\system32\ODBCCR32.dll' geladen, Keine Symbole geladen.
    DBMS: MySQL
    Version: 5.0.24a-community-nt
    ODBC Driver Manager Version: 03.52.0000
    CmySQLTestSet::GetDefaultSQL()
    Eine Ausnahme (erste Chance) bei 0x77e9bc81 in MySQLTest.exe: Microsoft C++ exception: CODBCException @ 0x0012f6ec.
    Eine Ausnahme (erste Chance) bei 0x77e9bc81 in MySQLTest.exe: Microsoft C++ exception: CDBException @ 0x0012f724.
    Eine Ausnahme (erste Chance) bei 0x77e9bc81 in MySQLTest.exe: Microsoft C++ exception: [rethrow] @ 0x00000000.
    'MySQLTest.exe': 'C:\WINNT\MUI\fallback\0407\msctf.dll.mui' geladen, Keine Symbole geladen.
    'MySQLTest.exe': 'C:\Programme\Logitech\MouseWare\system\LGMOUSHK.DLL' geladen, Keine Symbole geladen.
    Warning: Uncaught exception in WindowProc (returning 0).
    'MySQLTest.exe': 'C:\WINNT\system32\ODBCCR32.dll' entladen
    'MySQLTest.exe': 'C:\WINNT\system32\mfc42.dll' entladen
    'MySQLTest.exe': 'C:\WINNT\system32\mfc42loc.dll' entladen
    'MySQLTest.exe': 'C:\WINNT\system32\myodbc3.dll' entladen
    'MySQLTest.exe': 'C:\WINNT\system32\wshtcpip.dll' entladen
    'MySQLTest.exe': 'C:\WINNT\system32\RNR20.DLL' entladen
    'MySQLTest.exe': 'C:\WINNT\system32\winrnr.dll' entladen
    Der Thread 'Win32 Thread' (0x1dc) hat mit Code 0 (0x0) geendet.
    Der Thread 'Win32 Thread' (0x2a8) hat mit Code 0 (0x0) geendet.
    Das Programm "[848] MySQLTest.exe: Systemeigen" wurde mit Code 0 (0x0) beendet.

    Woher kommen die Exceptions und wie kann ich das Problem lösen?

    Habs jetzt mal mit OLE DB versucht, da scheint es zu funktionieren. Ist jemanden so was schon bekannt?



  • Versuch mal, die Exceptions zu fangen. 😉



  • estartu schrieb:

    Versuch mal, die Exceptions zu fangen. 😉

    Wenn ich wüsste, wo die geworfen werden? Ich habe jediglich eine Klasse, die von CRecordset abgeleitet ist. In der gibts folgende Methode, die ja vom Assistenen (und von mir) überschreiben worde:

    CString CMySQLTestSet::GetDefaultConnect()
    {
    	TRACE("CMySQLTestSet::GetDefaultConnect()\n");
    		return _T("Driver={MySQL ODBC 3.51 Driver};Server=localhost;Database=test;User=root;Password=mypasswd;Option=3;");
    
    }
    

    Die Exception wird nach dem Starten der Anwendung nach Ausführung dieser Methode geworfen. Sie führt aber nicht zum Abbruch des Programms. Wenn man dann Zugriffe auf die DB durchführen will kommt das gleiche Problem. Es erscheint immer ein ca. 3x2cm großes leeres Meldungsfenster mit dem roten Symbol. Komisch ist auch wenn man es mit dem Assistenten anlegen will, dann kommt immer bei der Auswahl der im Treiber angelegten Datenquelle die Meldung: "Loading database list not implemented for SQLDriverConnect()" und dann hat er natürlich keine Datenquelle wählen können. Hat das was mit dem Treiber oder dem Visual Studio zu tun? Verwende VS .net 2003

    Bin etwas ratlos, so viel Ahnung habe ich auch nicht davon. Kann es noch irgendwie an falsch gesetzten Rechten liegen? Jemand hat mir noch gesagt, dass eventuell der Treiber kein "SHOW DATABASES" ausführen kann. Wo kann man das einstellen und warum funktionierts beim Anlegen der Quelle im ODBC-Treiber?



  • Schau dir doch mal den Callstack an, während die leere Meldung gezeigt wird.
    Evtl. wäre der Callstack von GetDefaultSQL auch ein Ansatz.

    Machst du denn irgendwo ein Open oder so? Dann würde das try-catch da drum gehören. 😉



  • estartu schrieb:

    Schau dir doch mal den Callstack an, während die leere Meldung gezeigt wird.
    Evtl. wäre der Callstack von GetDefaultSQL auch ein Ansatz.

    Machst du denn irgendwo ein Open oder so? Dann würde das try-catch da drum gehören. 😉

    Der letzte Eintrag ist ca. die 10 Zeile aus meinem letzten Post, die dann noch im Aufruffenster steht. Ich mache weder ein Open noch sonst was, es wird einfach eine Instanz der im Programm erzeugten Klasse angelegt, die von CRecordset abgeleitet ist. Offensichtlich löst der Konstruktor das aus. So tief bin ich da auch noch nicht reingestiegen. Das mit dem try/catch versuche ich ja eigentlich immer konsequent durchzuziehen, nur bin ich noch nicht mal soweit damit zu arbeiten. Hast du noch eine Idee?


  • Mod

    Wenn Du einen Breakpoint auf den GetDefaultConnect setzt, dann kannst Du durch den Code weiter durch tracen bis Du an die Open Stelle kommst. Ich vermute das evtl. Dein Connection String falsch ist.



  • Die vielen Zeilen in deinem ersten Post sind nicht der Callstack sondern die Debugausgabe. 😉

    Klick mal (während das Debuggen läuft) irgendwo mit der rechten Maustaste auf eine leere Stelle einer Symbolleiste.
    Dann klick da mal auf Callstack bzw. Aufrufliste. Dann sollte die erscheinen oder verschwinden. Wenn du sie weggeschaltet hast, schalte sie wieder dazu.
    Nun guck DAS Fenster im Zusammenhang mit meinem letzten Post nochmal an. 😉



  • @Martin: Das vermute ich auch. Ich habe schon ziemlich viele Varianten durchprobiert, aber keine funktioniert. Als Quelle habe ich zum einen die Seite www.connectionstrings.com und zum anderen einen Thread auf codeproject genommen. Dort war erklärt was die Parameter machen. Wenn man ein wenig damit probiert hat man vom Programmabsturz bis zum dem beschriebenen alles dabei.

    @estartu: Sorry, war immer der Meinung callstack und Ausgabefenster wären das gleiche. So, hab mir das mal angeschaut, kann aber nix damit anfangen. Wenn das Meldungsfenster erzeugt wird befindet er sich gerade in der wincore.cpp, Zeile 249. Dort hin kommt er, weil in der dbcore.cpp eine Routine CRecordset::AllocHstmt() abegearbeitet wird, die nach der Zeile 2341 die Funktion Open aufruft. Leider hab ich von dem ganzen überhaupt keine Ahnung.
    Wie es weiterhin aussieht scheint die Funktion CRecordView::OnInitialUpdate() in Zeile 63 die Openfunktion auszulösen.
    Die Zeilenangaben sind sicher nur für meine Version (VS 2003.net) gültig.



  • Schau mal ins Artikelforum, da gibt es von mir einen Artikel zum Debuggen.
    Vielleicht findest du da ja was.

    Wenn du mit dem Callstack arbeitest ist das sinnvollste, dort erstmal eine Zeile zu suchen, die aussieht als wäre sie von dir und diese doppelt zu klicken. 🙂
    Von dort aus kann man sich dann langsam wieder tiefer in die MFC vorarbeiten.

    Das ist aber alles nur Stochern im Nebel, ne konkrete Idee habe ich leider nicht. 😞



  • naja, woher der open-Aufruf kommt ist jetzt sicher klar. Wenn man ein SDI-Projekt mit Datenbankunterstützung anlegt, so nimmt der Assistent immer die View-Klasse CRecordView. Die will ja nach Erstellen des Hauptfensters den ersten Datensatz anzeigen und muss logischerweise die DB öffnen um den ersten Datensatz zu lesen. Ich hab jetzt mal probiert einen weiteren Openbefehl als Reaktion auf ein Buttonereignis zu auszuführen, da gibts das gleiche Bild. Wird wohl doch was dran sein, dass der Connectionstring nicht stimmt.
    Aber sind noch folgende Dinge total unklar: warum kann man beim Anlegen eines neuen SDI-Projektes mit DB-Unterstützung bei der Auswahl der ODBC-Quelle die MySQL-Datenbank im Treiber nicht auswählen (Meldungsfenster: Loading database list not implemented for SQLDriverConnect())? Teilweise stürzt sogar die IDE ab? Im ODBC-Admin hab ich aber einen connection::success und sehe auch die tables.
    Nimmt man dann bei der Auswahl im Assistenten statt ODBC OLE DB und dann noch einen "Microsoft OLE DB Provider for ODBC Drivers" dann kommt auch das Fenster, wo man die Tabellen als Datengrundlage auswählen kann. Aber warum ist das so?



  • Kann das eventuell auch am Microsoft Visual Studio 2003.net liegen? Ich habe eben das alles mit meiner alten VS 6.0 Autorenedition probiert und da läuft das ganze ohne Probleme. Ist da irgendwem was bekannt?


Anmelden zum Antworten