Ungültiger Feldtyp



  • Hallo zusammen!

    Erst einmal was kurzes zum Backround.
    Habe mir eine Form gebastelt mit TSQLConnection, TSQLQuery, TEdit und TBitBtn.
    Bei Klick auf BitBtn1 wird der Text aus Edit1 in Variable asMysearchword gespeichert. Dann soll eine Datenbankverbindung aufgebaut werden und eine Abfrage auf den Server durchgeführt werden. Das Resultat soll mir in eine MessageForm angezeigt werden.

    Hier mein Code dazu:

    int iMyresult;
    
    if (Form1->SQLConnection1->Connected == false) {
    
    SQLQuery1->SQL->Add("use myDB;");
    SQLQuery1->ExecSQL();
    SQLQuery1->SQL->Clear();
    SQLQuery1->SQL->Add("SELECT count(myFeld) FROM MyTabelle where myFeld =" +asMysearchword);
    Form1->SQLConnection1->Connected=true;
    SQLQuery1->Open();
    iMyresult = SQLQuery1->FieldByName("myFeld")->AsInteger ;
    
    if(iMyresult > 0){ ShowMessage(iMyresult); }
    else { ShowMessage("Nix gefunden"); }
    
    SQLQuery1->SQL->Clear();
    Form1->SQLConnection1->Close();
    }
    

    Blöderweise erhalte ich den Fehler: Ungültiger Feldtyp
    Und ich weis noch nicht einmal wo ich jetzt ansetzen könnte. 😕

    Klar: Die Suchfunktion. Habe ich. Aber irgend etwas stimmt da nicht. Egal was ich in den Suchfeldern und Filter(oder ohne Filter) eingebe... ich bekomme immer -> "Keine Beiträge entsprechen Ihren Kriterien." -> Na sowas. Da habe ich doch nur nach dem Wort "Datenbank" gesucht. Und da gibt es keine Ergebnise??? Sehr unwahrscheinlich. Wie auch immer. Das ist ein anderes Thema.

    Ich hoffe es kann mir jemand bei dem Feldtyp auf die Sprünge helfen.
    Das abgefragte Feld in der Tabelle ist varchar(45)

    IDE: TurboExplorer C++ 2006
    OS: Windows 7

    Gruß
    Cookie_woman



  • Da stellt sich erst mal die Frage, welcher Vorgang den Fehler auslöst.
    Ich verwende zwar nicht TSQLConnection und TSQLQuery sondern andere Komponenten, aber auf den ersten Blick sehe ich zwei problematische Stellen:

    1. Bei String-Feldern muss der Suchwert zwischen Hochkommas gesetzt werden.

    SQLQuery1->SQL->Add("SELECT count(myFeld) FROM MyTabelle where myFeld =" +asMysearchword);
    
    //falsch: 
    SQLQuery1->SQL->Add("SELECT count(myFeld) FROM MyTabelle where myFeld = teststring");   
    
    //richtig: 
    SQLQuery1->SQL->Add("SELECT count(myFeld) FROM MyTabelle where myFeld = 'teststring'");
    

    2. Bei "AsInteger" muss der Datentyp exakt stimmen, sonst gibt es eine Exception. Außerdem wird hier nicht "count(myFeld)" ausgelesen, sondern direkt "myFeld".

    iMyresult = SQLQuery1->FieldByName("myFeld")->AsInteger;
    
    //das sollte auf jeden Fall funktionieren:
    SQLQuery1->SQL->Add("SELECT count(myFeld) as Anzahl FROM MyTabelle where myFeld = '" +asMysearchword +"'");
    ...
    iMyresult = SQLQuery1->FieldByName("Anzahl")->AsString.ToIntDef(0);
    


  • Hallo j.halder,

    //falsch: 
    SQLQuery1->SQL->Add("SELECT count(myFeld) FROM MyTabelle where myFeld = teststring");   
    
    //richtig: 
    SQLQuery1->SQL->Add("SELECT count(myFeld) FROM MyTabelle where myFeld = 'teststring'");
    

    Zunächst vielen Dank für deine Info.

    Sehr interessant. Im SQL Editor werden beide Abfragen als richtig erkannt. Ok. Kann am Editor liegen.

    Ich habe dann mal deinen Vorschlag genommen und da ist wohl immer noch was nicht richtig. Es kommt die Fehlermeldung: Ungültige Feldgröße.

    Ok habe ich mir gesagt, dann machst du aus Spalte myFeld ein int(11) mit Eintrag 25.
    Meine Abfrage sieht momentan so aus:

    SQLQuery1->SQL->Add("SELECT count(*) as Anzahl FROM myFeld where myFeld =25"); // 25 nicht in '' weil myFeld int ist. Selbst mit '' kommt o.g. Fehler
    
    iMyresult = SQLQuery1->FieldByName("Anzahl")->AsInteger;
    
    if(iMyresult > 0){ ShowMessage(iMyresult); }
    else { ShowMessage("Nix gefunden"); }
    

    Könnte das an die verwendete libmysql.dll und dem mysql DB Server liegen? Meine verwendete MySQL DBServer ist 5.6.

    Gruß
    Cookie_woman



  • Hallo cookie_woman,

    sieht alles korrekt aus.
    Ob es an den verwendeten DLLs liegt, kann ich nicht beurteilen, da ich andere SQL-Komponenten verwende. Aber letztendlich kommt es ja auf den Server an und wie dieser den SQL-String umsetzt.

    Liegt es denn definitiv an der WHERE-Klausel?
    Hast du es schon einmal ohne WHERE versucht?
    Was genau für ein Datentyp ist myFeld (int8, int32, int64)?
    int(11) sagt mir nichts, hat aber laut Google etwas mit der Anzeigenbreite zu tun.
    Wenn du MySQL verwendest, solltest du dort mal nach der genauen Syntax für die verschiedenen Datentypen schauen.



  • Hallöchen j.halder,

    vielen Dank für deine Antwort.

    Liegt es denn definitiv an der WHERE-Klausel? 
    Hast du es schon einmal ohne WHERE versucht?
    

    Wieso bin ich eigentlich nicht selbst darauf gekommen? Wegen's dem Ausschlussverfahren. Werde ich mal prüfen und berichten.

    Was genau für ein Datentyp ist myFeld (int8, int32, int64)? 
    int(11) sagt mir nichts, hat aber laut Google etwas mit der Anzeigenbreite zu tun.
    

    Also deine Angabe zu den Zeichenlängen habe ich noch nie so gesehen. Obwohl ich glaube zu wissen, worauf du abziehlst. Die MySQL Version ist eine 32bit Version und kann auch auf einen 64bit Rechner installiert werden.

    int(11) ist die Zeichenlänge. Hier also fest auf 11 int Zeichen.

    Wenn du MySQL verwendest, solltest du dort mal nach der genauen Syntax für die verschiedenen Datentypen schauen.
    

    Also die Syntax ist richtig. Die habe ich bereits x-Mal bei php angewendet.

    Ich werde auf jeden Fall das mit der where-Klausel, den Datentyp auf 2 Zeichen begrenzen und ggf. eine andere/ ältere mysql Version prüfen.

    Ich melde mich dann wieder.

    Gruß
    Cookie_woman



  • Hallöchen die Mitleser,

    also ich habe unterschiedliche MySQL Versionen aus den letzten Jahren verwendet. Aktuell habe ich 5.0.27 aus dem Jahr 2006 installiert.

    Die where-Klausel habe ich entsprechend angepasst. Praktisch ohne Filter und das Feld auf 2 Zeichen begrenzt.

    Das Problem hat sich nicht gelöst. Der Compiler bringt immer eine Exception: Ungültige Feldgröße.

    Über Google konnte ich das ->http://www.c-plusplus.net/forum/140471-full finden. Allerdings hat mich das auch nicht weiter gebracht. Selbst wenn nur eine Spalte mit varchar(2) (NOT NULL) vorhanden ist, kommt o.g. Fehler.

    So langsam verzweifle ich mal wieder. 😕

    Gruß
    Cookie_woman



  • Hallo,
    also irgendwie habe ich hier etwas den Überblick verloren bzw werde nicht wirklich schlau daraus.
    In welcher Codezeile tritt den nun genau die Exception auf?

    Beim Add der SQL Anweisung sollte doch keine Exception auftreten, denn hier wird wenn ich mich recht erinnere noch nicht wirklich etwas gemacht.

    Anschließend muß die Anweisung ja ausgeführt werden, hier kann ein Fehler auftreten wenn die SQL Syntax nicht stimmt, allerdings habe ich hier immer Fehler direkt von MySql Server erhalten.

    Oder tritt der Fehler beim auslesen bzw konvertieren der Daten auf.
    Ich würde im ersten schritt das count() aus der SQL mal entfernen, und eine einfach Abfrage ausführen.

    Hast Du andere funktionierende Abfragen in deinem C++ Programm?

    MfG Stephan



  • Moin zusammen

    @_Stephan_;

    Also bei Button Click sieht es so aus:

    void __fastcall TForm3::BitBtn1Click(TObject *Sender)
    {
    asMyappname 	= Application->ExeName+".ini";
    asHostName	= "localhost";
    asMyUser		= "fkt_localhost";
    asMyPassword	= "mypasswd";
    iMyBlobSize	= -1;
    asMyErrorResourceFile = "";
    iMyLocaleCode	= 0000;
    asMyCompressed	= "false";
    asMyEncrypted	= "false";
    iMyPort		= 3306;
    asMydatabase	= "mydatabase";
    
    	//asMysearchword = QuotedStr(Edit1->Text);
    	asMysearchword = Edit1->Text;
    
    	Form1->SQLConnection1->Params->Values["HostName"]=asHostName;
    	Form1->SQLConnection1->Params->Values["Database"]=asMydatabase;
    	Form1->SQLConnection1->Params->Values["User_Name"]=asMyUser;
    	Form1->SQLConnection1->Params->Values["Password"]=asMyPassword;
    	Form1->SQLConnection1->Params->Values["BlobSize"]=WideString(iMyBlobSize) ;
    	Form1->SQLConnection1->Params->Values["ErrorResourceFpressed"]=asMyCompressed;
    	Form1->SQLConnection1->Params->Values["Encrypted"]=asMyEncrypted;
    	Form1->SQLConnection1->Params->Values["Port"]=WideString(iMyPort);
    
    AnsiString asMyresult;
    
    	if (Form1->SQLConnection1->Connected == false) {
    
    	 SQLQuery1->SQL->Add("use mydatabase;");
    	 SQLQuery1->ExecSQL();
    	 SQLQuery1->SQL->Clear();
    	 SQLQuery1->SQL->Add("SELECT id as Anzahl FROM myTable");
    	 Form1->SQLConnection1->Connected=true;
    	 SQLQuery1->Open();
    	 asMyresult = SQLQuery1->FieldByName("Anzahl")->AsString; 
    
    	 if(asMyresult > 0){ ShowMessage(asMyresult); }
    	 else { ShowMessage("Sowas blödes auch. Nix gefunden"); }
    
    	SQLQuery1->Close();
    	SQLQuery1->SQL->Clear();
        Form1->SQLConnection1->Close();
     	}
    	else{
    	Application->MessageBoxA("SQL-Server Verbindung besteht nicht","Warnung!",MB_OK|MB_ICONSTOP);
    	}
    }
    

    Es kommt dann eine Exception mit dieser Info: Erste Gelegenheit für Exception bei $76A8C41F. Exception-Klasse EDatabaseError mit Meldung 'Ungültige Feldgröße'. Prozess meineanwendung.exe (4120)

    Eine funktionierende Abfrage auf Datenbank->Tabelle->Spalte->Wert habe ich bisher über den Turbo C++ nicht hinbekommen.

    Was scheinbar funktioniert ist bisher nur das:

    void __fastcall TForm1::FormShow(TObject *Sender)
    {
    	SQLConnection1->Params->Values["HostName"]="localhost";
    	SQLConnection1->Params->Values["Database"]="mydatabase";
    	SQLConnection1->Params->Values["User_Name"]="fkt_localhost";
    	SQLConnection1->Params->Values["Password"]="mypasswd";
    	SQLConnection1->Params->Values["BlobSize"]="-1";
    	SQLConnection1->Params->Values["ErrorResourceFile"]="";
    	SQLConnection1->Params->Values["LocaleCode"]="0000";
    	SQLConnection1->Params->Values["Compressed"]="False";
    	SQLConnection1->Params->Values["Encrypted"]="False";
    
    	SQLConnection1->Connected=true;
    	if (SQLConnection1->Connected) {
    
    	StatusBar1->SimpleText="SQL-Server Verbindung OK";
    	SQLConnection1->Close();
    	}
    	else{
    	StatusBar1->SimpleText="SQL-Server Verbindung fehlerhaft";
    	}
    }
    

    Tja... und in der Statusbar steht SQL-Server Verbindung OK.
    Also muss ich davon ausgehen, dass die Verbindung ok ist.

    Gruß
    cookie_woman



  • Also, wenn Du nicht genau weißt in welcher Zeile die Exception auftritt, dann verwende bitte den Debugger.
    Das mit den SQL Connection Parametern kenne ich so nicht.

    Ich hatte früher die ADO Komponente in Zusammenhang mit ODBC und einem Connection String verwendet.
    Mittlerweile verwende ich nur noch die MySQL C-API in einer eigenen Klasse.
    Greifst Du mit der Komponente direkt auf MySQL zu oder gehst Du über eine ODBC Verbindung?

    Zeile 38 könnte meiner Meinung nach einen Fehler bringen, denn id bzw Anzahl ist vermutlich ein Integer und dieser kann eventuell nicht als String dargestellt werden.
    Allerdings sollte hier eine sprechendere Fehlermeldung kommen.

    SQLQuery1->SQL->Add("SELECT id as Anzahl FROM myTable");
         Form1->SQLConnection1->Connected=true;
         SQLQuery1->Open();
         asMyresult = SQLQuery1->FieldByName("Anzahl")->AsString; // Zeile 38
    


  • Hallo _Stephan_,

    das ist es ja, ich lasse die exe Datei immer mit Debugger kompilieren. Bei den Ausgaben vom Debugger steht in jeder Zeile Modul laden: blabla.dll. Ohne Debug-Infos. Basisadresse: ...
    Nur bei Klick auf den Button in meiner Form... dann dauert es ein paar Millisekunden und die Exception wird ausgelöst und der Debugger bringt das was ich schon geschrieben hatte. (Erste Gelegenheit für Exception bei $76A8C41F. Exception-Klasse EDatabaseError mit Meldung 'Ungültige Feldgröße'. Prozess meineanwendung.exe (4120))
    Wenn ich dann auf "Pause Button" vom Turbo C++ gehe, dann habe ich die Info im Fenster "Aufruf-Stack-Thread 376":

    :7699f5be USER32.WaitMessage + 0x15
    :52079340 vcl100.@Forms@TApplication@HandleMessage$qqrv + 0x1c
    :00401B4F WinMain( =:00400000,  =NULL,  =:00523AF0,  =9)
    :00419a43 ; __Startup
    

    Im Kartenreiter der Anwendung habe ich dann die CPU Ausgabe und damit kann ich leider nix anfangen.

    Mit ODBC habe ich es erst gar nicht versucht, weil dann eine weitere Fehlerquelle hinzukommt. Und das will ich vermeiden. Ergo... Ich gehe "direkt" auf MySQL.

    Ja, man könnte vermuten, dass das Feld id ein int ist. Ist aber ein VarChar. 🙂

    Um hier die ganze Geschichte etwas abzukürzen... Du schreibst, du nimmst die MySQL C-API in einer eigenen Klasse. Da werde ich mich mal schlau darüber machen.

    Wenn dennoch jemand was für mich hat an Infos... Habe dafür immer ein offenes Ohr. 🙂

    Gruß
    Cookie_woman



  • Geh´ deinen Code doch bitte Schritt für Schritt mit dem Debugger durch. Damit solltest du relativ einfach herausfinden können, in welcher Zeile der Fehler auftritt. Mit F5 kannst du einen Breakpoint auf eine Zeile setzen und zur Laufzeit hält der Debugger dort an. Anschließend kannst du mit F8 jede Zeile einzeln ausführen lassen bis zu der Stelle, wo dir dein Code um die Ohren fliegt. Dann weißt du ziemlich genau, an welcher Stelle es knallt und kannst dir über den Code Gedanken machen.


Anmelden zum Antworten