SQL befehl übergeben
-
Hallo,
ich versuche über die Funktion Open(), von CRecordSet, einen SQL Befehl zu übergeben, ich habe es so wie es in der MSDN steht versucht.
CRecordTest rt; // von CRecordset abgeleitet rt.Open( CRecordset::dynaset,_T("SELECT Name FROM Adresse Recordset::readOnly); if((rt.ISBOF()) rt.MoveFirst(); rt.Close();
Ich bekomme zur Laufzeit bei der Open()-Funktion eine Fehlermeldung
dass er den Datensatz nicht öffnen kann " Fehler beim öffnnen ... usw."Übergebe ich an Open() nur den Tabellennamen, so funktioniert es einbahnfrei.
Was mache ich Falsch?
Muss ich noch etwas in meiner von CRecordSet abgeleiteten Klasse ändern/überschreiben?
Für eure Hilfe bedanke ich mich schon im Voraus
!
-
rt.Open( CRecordset::dynaset,_T("SELECT Name FROM Adresse Recordset::readOnly);
Da sind zwei öffnende Klammern, aber nur eine schliessende. Ausserdem sind nur einmal Anführungszeichen vorhanden. Und vor Recordset::readOnly fehlt bestimmt ein Komma.
Noch was:
wenn Open() funktioniert, ist das Recordset automatisch auf dem ersten Datensatz (wenn welche vorhanden sind). Eine Abprüfung auf IsBOF() ist sinnlos und das MoveFirst() ebenfalls, weil er MoveFirst() nur ausführen wird, wenn er sowieso schon auf dem ersten Datensatz ist.Noch noch einer:
IsBOF() schreibt sich mit kleinem s. Dein Code lässt sich mit Sicherheit nicht übersetzen. Und eine Fehlersuche in Code mit lauter Kopier- und Schreibfehlern finde ich persönlich als... öhm... Mist. Wollte ich nur mal bemerken, weil das andauernd vorkommt...
-
Hallo isabeau,
Sorry wegen den Schreibfehlern.
die Fehler sind durch das Kopieren/Einfügen entstanden, ich bin hier auf der Arbeit. Der Code bei mir zuhause, ist ohne die Schreibfehler und lässt sich schon übersetzen.
Mit MoveFirst() ist eigentlich nur als Beispiel gedacht. Um die Funktion geht es ja garnicht. Mir geht es um die open()-Funktion weil da bekomme ich die Fehlermeldung.Hier nochmal:
CRecordTest rt; // von CRecordset abgeleitet rt.Open( CRecordset::dynaset,_T("SELECT Name FROM Adresse"),CRecordset::readOnly); if((rt.IsBOF()) rt.MoveFirst(); rt.Close();
Hier nochmal die verbesserte Version, die Frage bleibt aber weiterhin bestehen!
-
Stellt sich eine Verbesserung ein, wenn du CRecordset::dynaset in CRecordset::snapshot änderst ? <- Schuss ins Blaue
Spricht eigentlich was dagegen, das SQL-Statement wegzulassen (wenn es dann funktioniert) ?
-
Hallo,
Stellt sich eine Verbesserung ein, wenn du CRecordset::dynaset in CRecordset::snapshot änderst ? <- Schuss ins Blaue
Nee leider nicht.
Spricht eigentlich was dagegen, das SQL-Statement wegzulassen (wenn es dann funktioniert) ?
Ja eigentlich schon, ich kann ja durch SQL-Statement auch eine WHERE anweisung übergeben, und bei großen Datenmengen denke ich ist es schon vorteilhafter.
Gruß
bbatec
-
Achso. Wenn es nur um die WHERE-Klausel geht, die kannst du auch in m_strFilter rein packen:
rt.m_strFilter = "NAME = '" + strName + "'"; // Bei Zahlen ohne '
Die Zeile wirkt wie WHERE NAME = '...' in einem SQL-Statement. Obwohl damit dein eigentliches Problem immer noch nicht wirklich gelöst ist. Weiss ich jetzt aber auch nicht weiter...
[edit] m_strFilter muss vor Open() bzw. vor Requery() gesetzt werden. [/edit]
-
müssen die spaltenname nicht in [], also [Spaltenname]?
-
hallo isabeau,
Die Zeile wirkt wie WHERE NAME = '...' in einem SQL-Statement. Obwohl damit dein eigentliches Problem immer noch nicht wirklich gelöst ist.
stimmt das Problem ist noch nicht gelöst.
hallo daniel12345
müssen die spaltenname nicht in [], also [Spaltenname]?
laut msdn nicht, ich kanns aber heute nachmittag versuchen.
-
Hallo ich bins nochmal,
leider funktioniert es auch mit [] nicht.
Wenn ich statt Kontaktperson einen * einfüge (für alles) dann bekomme ich keine Fehlermeldung. Sobald ich einen Namen von einer Spalte eingebe bekomme ich die Fehlermeldung zur Laufzeit des Programms "Fehler beim abrufen eines Datensatzes!" Der Fehler kommt von der Open()-Funktion.
Hier nochmal mein Code.void CMaterialAnlegenView::OnBnClickedSucheLieferant() { CTabLieferanten mTabLief; mTabLief.Open( CRecordset::snapshot,"SELECT Kontaktperson FROM Lieferanten",CRecordset::readOnly ); mTabLief.MoveFirst(); CString strTest=(CString)mTabLief.m_Kontaktperson; mTabLief.Close(); }
Muss ich vielleicht etwas in der von CRecordSet abgeleiteten Klasse verändern?
Ich bin langsam am verzweifeln, weil laut der MSDN und paar anderen Nachforschungen sollte es so eigentlich mit dem SQL-Statement funktionieren.Gruß
bbatec
-
Hallo ich bins nochmal
Lässt sich das ohne Fehler öffnen ?mTabLief.Open(CRecordset::snapshot, "SELECT Kontaktperson AS KONTAKT FROM Lieferanten", CRecordset::readOnly);
Oder vielleicht das:
mTabLief.Open(CRecordset::forwardOnly, "SELECT Kontaktperson AS KONTAKT FROM Lieferanten", CRecordset::readOnly);
-
Hallo isabeau,
werde ich heute nachmittag mal probieren, bin gerade auf der Arbeit.
Eine Frage was ist
".... KONTAKT ...."
?
Gruß
bbatec
-
Ich vermute einfach mal, dass das nicht klappt, weil ein ganz bestimmtes Feld angefordert wird. Irgendwo hiess es mal, dass das Ergebnis von so einem SELECT in die erste Spalte der Tabelle geschrieben wird. Vielleicht passen die Datentypen nicht zusammen ?
Naja, egal. Ich hatte jetzt diese Idee:
mit dem "AS KONTAKT" in dem Select-Statement wird praktisch ein neues Feld "KONTAKT" erstellt (kann auch anders benannt werden), in dem das Ergebnis von dem Select eingetragen wird. Also anstatt zu sagen "gib mir alles aus dem Feld Kontaktperson" und das dann auszulesen sagst du jetzt "gib mir alles aus dem Feld Kontaktperson in dem neuen Feld KONTAKT" und dann liest du das aus.
Und an die Daten kommt man dann so (wenn es funktioniert):CRecordset rs; // bzw. dein CRecordTest rt; CString strAbfrage; CString strErgebnis; strAbfrage.Format("SELECT Kontaktperson AS KONTAKT FROM Lieferanten"); rs.Open(CRecordset::forwardOnly, strAbfrage, CRecordset::readOnly); while(!rs.IsEOF()) { rs.GetFieldValue("KONTAKT", strErgebnis); AfxMessageBox(strErgebnis); // nur zur Kontrolle rs.MoveNext(); } rs.Close();
-
Hallo isabeau,
funktioniert leider nicht, bekomme jetzt folgende Fehlermeldung
"Ungültiger Zeichenwert für Konvertierungsangabe. bei Spalte 1 (KONTAKT)"
-
Hallo ich bins nochmal
wenn ich nach der 1. Spalte Slectiere also
mTabLief.Open( CRecordset::snapshot,"SELECT LieferantenNr FROM Lieferanten",CRecordset::readOnly );
LieferantenNr steht in der 1. Spalte dann funktioniert es, muss ich dem SQL-Befehl mitgeben in welcher Spalte er selektieren muss?
Gruß
BBATEC
-
Hallo hat einer eine Idee?
-
könnte vielleicht helfen:
bei klappts immer und ich definiere mit nen makro, und das sieht so aus:#define SQL_UPDATELIST(DB, TAB) (CString) "SELECT * FROM " + DB + "." + TAB + ";"
ich habe vorsichtshalber immer den datenbanknamen angegeben und ein semikolon am ende der anweisung. das semikolon kann man weglassen, habe ich mal gehört.
versuchs mal
-
Hallo Red Skall,
kannst du mir mal bitte ein bischen dein Code erklären,
irgendwie weiß ich es nicht wie ich das bei meinem Problem anwenden kann/soll.Danke dir!
-
wenn du diese zeile in dein prggramm schreibst (ausserhalb einer funktion am besten) dann kannst du dieses makro "benutzen".
das machst du so:
mTabLief.Open( CRecordset::snapshot,"SQL_UPDATELIST("Datenbankname", "Tabellenname"), CRecordset::readOnly );
die funktion der #define - anweisung erklärt sich von selbst:
er setzt die in den klammern stehenden begriffe in die anweisung (rechts) ein.das erspart dir schreibarbeit wenn du den befehl mehrfach verwndest und macht es übersichtlich