![]() |
Datenbank: Access MDB • Zugriff über: ADO
SQL Abfrage auf Access .mdb
Tag DP-Gemeinde,
bin jetzt schon ne weile im Forum angemeldet, und konnte auch schon einige Lösungen hier finden. Jetzt komme ich hier auch mal zu einem Eigenen Beitrag. Folgendes Problem steht bei mir an: Mein Programm soll mehrere Clients permanent überwachen, nun soll bei Programmstart eine lokale Access Liste angelegt werden, die aus Informationen der Clients besteht, welche am Server angemeldet sind. Aus dieser Liste wiederum sollen nun die IDs aller Clients die abgefragt werden sollen, in Delphi in ein dyn Feld geschrieben werden. Hierzu wiederum wird am Server eine Flag gesetzt, die in der Access Tabelle das Feld Status auf 'Y' setzt (Etwas ungünstig, da String obwohl Bool gereicht hätte, geht aber Server seitig nun nicht mehr anders) Langer Rede kurzer Sinn: Momentan rufe ich einfach alle IDs der in der Liste eingetragenen Clients ab, ohne auf den Status zu achten.
Delphi-Quellcode:
Das funktioniert auch wunderbar, nur werden später eben auch die Geräte gepollt die gar nicht benötigt werden.
DataModule.ADOTableClients.Active := True;
NumberOfClients := DataModule.ADOTableClients.RecordCount; SetLength(Client_ID_Array, NumberOfClients); for i := 0 to (NumberOfClients - 1) do begin Client_ID_Array[i]:= DataModule.ADOTableClients.FieldByName ('ID').AsInteger; DataModule.ADOTableClients.Next; end; Um das zu ändern nehme ich statt der Table eine Query:
Delphi-Quellcode:
Kompiliert auch, tut aber nichts, sprich NumberOfClients ist immer 0.
with DataModule.ADOQueryClients do
begin Close; SQL.Text := 'SELECT ID FROM Clients WHERE Status LIKE :Status '; Parameters.ParamByName('Status').Value:='Y'; Open; NumberOfClients := RowsAffected; end; Da ich die Delphi Geschichte jetzt erst seit knapp 2 Monaten mache und die Zeit mit Datenbanken in Delphi noch erheblich kürzer ist, kanns natürlich sein, dass das nur Blödsinn und der Fehler recht simpel ist. Ich find ihn aber leider nicht :coder2: Dann muss natürlich auch noch die for Schleife für die Query angepasst werden, wobei ich hier momentan auch noch etwas auf dem Schlauch stehe. Wäre schön wenn mir hier jemand bei diesem Problem helfen könnte. |
Re: SQL Abfrage auf Access .mdb
Warum like? Dann brauchst du auch den Joker
|
Re: SQL Abfrage auf Access .mdb
Auch ein = ändert nichts am Ergebnis, oder hab ich dich falsch verstanden?
Edit: Nur zum Verständnis: Wenn mein Wert genau Y ist, dann sollte doch auch ein LIKE ohne Joker funktionieren, oder? |
Re: SQL Abfrage auf Access .mdb
Irre ich mich, oder gibt RowsAffected die Anzahl der durch ein Statement geänderten Datensätze zurück?
[edit] Achja, Willkommen in der DP :dp: [/edit] |
Re: SQL Abfrage auf Access .mdb
Zitat:
Zitat:
@DeddyH: Danke, fühl mich schon recht wohl :-D |
Re: SQL Abfrage auf Access .mdb
Wenn es dir nur um die Anzahl geht, dann schreib doch ein "Select count(........)"-SQL. Dann sparst du dir das ermitteln über Delphi und Recordcount & co.
|
Re: SQL Abfrage auf Access .mdb
Ich möchte ja dann auch die IDs der ermittelten Datensätze haben, damit ich später nur diese Clients pollen kann.
Die Anzahl stellt dabei nur die Längenangabe für das dynamische Array und den Zähler der for-Schleife dar. Die SQL Anweisung funktioniert eben im Delphi Kontext irgendwie nicht. Im SQL Editor gibt er mir brav die gewünschten Datensätze zurück. |
Re: SQL Abfrage auf Access .mdb
Geh doch mal mit Last auf den letzten Datensatz, bevor Du den RecordCount abfragst. Ich meine mal gelesen zu haben, dass das helfen soll.
|
Re: SQL Abfrage auf Access .mdb
... auch nicht.
Hab auch mal versucht den Parameter wegzulassen:
Delphi-Quellcode:
Aber das hatte auch nicht den gewünschten Effekt.
SQL.Text := 'SELECT TT_ID FROM Machines WHERE Status = ''Y'' ';
|
Re: SQL Abfrage auf Access .mdb
Und Du bist ganz sicher, dass Du die richtige Datasource zugewiesen hast bzw. die Abfrage auch tatsächlich ausgeführt wird? Mal einen Breakpoint gesetzt? Ist sicherlich nur ein kleiner dummer Fehler, aber so etwas sucht man meist ewig.
|
Re: SQL Abfrage auf Access .mdb
Ich hoffe doch, wird halt zur Laufzeit definiert, so dass das Programm verschoben werden kann.
Delphi-Quellcode:
Datasource von ADOQueryClients ist DataSourceClients, die per DataSet wiederum auf ADOTableClients verweist.DB_Path := ExtractFilePath(ParamStr(0)) + 'DATA'; ADOConnectionStringStandard := 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=' + DB_Path + '\Database.mdb;Persist Security Info=False'; (* ADOTableClients: Definition of 'ConnectionString' and 'Table' *) with ADOTableClients do begin try ConnectionString := 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=' + DB_Path + '\Database.mdb;Persist Security Info=False'; TableName := 'Clients'; Active := True; except ShowMessage('The database Database.mdb could not be found in the current directory ' + #10#13 + DB_Path) end; end; ADOQueryClients. ConnectionString := ADOConnectionStringStandard; Ich suche ja schon ne Weile, von daher kann es fast nur ein kleiner oder besonders dämlicher Fehler sein, der mir nicht auffällt. :pale: |
Re: SQL Abfrage auf Access .mdb
Zunächst einmal würde ich mir einen Breakpoint auf die Ausführung der Abfrage setzen, um zu prüfen, ob Du überhaupt dort ankommst.
Zitat:
|
Re: SQL Abfrage auf Access .mdb
Hüstel, dachte das geht so ...
Ist das wohl der Fehler? Ich wollte eben mit einer Datasource sowohl Query also auch Table abdecken. Durch diese Verbindung wähnte ich dann alles abgedeckt. Kann natürlich sein, dass das absoluter Käse ist und ich mal wieder ungenau gelesen habe. (Gefährliches Halbwissen :stupid: ) |
Re: SQL Abfrage auf Access .mdb
Nimm mal die Datasource bei der Query raus und setze die Query als Dataset in der Datasource ein (ich hoffe, ich habe das jetzt nicht auch verwechselt :mrgreen:).
|
Re: SQL Abfrage auf Access .mdb
Wo/Wie krieg ich denn jetzt meine Tabelle rein? :gruebel:
Ich kann ja nur bei einer Table auch einen tableName vergeben ... |
Re: SQL Abfrage auf Access .mdb
Wozu brauchst Du den Tablename?
|
Re: SQL Abfrage auf Access .mdb
... Stimmt, brauch ich nicht, hab ich in der SQL, schon wieder nur halb gedacht.
... Geht aber trotz allem immer noch nicht. Recordcount und damit NumberOfClients ist nach wie vor 0 Edit: Kann sein, dass ich bei der Aufrufreihenfolge was verzockt habe ... Das ganze wird während der FormCreate procedure der MainForm aufgerufen. Möglich, dass da noch nicht alles initialisiert ist ... Muss das prüfen. |
Re: SQL Abfrage auf Access .mdb
Hallo,
Delphi-Quellcode:
:Status ist doch ein String, also mach mal Hochkommas drum, könnte sein dass das einzelne Y als irgendwas anderes interpretiert wird.
SQL.Text := 'SELECT ID FROM Clients WHERE Status LIKE :Status ';
Delphi-Quellcode:
Was für ein Ergebnis bekommst Du denn ohne die Wherebedingung, dann müsste doch alles kommen, ist dem so, wenn nein, liegt das Problem nicht in der Abfrage.
SQL.Text := 'SELECT ID FROM Clients WHERE Status LIKE ' + QuotedStr('Y'));
Wie sieht das Ergebnis aus, wenn Du es nicht aus Delphi heraus absetzt (Access, Datenbankexplorer, ...)? Stephan |
Re: SQL Abfrage auf Access .mdb
Quoted String hatte ich zuvor auch schon getestet, hat aber nicht funktioniert.
Hab jetzt auch nochmal die Abfrage um die WHERE Passage erleichtert und es passiert genau ... Nichts. Das heisst, dass ich als nächstes wirklich erst mal meiner Vermutung nachgehen muss, das beim Aufruf etwas danebenläuft. Vielen Dank erst mal an alle Beteiligten. Melde mich dann mit der Erfolgsmeldung oder mit weiteren Hilferufen :stupid: |
Re: SQL Abfrage auf Access .mdb
Zitat:
|
Re: SQL Abfrage auf Access .mdb
Geschafft:
Es lag wirklich an der Aufrufreihenfolge. Seltsamerweise hat der einfache Aufruf ohne SQLabfrage an gleicher Stelle funktioniert, mit SQL Abfrage leider nicht. Die Abfrage habe ich nun testweise ins Datenmodul verschoben und voila, hier funktioniert dann alles wie es soll:
Delphi-Quellcode:
Ein Last; hab ich nicht benötigt, im Gegenteil:
with ADOQueryClients do
begin Close; SQL.Text := 'SELECT ID FROM Clients WHERE Status = ''Y'' '; // SQL.Text := 'SELECT ID FROM Clients WHERE Status LIKE :Status '; // funktioniert in diesem Fall genau wie: // SQL.Text := 'SELECT ID FROM Clients WHERE Status = :Status '; // Parameters.ParamByName('Status').Value:='Y'; Open; NumberOfClients := RecordCount; end; SetLength(Client_ID_Array, NumberOfClients); for i := 0 to (NumberOfClients - 1) do begin Client_ID_Array[i]:= ADOQueryClients.FieldList.FieldByName ('ID').AsInteger; ADOQueryClients.Next; end; Setze ich in diesem Fall Last; wird nur noch der letzte Datensatz ins Array übernommen. @ mkinzler: Habs gerade nochmal ausprobiert: Da mein Status nur Y ist, funktioniert LIKE ohne Joker genau wie =. Oder anders formuliert: Lässt man den Joker weg, funktioniert LIKE allgemein wie =. Vielen Dank nochmal an alle. Die Fehlersuche hätte ohne die hier gefallenen Denkanstöße einiges länger gebraucht. :dp: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:42 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz