OK jetzt mal ganz kurz und knackig mein Problem mit ODBC



  • Der Feher kommt von der Datenbank, irgendwie baust du den "Insert-Befehl" falsch zusammen.

    Lass dir mal strErgebnis ausgeben bevor du es an die Datenbank schickst

    hierman kannst du dann das Ergebnis direkt ausm Debugger kopieren:

    TRACE(strErgebnis);
    

    Wenn du WindowsXP hast kannst du auch einfach ne MessageBox nehmen, wenn der Fehler da ist STRG+C drücken und schon hat man den Text der MsgBox im Speicher und kann ihn irgendwo einfügen 😉

    Es msste bei dir in etwa so aussehen (denke ich):

    SqlString.Format( "'%s','%s','%s','%s','%s'", NewSong.Shelf.c_str(),NewSong.Interpreter.c_str(),NewSong.Title.c_str(),NewSong.Rubric.c_str(),NewSong.CD.c_str());
            strErgebnis = "Insert into tbl_Datenbank(spalte1, spalte2, spalte3, spalte4, spalte5) values ";
    

    und die Worte "spalte1" bis "spalte5" ersetzt du durch deine Spaltennamen! Damit sollte es dann klappen..

    Wenn nicht, schick mal den SQL, also genau das was du an die Datenbank schickst (direkt vor dem ExecuteSQL).



  • oder probier mal, den tabellennamen in eckige klammern zu setzen. ansonsten lassen sich solche sql-befehle auch ganz gut in access testen, da wird nämlich angezeigt, wo genau der fehler ist



  • ja genau, einfach ne Abfrage erstellen und dann in die SQL-Ansicht gehen, da kannste die SQLs testen..



  • Hallo also es klappt immer noch nicht:

    void MusicManagement ::StoreDB(MusicPiece NewSong)
    {
    	CDatabase music_data;
    	CString SqlString;
    	CString strErgebnis;
    
    		// Open the database
    		music_data.Open( "MUSIK" );
    
    		music_data.BeginTrans();
    		SqlString.Format( "%s,%s,%s,%s,%s", NewSong.Shelf.c_str(),NewSong.Interpreter.c_str(),NewSong.Title.c_str(),NewSong.Rubric.c_str(),NewSong.CD.c_str());
    		strErgebnis = "Insert into tbl_Datenbank(Regal,Interpret,Titel,Rubrik,CD) values ";
    		strErgebnis += (LPCTSTR)SqlString;
    		music_data.ExecuteSQL(strErgebnis); // SQL absenden
    		music_data.CommitTrans(); // daten festschreiben
    
      strErgebnis = "Insert into tbl_Datenbank(spalte1, spalte2, spalte3, spalte4, spalte5) values ";
    		music_data.Close();
    
    }
    

    Hier jetzt mal die komplette Methode das mit den Klammern um die tabelle hab ich auch probiert, klappt ebenfalls nicht.

    Was ich noch nicht so ganz verstanden habe ist der Tip mit der Abfrage erstellen, soll ich einfach ne Abfrage in Access machen? Und dann seh ich ob das funktioniert ???

    Wenn ich das Trace ausprobiere hat strErgebnis alle Werte übernommen drücke ich auf F10 geht der in einen anderen Bereich und zeigt hier einen Fehler und geht nicht weiter:

    [cpp]// special case for WM_INITDIALOG
    		CRect rectOld;
    		DWORD dwStyle = 0;
    		if (nMsg == WM_INITDIALOG)
    			_AfxPreInitDialog(pWnd, &rectOld, &dwStyle);
    
    		// delegate to object's WindowProc
    		lResult = pWnd->WindowProc(nMsg, wParam, lParam);
    
    		// more special case for WM_INITDIALOG
    		if (nMsg == WM_INITDIALOG)
    			_AfxPostInitDialog(pWnd, rectOld, dwStyle);
    	}
    	CATCH_ALL(e)
    	{
    		[b]lResult = AfxGetThread()->ProcessWndProcException(e, &pThreadState->m_lastSentMsg);[/b] //genau hier bleibt der Compiler hängen
    		TRACE1("Warning: Uncaught exception in WindowProc (returning %ld).\n",
    			lResult);
    		DELETE_EXCEPTION(e);
    	}
    	END_CATCH_ALL
    
    	pThreadState->m_lastSentMsg = oldState;
    	return lResult;
    }[/cpp]
    


  • Ja, das ist schon ganz gut soweit..

    Zum ersten: Ja, einfach irgeneine Abfrage in Access erstellen, und dann in die Entwurfsansicht, und dann auf SQL umstellen.
    Jetzt kannst du den kompletten Insert aus dem TRACE rauskopieren und in die Abfrage einfügen. Abfrage speichern, und per doppelklick ausführen.

    Jetzt sollte ein Fehler kommen der sagt wo der Fehler in dem SQL-Statement ist. Den brauchen wir 😉

    Den Fehler kann man natürlich auch vom Programm aus holen und dann anzeigen lassen, dazu benötigt man dann Exception-Handling (Try/Catch/CDBException).



  • Du hast einfach die Klammern um die Werte vergessen:

    SqlString.Format( "(%s,%s,%s,%s,%s)", NewSong.Shelf.c_str(),NewSong.Interpreter.c_str(),NewSong.Title.c_str(),NewSong.Rubric.c_str(),NewSong.CD.c_str());
    


  • und die einfachen Anführungszeichen:

    SqlString.Format( "('%s','%s','%s','%s','%s')", NewSong.Shelf.c_str(),NewSong.Interpreter.c_str(),NewSong.Title.c_str(),NewSong.Rubric.c_str(),NewSong.CD.c_str());
    

    weil es strings sind. ich glaube Access benötigt die auch..



  • Ok perfekt danke für eure Hilfe das funktioniert 👍 , aber wie Ihr schon rausgehört habt kommt der nächste Fehler sofort. Aber das hat was mit dem Access Tabellenfeld zu tun. Und zwar kommt die Fehlermeldung "Feld "tbl_Datenbank.Interpret" darf keine Zeichenfolge der länge NULL sein 😮 😕 Was das wohl beudeten mag. Man weiss es nicht man munkelt nur



  • Das heisst das für Interpret etwas angegeben werden muss.

    Null bedeutet NIX, also steht bei dir in NewSong.Interpret nix drin.

    Du hast nun zwei Möglichkeiten (irendwie mag ich den Spruch 😃 ):

    1. In Access der Spalte sagen das sie NULL werden darf.
    2. Dafür sorgend das immer nen Interpret angegeben ist.



  • Ja ich merke es das du diesen Spruch liebst 😃

    Ich denke mal das ich eher sagen werde das Null drin stehen darf , ich tippe mal das ich das bei allen machen muss.



  • Wenn ich aber in Access nach gucke , steht da das die Eingabe nicht erforderlich ist, dass heisst doch schon automatisch das da auch NULL drin stehen darf oder??



  • OK alles zurück 😃 Es FUNKTIONIERT 🕶 Hey man that's cool
    Ich hatte noch dein Beispiel von vorhin mit drin :

    SqlString.Format( "('%s','%s','%s','%s','%s')", NewSong.Shelf.c_str(),NewSong.Interpreter.c_str(),NewSong.Title.c_str(),NewSong.Rubric.c_str(),NewSong.CD.c_str());
    

    Ich hatte es mir in den Code kopiert um nicht hin und her schalten zu müssen und deswegen hatte ich als so ne blöde Fehlermeldung 🙄

    DANKE für eure Hilfe ohne euch hätte ich das nie geschafft

    Gruß SIlver



  • Der einzige Nachteil momentan funktioniert es nur wenn ich wirklich alle Felder ausfülle



  • In die Entwurfsansicht der Tabelle im Access gehen und dann "Eingabe erforderlich" bei der Spalte auf "nein" stellen - Problem behoben..



  • Silvercreast schrieb:

    Wenn ich aber in Access nach gucke , steht da das die Eingabe nicht erforderlich ist, dass heisst doch schon automatisch das da auch NULL drin stehen darf oder??

    Das meinte ich ja damit trotz das das da drin steht.



  • hmm, hatte ich überlesen.

    Das ist komisch, hast du die Spalte vielleicht als Primärschlüssel deklariert? Dann ist eine Eingabe nämlich auch erforderlich..

    Ansonsten fällt mir dazu jetzt nix mehr ein 🙄



  • Ich hab noch 3 Ideen:
    1. Versuch mal von Hand in Access "nix" einzugeben. Was passiert?
    2. Wie sieht der endgültig zusammengebaute String aus?
    3. Vielleicht draf man leere Felder beim Insert nicht erwähnen?



  • Ahh - daran liegt's..

    Du darfst nicht '' übergeben, das muss dann NULL heissen.

    mach einfach

    strErgebnis.Replace("''","NULL");
    

    direkt vorm ExecuteSQL, dann sollte es gehen..

    Access und Oracle wollen da ein NULL stehen haben
    MySQL isses egal..

    grad getestet 😉



  • Cool danke funktioniert 😃


Anmelden zum Antworten