GetTableNames() für SQL



  • Hallo zusammen,

    ich connecte eine MySQL Datenbank. Die ist vorhanden und 13 Tabellen.
    Mit phpMyAdmin auch alles ok. Der Connect und Disconnect mittels
    TSLQConnection klappt auch einwandfrei.

    Sobald ich aber mittles GetTableNames() die Tabellennamen auslesen
    will, erhalte ich eine EAccessViolation (Zeile 24 im Quellcode).
    Jetzt aber der Clou: Kopiere ich diesen Quellcode und die Komponente
    TSQLConnection in ein vorhandenes Projekt und rufe es dort auf, klappt
    es fehlerfrei!? 😕

    try {																			// Fehlerroutine Start
     AnsiString z1; Boolean bo1,bOk;   												// Vars definieren
     TSQLConnection *DB;															// vorbereiten
    
     DB=Form2->frm1_sqlDatenbank;													// zuweisen
    
     bo1=DB->ConnectionState; bOk=false; z1="DB Disconnect"; 						// Ist Anbindung aktiv?
     if(bo1==false) {																// Nein, daher öffnen
      DB->Params->Values["Hostname"]  =zDHost;										// Verweis auf \\htdocs\ Ordner  127.0.0.1
      DB->Params->Values["Database"]  =zDBase; 			     						// Verweis auf Datenbankname
      DB->Params->Values["Encrypted"] =BoolToStr(oDEnc);							// Passwort wird entschlüsselt übergeben
      DB->Params->Values["User_Name"] =zDBenu;										// dann Anmeldedaten
      DB->Params->Values["Password"]  =zDPass;										// vorgeben
      DB->LoginPrompt                 =oDLogin;										// Login anzeigen beim Verbinden
    
      DB->Open();  bOk=true;	z1="DB Connect"; 									// Datenbankanbindung öffnen
      //ShowMessage("Datenbank Connect gestartet.");                                  // Info geben
      frm2_lbl1_Info->Caption     ="Verbindung aktiv - "+ZeitStempel(12,"");        // Text anpassen
      frm2_lbl1_Info->Font->Color =clGreen;											// Textfarbe
      frm2_btn1_dbConnect->Caption="Datenbank  &trennen";							// Button anpassen
      frm2_btn2_dbConnect->Caption="Datenbank  &trennen";							// Button anpassen
      TextRTF(100,clGreen,8,"Arial",-1,frm2_rtf1_Status,"\tDatenbank verbunden => "+zDBase);	// Infozeile
    
      DB->GetTableNames(frm1_lbPseudo->Items,false);   							// und Tabellen auslesen
     }                                           									// ende if(bo1
    

    Daher meine Frage: Gibt es irgendwie zentral eine Möglichkeit, detaillierte
    Fehlermeldungen bei solchen Aktionen zu erhalten? Es tut mir leid, aber
    der Debugmodus und die Onlinehilfe des RAD Studio 2007 ist es für mich absolut
    nicht. Hat jemand eine Idee, warum diese Zeile einen Fehler auslöst, zumal
    es im anderen Quellcode funktioniert (dort kann ich es aber dummerweise nicht
    gebrauchen). Habe auch schon ein neues Projekt angefangen und die Zeilen und
    die Komponente aus dem funktionierenden Quellcode wieder zurückkopiert, eben-
    falls ohne Erfolg. Auch das Löschen der Komponente brachte keinen Erfolg. Aller-
    dings fiel mir beim Neuanlegen der Komponente TSQLConnection auf, daß RAD
    Studio bei den Parametern immer die alten Einstellungen bereits stehen hatte
    und merkwürdigerweise statt des Datenbanknamens den Name der ersten Tabelle
    stehen hatte? Ausserdem wollte er im Gegensatz zum anderen Objekt unbedingt
    den Pfad zu DBXDynalink.pas wissen.

    Wäre sehr dankbar für jeden Tipp. 😋

    Grüsse, Stefan



  • Hallo

    Benutzt erstmal den Debugger um die genaue Stelle der Exception einzugrenzen. Da es ein Speicherzugriffsfehler ist, ist es vermutlich kein direkter Datenbank-Fehler sondern du versuchst irgendwo auf eine ungültige Instanz zuzugreifen. Ich tippe mal darauf das Form2 oder Form2->frm1_sqlDatenbank zum Ausführungszeitpunkt nicht gültig ist.

    bis bald
    akari



  • Hallo Akari

    danke für die Antwort.

    Form2 ist das einzige Formular, was ich habe und sichtbar vor mir
    (also aktiv).

    Die Komponente Form2->frm1_sglDatenbank (= TSQLConnection Komponente)
    ist auch aktiv, denn die Verbindung aufbauen/abbauen funktioniert fehlerfrei.
    Und genau in dieser Routine (siehe meine Quellcode) mache ich ja dann die
    Abfrage der Tabellen. Die Anzeige im Debugger mit Hex-Werten sagt mir leider
    überhaupt nichts. Das ganze Projekt besteht auch nur eben zum Testen aus
    dem Form2 und ein paar Komponenten. Wenn Form2->frm1_sglDatenbank nicht aktiv
    wäre, dann dürfte ich doch die Übergabe an DB=Form2->frm1_sglDatenbank;
    nicht fehlerfrei erhalten, oder? 😕

    Gruss Stefan



  • Hallo

    Du sollst den Debugger dazu benutzen um festzustellen bei welcher Zeile die Exception kommt! Steht doch auch in dem verlinktem Tutorial beschrieben.

    bis bald
    akari



  • Was ist denn

    frm1_lbPseudo // Sichtbare Komponente, oder codebasiert erstellte geschichte?
    frm1_lbPseudo->Items // klappen Operationen hierauf?
    

    schonmal überprüft ob das nen AccessViolation gibt?

    mfg
    xXx



  • Hallo, xXx

    ja, ist eine sichtbare Komponente und kann beliebig befüllt werden.

    Im anderen Quellcode benutze ich übrigens diese Listbox für die
    Funktion

    GetTableNames(frm1_lbPseudo->Items,false);
    

    und erhalten auch brav alle Tabellennamen darin zurück. Habe es im neuen Quellcode auch
    mit StringListe probiert; ohne Erfolg.

    Ich habe etwas gelesen über mysql_error(). Gibt es darüber eine
    Möglichkeit den Fehler präziser zu erfassen und funktioniert das
    auch bei den Komponenten aus dem RAD Studio?

    Bin mit Datenbankprogrammierung leider absoluter Anfänger und
    daher meine Fragen 😉

    Danke und Grüsse, Stefan



  • Zu mysql_error:
    Mit hoher Wahrscheinlichkeit nein!
    Das klappt nur, wenn du die Mysql-API nutzt und ein Mysql-Connection-Handle hast. Das bekommst du von den Komponenten eher nicht. Zudem denke ich, das die ODBC o.Ä. nutzen und nicht die native API.

    Klappen denn andere Queries? Ich denke um ein genaues Verständnis / intensive Benutzung des Debuggers kommst du nicht herum...

    mfg
    xXx



  • Hallo Akari und xXx,

    mit Haltepunkt setzen und F10 vorwärts steppen habe ich ja
    schon gemacht. Deshalb weiss ich ja auch, daß er bei dem
    Befehl GetTablesNames() einen EAccessViolation Fehler bringt.

    Meint ihr dann mit dem Debuggen, daß ich es mit Einzelsteps
    machen soll (ist glaube ich F9 oder F11)?

    Gruss, Stefan



  • Hallo, so bekomme ich keine Fehlermeldung (also alle notwendigen Komponenten
    und Forms sind einwandfrei da und aktiv):

    try {																			// Fehlerroutine Start
     AnsiString z1; Boolean bo1,bOk;   												// Vars definieren
     TSQLConnection *DB;															// vorbereiten
    
     DB=Form2->frm1_sqlDatenbank;													// zuweisen
    
     bo1=DB->ConnectionState; bOk=false; z1="DB Disconnect"; 						// Ist Anbindung aktiv?
     if(bo1==false) {																// Nein, daher öffnen
      DB->Params->Values["Hostname"]  =zDHost;										// Verweis auf \\htdocs\ Ordner  127.0.0.1
      DB->Params->Values["Database"]  =zDBase; 			     						// Verweis auf Datenbankname
      DB->Params->Values["Encrypted"] =BoolToStr(oDEnc);							// Passwort wird entschlüsselt übergeben
      DB->Params->Values["User_Name"] =zDBenu;										// dann Anmeldedaten
      DB->Params->Values["Password"]  =zDPass;										// vorgeben
      DB->LoginPrompt                 =oDLogin;										// Login anzeigen beim Verbinden
    
      DB->Open();  bOk=true;	z1="DB Connect"; 									// Datenbankanbindung öffnen
      //ShowMessage("Datenbank Connect gestartet.");                                  // Info geben
      frm2_lbl1_Info->Caption     ="Verbindung aktiv - "+ZeitStempel(12,"");        // Text anpassen
      frm2_lbl1_Info->Font->Color =clGreen;											// Textfarbe
      frm2_btn1_dbConnect->Caption="Datenbank  &trennen";							// Button anpassen
      frm2_btn2_dbConnect->Caption="Datenbank  &trennen";							// Button anpassen
      TextRTF(100,clGreen,8,"Arial",-1,frm2_rtf1_Status,"\tDatenbank verbunden => "+zDBase);	// Infozeile
    
      if(DB->ConnectionState==true) {
       ShowMessage(DB->Name+"\r\r"+IntToStr(frm1_lbPseudo->Items->Count));
       //DB->GetTableNames(frm1_lbPseudo->Items,false);   							// und Tabellen auslesen
      }
     }                                           									// ende if(bo1
    

    Wenn ich im Debugger mit F11 mich durchhangel, dann will er
    (sobald ich den GetTableNames() Befehl freigebe) komischerweise
    die Dateien DBXDynalink.pas und DBXDynalinkNative.pas

    Komisch für mich deshalb, weil ich bei dem anderen Quellcode
    diese nicht brauche. Habe die beiden Dateien vom RAD Studio
    Verzeichnis überall mit reingefügt und auch die Pfade zum includen
    angegeben. Der Debugger springt auch rein in die Routine:

    function TDBXDynalinkCommand.DerivedExecuteQuery: TDBXReader;

    und dort gleich auf den End-Befehl.

    Dann kommt der Dialog "Dem Projekt hinzufügen..." und er will diese PAS
    Datei haben (in der er schon munter herumspringt!!! 😡 ) und ich gebe
    wieder einmal den Pfad dazu an. Dann kommt die Meldung Quellcode geändert
    und er startet neu und das Spiel beginnt von vorne. Drücke ich aber nach
    dem Hinzufügen der PAS Datei im Debugmodus F5 für normal weiterlaufen,
    dann kommt sofort der Fehler (mit F10 kommt das CPU Fenster und mit F11
    bzw. Shift+F11 kommt wie oben erwähnt der Neustart wegen Quellcodeänderung.

    So macht es keinen Spass...

    Also wenn noch jemand einen Tipp hat, ich kapiere es einfach nicht.
    Für mich riecht das ganze immer mehr nach einem RAD Studio Bug. Er
    springt in eine Datei, die er anschliessend haben will.

    Gruss Stefan



  • Hallo, habe es jetzt mal so probiert:

    try {																			// Fehlerroutine Start
     AnsiString z1; Boolean bo1,bOk;   												// Vars definieren
     TSQLConnection *DB;															// vorbereiten
     TSQLQuery* Query;
    
     DB=new TSQLConnection(this);													// zuweisen
    
     bo1=DB->ConnectionState; bOk=false; z1="DB Disconnect"; 						// Ist Anbindung aktiv?
     if(bo1==false) {																// Nein, daher öffnen
      DB->DriverName                  ="MySQL";                                     //
      DB->ConnectionName              ="MySQLConnection";                           //
      DB->GetDriverFunc               ="getSQLDriverMYSQL";							//
      DB->LibraryName                 ="dbxmys30.dll";								//
      DB->VendorLib                   ="LIBMYSQL.dll";								//
      DB->Name                        ="frm1_sqlDatenbank_TEST";   					//
      DB->Params->Values["Hostname"]  =zDHost;										// Verweis auf \\htdocs\ Ordner  127.0.0.1
      DB->Params->Values["Database"]  =zDBase; 			     						// Verweis auf Datenbankname
      DB->Params->Values["Encrypted"] =BoolToStr(oDEnc);							// Passwort wird entschlüsselt übergeben
      DB->Params->Values["User_Name"] =zDBenu;										// dann Anmeldedaten
      DB->Params->Values["Password"]  =zDPass;										// vorgeben
      DB->LoginPrompt                 =oDLogin;										// Login anzeigen beim Verbinden
    
      DB->Open();  bOk=true;	z1="DB Connect"; 									// Datenbankanbindung öffnen
      //ShowMessage("Datenbank Connect gestartet.");                                  // Info geben
      frm2_lbl1_Info->Caption     ="Verbindung aktiv - "+ZeitStempel(12,"");        // Text anpassen
      frm2_lbl1_Info->Font->Color =clGreen;											// Textfarbe
      frm2_btn1_dbConnect->Caption="Datenbank  &trennen";							// Button anpassen
      frm2_btn2_dbConnect->Caption="Datenbank  &trennen";							// Button anpassen
      TextRTF(100,clGreen,8,"Arial",-1,frm2_rtf1_Status,"\tDatenbank verbunden => "+zDBase);	// Infozeile
    
      ShowMessage(DB->Name+"\r\r"+IntToStr(frm1_lbPseudo->Items->Count));
      //DB->GetTableNames(frm1_lbPseudo->Items,false);   							// und Tabellen auslesen
      //SELECT Beispiel FROM Tabelle LIKE '%Suchbegriff%'; //enthält "Suchbegriff" irgendwo im Ergebnis
      Query= new TSQLQuery(this);
      Query->SQLConnection = DB;
      Query->SQL->Clear();
      Query->SQL->Add("SELECT * FROM `adressen` LIMIT 0,30");
      Query->Open();
      Form2->Caption = Query->Fields->Fields[1]->AsString;
      delete Query;
     }                                           									// ende if(bo1
    

    Effekt: Jetzt tritt der Fehler auf bei dem Befehl: Query->Open() (Zeile 38)
    mit genau dem gleichen Effekt wie im letzten Beitrag beschrieben.

    Hat denn niemand eine Idee? So kann ich ja garnicht mehr programmieren....

    Gruss, Stefan



  • Ich habe nun ein neues Projekt angelegt und in das
    leere Form aus dem Fehlerprojekt alle Komponenten rüberkopiert.
    Aus den CPP Dateien habe ich alle Funktionsaufrufe ebenfalls
    rüberkopiert und voila der Fehler ist weg. Sowohl GetTableNames()
    als auch TSQLQuery funktionieren sofort fehlerfrei.

    Und auch keine PAS Datei wird mehr verlangt. Danke an CodeGear! 😡

    Echten Danke aber an jeden hier für seine Unterstützung.

    Gruss, Stefan



  • Hallo,

    hatte diese Fehlermeldungen auf unterschiedlichen Rechnern (das neuanlegen
    des Projektes hatte nur bei einem Rechner funktioniert).

    Alle im Freundeskreis auch ratlos, Fehlerbilder total unterschiedlich.
    Bei einem Rechner ging z.B. SELECT * FROM adressen nicht, aber
    SELECT name FROM adressen funktionierte. Bei anderen Rechnern ging z.B.
    der Befehl Query->RecordCount(); nicht, aber der Befehl Query->FieldCount();
    usw.

    Auch Neuinstallieren von Xampp bzw. MySQL und RAD Studio 2007 brachten keine
    Abhilfe. Dann das Problem gefunden: Es gibt unterschiedliche DLL Dateien von
    diesen Dateien: libmysql.dll und dbxmys30.dll

    So funktioniert es NICHT:

    TSQLConnection->LibraryName                 ="dbxmys30.dll";   	//
      TSQLConnection->VendorLib                   ="LIBMYSQL.dll";  	//
    

    So funktioniert es auf allen Rechnern fehlfrei:

    TSQLConnection->LibraryName                 =Form1->PfadProg+"dbxmys30.dll";   	//
      TSQLConnection->VendorLib                   =Form1->PfadProg+"LIBMYSQL.dll";  	//
    

    Form1->PfadProg ist der aktuelle Programmpfad; hier müssen
    die beiden DLL Dateien vom RAD Studio Bin-Verzeichnis liegen!
    Nicht die von MySQL, Windows oder sonst wo her.

    Hoffe es hilft noch anderen, die vielleicht auch über merkwürdige
    Fehler grübeln (ja, man kann die DLLs auch in die Exe implementieren).

    😃

    Grüsse, Stefan


Log in to reply