[C++Builder] Hilfe zu ADO-Abfragen
-
Hallo
bei SELECT must du Open anstatt ExecSQL benutzen.
Das steht auch in der BCB-Hilfe zu beiden Methoden.bis bald
akari
-
Danke für die schnelle Antwort!
Ich hab das ganze auch mit Open probiert (hatte das auch in der HIlfe nachgelesen) doch es gibt trotzdem keine Ergebnismenge!
Wie kann ich mir das denn vorstellen, wo die Daten nach einem ausgeführten SQL Befehl stehen?!
Sind die in einer Variable gespeichert (welche?) und wie komm ich an die ran?Brauche ich um eine datenmenge speichern zu können auch eine DataSource - Koponente oder reicht wirklich nur die ADOQuery aus?
Nachdem ich adoquery->Open() ausgeführt habe, kommt folgender Hinweis (wenn ich mit der Maus über den Befehl gehe):
E2027 Eine Speicheradresse muss verwendet werden?
Hat das was damit zu tun warum es nicht geht?
-
Aus der Hilfe:
Datensensitive Steuerelemente werden über Datenquellen mit einer Datenbank verbunden. Eine Datenquellenkomponente (TDataSource) dient als Bindeglied zwischen dem Steuerelement und der Datenmenge, welche die Daten enthält. Jedem datensensitiven Steuerelement muß eine Datenquellenkomponente zugeordnet sein, damit es Daten anzeigen und bearbeiten kann. Umgekehrt muß auch allen Datenmengen eine Datenquellenkomponente zugeordnet sein, damit die in der Datenmenge enthaltenen Daten in datensensitiven Steuerelementen eines Formulars angezeigt und bearbeitet werden können.
Hinweis: Datenquellenkomponenten sind auch zum Verknüpfen nicht verschachtelter Datenmengen in Haupt-/Detail-Beziehungen erforderlich.
-
Dein Connection-String ist falsch.
adoquery->ConnectionString = "Provider="DB_PROVIDER";Password="DB_PASSWORD";" "User ID="DB_USER_ID";Data Source="DB_DATA_SOURCE";" "Persist Security Info=True;";
Ich denke Du wolltest
adoquery->ConnectionString = "Provider="+DB_PROVIDER+";Password="+DB_PASSWORD+";User ID="+DB_USER_ID+";Data Source="+DB_DATA_SOURCE+";Persist Security Info=True;";
weil die Werte Variablen sind und Du ja einen (Ansi)String übergibst.
Weiterhin würde ich immer vor einen ADOQuery->SQL->ADD ein ADOQuery->SQL->Clear durchführen, um zu gewährleisten, daß da auch ja nichts drin steht.
Zur SQL-Befehlabarbeitung (Insert,update,delete) ist die Query als DataSet schon genau richtig und nichts weiter notwendig.
-
an die Ergebnismenge kommt man nicht indem man einfach
sql_ausfuehrung = adoquery->ExecSQL(); oder
sql_ausfuehrung = adoquery->Open(); machtdu musst schon mit FieldByName oder Fields[Index] darauf zugreifen
in einem anderen Thread von dir wurde von caspar_louis schon ein Beispiel gegeben
-
ich glaube schon, dass mein ConnectionString so richtig ist, da die Variablen
#define Werte sind. Und mit einem "+" würde es an dieser Stelle nicht gehen!
Die Verbindung wird auch hergestellt. Ich denke, dass mein Problem an einer anderen Stelle liegt.Ich habe jetzt mal dasProgramm zum Testen ein wenig verändert.
Es lautet jetzt so:TDataSet *dataset; AnsiString DB_PROVIDER = "******"; AnsiString DB_PASSWORD = "******"; AnsiString DB_USER_ID = "******"; AnsiString DB_DATA_SOURCE = "******"; adoc->ConnectionString = "Provider="+DB_PROVIDER+";Password="+DB_PASSWORD+";" "User ID="+DB_USER_ID+";Data Source="+DB_DATA_SOURCE+";" "Persist Security Info=True;"; adoc->Open(); adoquery->DataSource = datasource; adoquery->Connection = adoconnection; AnsiString sql; AnsiString ergebnis; int count; sql = "SELECT bs.emailsperre FROM Bearbeitungsstatus bs WHERE bs.personalnummer = 85/150 AND bs.monat = 3 AND bs.jahr = 2006"; adoquery->SQL->Clear(); adoquery->SQL->Add(sql); adoquery->Open(); dataset = adoquery->DataSource->DataSet; count = dataset->FieldCount;
Er kommt jetzt bis zur Stelle
dataset = adoquery->DataSource->DataSet;
Wenn ich danach die Anzahl abfragen möchte, dann schmeist er mir folgenden Fehler:
Im Projekt xxxx ist eine Exception der Klasse EAccessViolation aufgetreten. Meldung:
Zugriffsverletzung bei Adresse 4032C91C in Modul dbrtl60.bpl. Prozeß wurde angehalten. Mit Einzelne Anweisung oder Start
fortsetzen.Das Programm ist doch von Ansatz her richtig, oder?
Jetzt wollte ich eigentlich mit der TDataSet Komponente auf die Ergebnismenge zugreifen und damit was machen!
z.B.ergebnis = dataset->Fields->Fields[0]->AsString;
Kann mir einer weiterhelfen den Fehler zu beheben?
Vielen Dank
-
Do sulltest mal den Bereich Datenbanken im Builder Tutorial hier auf dieser Seite durchgearbeiten ...
-
count = dataset->FieldCount;
Welche Anzahl?
Du fragst die Anzahl der Spalten ab, nicht die die der Datensätze. Willst Du das?
Sonstcount =ADOQuery->RecordCount;
BCB-Hilfe
Mit SQL legen Sie die SQL-Anweisung fest, die mit Hilfe der Methoden ExecSQL oder Open der ADO-Abfragekomponente ausgeführt wird.
...
ADOQuery1->Close();
ADOQuery1->SQL->Clear();
ADOQuery1->SQL->Add("SELECT EmpNo, LastName, FirstName, HireDate");
ADOQuery1->SQL->Add("FROM Employee");ADOQuery1->Open();
Warum "öffnest Du Deine Query, bevor Du was zur Abfrage übergeben hast?
dataset brauchst Du nicht.
ergebnis = ADOQuery->Fields[0]->AsString;
-
@loggi:
Im Prinzip hast du schon recht, dass werde ich auch machen, doch ich habe ein kleines Problem mit meinem Programm gerade und ich müsste schon schnell vorwärts kommen;
Ich brauche vielleicht mal ein kleines Bsp für ADO - Komponenten (welche ich benutzen muss...)
Damit ich endlich eine Ergbenismenge bekomm und auf die zugreifen kann!Sorry wenn ich ein wenig gereizt schreib, aber es nervt mich, dass ich mit dem selben SQL-Befehl im Datenbank Explorer von BCB eine Ergebnismenge bekomm (genau die die ich haben möchte) und mit den Komponenten bekomm ich das gerade nicht hin!
Mit ist klar, das ich zum Ausführen eines SQL-Befehls eine ADOQuery - Komponente benutzen kann. Wenn eine Ergebnismenge zurück kommt dann ->Open() ansonsten ->ExecSQL();
Ich brauch auch eine DataSource - Komponente, da diese die Ergebnismenge speichert(??) oder?
So, jetzt führe ich also mein SQL Statement aus nachdem ich eine Verbindung hergestellt habe aber es kommt keine Ergebnismenge zurück
HILFE!
-
Ich brauch auch eine DataSource - Komponente, da diese die Ergebnismenge speichert(??) oder?
Nein, dein Query kann mehr als du denkst.
Deine Ergebnismenge hast du im Query.
-
OK!
caspar_louis hat ja auch anhand einem Bsp schön gezeigt, wie man das mit dieser Komponente lösen kann.
Leider bekomm ich aber keine Ergebnisse übermittelt! Das ist ziemlich komisch da ich wie gesagt mit dem selben SQL Befehl ja im Datenbank Explorer ein Ergebnis bekomm.Habe ich vielleicht eine Einstellung vergessen?
Denn er bringt ja so keine Syntaxfehler sondern er liefert mir immer "0" bei RecoderCount obwohl er in diesem Fall ja "1" sein müsste!Ich habe in meine Projekt eine ADOConnection, ADOQuery und eine TDataSource Komponente.
(fehlen welche?)
-
Komponenten sollten nicht fehlen.
Was mir aufgefallen ist
SELECT bs.emailsperre FROM Bearbeitungsstatus bs WHERE bs.personalnummer = 85/150 AND bs.monat = 3 AND bs.jahr = 2006
Sollte das ein String sein, vovon ich ausgehen, dann gehört das in Hochkommas o.ä. (je nach SQL).
Sonst fragt er auf bs.personalnummer = 0.56, weil er ja 85/150 rechnet.
-
Ich habe jetzt hinbekommen, dass ADOQuery->FieldCount mir ein Ergegbis liefert.
Das Ergbenis ist "1";Jetzt möchte ich das Ergebnis in einen AnsiString kopieren.
Und zwar habe ich folgendes probiert:
ergebnis = adoq->Fields->Fields[0]->AsString;
Doch er schreibt mir in die Variable "ergebnis" nur den Wert NULL!! Woran kann das denn jetzt liegen?
Oder muss man ganz anders auf die Ergebnismenge zugreifen?
Danke für die Antworten (sie helfen mir wirklich weiter)
-
Liest Du die Antworten ?
Falls ja, dann lies sie nochmal.
-
Ja ich lese sie
Aber du hattest mir folgenden Befehl gezeigt:ergebnis = ADOQuery->Fields[0]->AsString;
Wenn ich so den Befehl ausführen möchte, dann bringt er mir folgenden Fehler
[C++ Fehler] Unit1.cpp(50): E2288 Zeiger auf Struktur auf linker Seite von -> oder von ->* erforderlich*
Was ist deiner Meinung nach damit zu machen?
-
BCB-Hilfe
Beschreibung
Mit FieldCount können Sie die Anzahl der in der Eigenschaft Fields aufgelisteten Felder ermitteln. Bei Datenmengen mit dynamisch erstellten Feldern kann der Wert bei jedem Öffnen unterschiedlich sein. Bei Datenmengen mit persistenten Feldern sollte FieldCount bei jedem Öffnen der Datenmenge identisch sein.
Das sagt Die also nur, daß Du eine Spalte abgefragt hast (Bei dem Select). Es sagt Dir gar nichts über die Ergebnismenge aus. Da mußt Du schon ADOQuery->RecordCount nehmen. Das gibt die Anzahl der Treffer.
-
Oh gott stimmt ja!
Sorry! Das hatte ich ganz übersehen. Ich habe das Projekt neu gestartet und da waren die Änderungen von vorher nicht übernommen worden.
Wenn ich jetzt RecordCount nehme dann liefert er mir "-1" als Ergebnis.
Laut Hilfe:RecordCount enthält nur dann einen gültigen Wert, wenn die Datenmenge aktiv ist. Wenn die Anzahl der Datensätze nicht ermittelt werden kann, ist RecordCount -1.
kann also hier keine Datensätze ermittelt werden.
Was meinen die denn mit "Datenmenge aktiv ist"?? Muss man noch eine Einstellung vornehmen, damit ich sie abrufen kann?Die Werte stehen ja in der DB, aber ich komm nicht dran! So ein scheiß!
-
ergebnis = ADOQuery->Fields[0]->AsString;
Ja das war natürlich falsch.
ergebnis = ADOQuery->FieldByName("NameDesFeldes")->AsString;
wäre richtig. Aber das scheinst Du nicht so richtig zu mögen.
Ich setze das immer ein, um nicht von der Reihenfolge im Select abhängig zu sein. Das kann sich ja ändern. Wenn du stur nach Index arbeitest, kann es Dir passieren,daß Du die falschen Werte zuordnest (nicht bei Abfrage von nur einer Spalte).
Die Datenmenge = Abfragemenge = RecordSet im DataSet von ADOQuery wird mit Open() aktiv, mit Close() inaktiv, also dann wenn Du die Abfrage ausführst.
Ich denke immer noch, daß Du kein Ergebnis kriegst, weil Deine Where-Bedingung nicht korrekt ist (siehe vorherige Antworten). Dazu hast Du Dich auch noch nicht geäußert.
-
Hmm wenn ich ehrlich bin hat mir die Lösung mit dem "FieldByName" wirklich nicht so gut gefallen!
Aber deine Argumente scheinen für diese Methode zu sprechen!
Wahrscheinlich hast du recht mit der where Bedingung!
Ich habe gedacht, dass wenn ich schreibe:
"SELECT bs.emailsperre FROM Bearbeitungsstatus bs WHERE bs.personalnummer = 85/150 AND bs.monat = 3 AND bs.jahr = 2006"
das er dann alles als String ansieht und diesen dann ausführen kann!
Müssen also Werte nach denen gesucht werden immer in Hochkomma stehen?Wie würde ich das in diesem Fall richtig machen?
Wenn ich z.B. ein anderes SQL-Statement nehme wie:
AnsiString persnr = "67/150"; sql = "select a.datum from aida_daten a where a.personalnummer = "+persnr;
dann führt er sogar nicht mehr die Methode adoquery->Open() aus!
Er meldet EDatabaseError -> Ungültige Feldgröße!Was hat das denn jetzt schon wieder zu bedeuten? Alle SQL-Befehle teste ich vorher im DB-Explorer und die funktionieren super.
Das einzige ist, das es mit diesem Hochkommas zusammenhängen kann!
Wie kann ich das lösen?
-
Hast Du mal den Debugger benutzt und dabei den Ausdruck sql überwacht?
Welchen Inhalt hat sql, wenn Du es mit <<ADOQuery->SQL->ADD(sql);>> übergibst?
Du kannst auch den Ausdruck <<ADOQuery->SQL>> selbst überwachen und sehen, was da rauskommt.
Ich hätte übrigens auf folgende Syntax für den SQL-Befehl getippt.
SELECT bs.emailsperre FROM Bearbeitungsstatus bs WHERE bs.personalnummer = '85/150' AND bs.monat = 3 AND bs.jahr = 2006"
Also z.B. so zusammengebaut
AnsiString persnr = "67/150"; AnsiString sql = "select a.datum from aida_daten a where a.personalnummer = '"+persnr+"'";
Eleganter wäre natürlich die Übergabe von Parametern an das SQL-Konstrukt(nachzulesen in BCB-Hilfe).
So und nun mach ich erst mal Mittag.