Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Letzten oder bestimmten Datensatz finden (https://www.delphipraxis.net/5708-letzten-oder-bestimmten-datensatz-finden.html)

Gambit 16. Jun 2003 13:59


Letzten oder bestimmten Datensatz finden
 
Moinsen,

ich möchte in meiner Datenbank einen bestimmten letzten Datensatz finden, dort den Wert eines bestimmten Feldes abfragen und das noch in Abhängigkeit eines anderen Feldes.

Mal klarer: Es gibt ein Feld "Regalnummer" Die soll incrementiert werden bzw. eingetragen werden, wenn ich einen neuen Datensatz anlege. Nun gibts es aber zwei verschiedene Arten von Regalnummern, einmal die, die noch ein "E" hinten dran haben und die, die ein "K" hinten dran haben. Ob E oder K hängt von einem anderen Feld ab.

Ich möchte nun: zb nach E abgrenzen, dann dort den letzten Datensatz finden und ein Feld dieses Datensatzes abfragen.

Wie mach ich das, vor allen Dingen, ohne die Anzeige der Daten in meinem DBGrid zu verändern(FindLast würde also nicht in Frage kommen)

Geht das vielleicht irgendwie mit SQL?

Gruß Gambit

P.S Hoffe, ich hab das einigermaßen klar machen können, irgendwie raucht mir der Kopp bei dem schwülen Wetter...

MrSpock 16. Jun 2003 16:02

Hallo Gambit,

die Abfrage mittels SQL wäre mit dem like operator möglich:

Delphi-Quellcode:
SELECT Max(regalNr) as letzterMitE FROM regale WHERE regalNr LIKE '%E'

Gambit 16. Jun 2003 21:27

Ja, Danke! Aber würde das Ergebnis dann nicht auch sofort in meinem DBGrid angezeigt? Das Ergebnis soll ja nur intern verarbeitet werden.

Engage!

Gambit

MrSpock 17. Jun 2003 06:53

Hallo Gambit,

nein, das Ergebnis steht nur in der TQuery Komponente. Um es anzuzeigen müsstest du erst noch ein Grid und eine TDataSource Komponente mit DIESER Query verknüpfen.

Das Ergebnis liest du mit:

Delphi-Quellcode:
letzter := qryRegale.FieldByName('letzterMitE').AsString;
aus. Je nach verwendeter Datenbank kannst du auch noch die Funktion SubString im SQL Statement benutzen, falls gewünscht.

Gambit 17. Jun 2003 09:29

Das hört sich gut an! Allerdings scheine ich wieder ein Tüddelchen-Problem zu haben:

Habe geschrieben:

Delphi-Quellcode:
Query2.SQL.Add('Select Max(Regalnummer) as letzterMitE FROM DVDBank WHERE Regalnummer LIKE ''%E''');
wenn ich nun:

Delphi-Quellcode:
letzter := Query2.FieldByName('letzterMitE').AsString;
schreibe, bekomm ich die Fehlermeldung: Feld 'letzterMitE' nicht gefunden.

Ist das nun ein Tüddelchen-Problem oder was mach ich falsch?

Ist mir ja schon fast peinlich...

Gambit

Gast 17. Jun 2003 09:29

Hallo Gambit 8)

TDataSet.Lookup

Delphi F1-Taste drücken:

"Die virtuelle Methode Lookup gibt die Feldwerte eines Datensatzes zurück, der mit den angegebenen Suchwerten übereinstimmt."

Von mir:

Im gegensatz zu Locate macht Lookup den gefundenen Datensatz NICHT zu
dem aktuellen Datensatz...

Alternative:

Du musst eine zusätzliche Query benutzen und so die Werte herausfinden

Gruß

Paul Jr.

Gambit 17. Jun 2003 09:35

Query2 ist bereits eine zusätzliche.

Gruß

Gambit

Gast 17. Jun 2003 09:43

Also wo liegt Dein Problem?

Gruß

Paul Jr.

Gambit 17. Jun 2003 09:45

Hab ich doch oben geschrieben: Es wird das Feld letzterMitE nicht erkannt. Ich dachte dieses Alias könnte ich wie einen ganz normalen Feldnamen benutzen.

Gambit

r_kerber 17. Jun 2003 09:47

Mal so aus'm Bauch heraus. Versuche doch mal zur Design-Zeit dieses SELECT inzutragen, und anschließend in der Query die Felder hinzuzufügen.

MrSpock 17. Jun 2003 09:48

Hallo Gambit,

du musst die Query erst ausführen, bevor du auf sie zugreifen kannst, dazu benutzt du bei einem SELECT Statement:

Delphi-Quellcode:
Query2.Open;

Gast 17. Jun 2003 09:49

Ach so jetzt sehe ich...

Query2.SQL.Add('Select Max(Regalnummer) as letzterMitE FROM DVDBank WHERE Regalnummer LIKE ''%E''');


und später so:


IF NOT Query2.EOF THEN
letzter := Query2.FieldByName('letzterMitE').AsString;

... dann es kann sein, dass Du kein Ergebnis mit Deiner Such-Bedingungen
bekommst...

Gruß

Paul Jr.

Gambit 17. Jun 2003 09:55

Hmm, ich hatte es so gemacht:
Delphi-Quellcode:
  Query2.Close;
  Query2.SQL.Clear;
  Query2.SQL.Add('Select Max(Regalnummer) as letzterMitE FROM DVDBank  WHERE Regalnummer LIKE ''%E''');
  Query2.ExecSQL;
ich versuchs mal mit open und der Idee von Rainer.

Die Abfrage sollte schon was finden, ich glaube nicht, dass das das Problem ist. Das Feld wird ja nicht gefunden...

Gambit

Gast 17. Jun 2003 09:58

ExecSQL... Alles klar... und weiter so... :mrgreen:

Mach Dir keine Sorgen... jeder mußt irgendwan anfangen...

Nun... ich würde Dir aber empfehlen nächstes Mall die Komplete Source-Code hier zu zeigen... bevor ich mir meine Finger verletze...

Gruß und viel Erfolg wünscht Dir :D

Paul Jr.

Gambit 17. Jun 2003 10:02

Ja, das kommt, wenn man einfach aus Beispielen abkupfert, sorry.

Jetzt funzt es. Aber die Idee von Rainer hab ich auch übernommen.

Asche auf mein Haupt, hatte sonst immer mit Open gearbeitet, ich fauler Sack...

Gambit

r_kerber 17. Jun 2003 10:15

Zitat:

Zitat von Gambit
Asche auf mein Haupt, hatte sonst immer mit Open gearbeitet, ich fauler Sack...

Selbstkritik ist der erste Schritt zur Besserung :lol: :spin: :chat:

Gambit 17. Jun 2003 10:21

Das Dumme ist nur, dass jetzt 9E als höchstes gefunden wird und nicht 10E, ich krieg die Krätze...


Gambit

r_kerber 17. Jun 2003 10:42

Ist ja auch logisch, 9 ist größer als 1. Du hast es hier mit Zeichenketten zu tun. Da wird beim Vergleich mit dem ersten Zeichen begonnen. Versuche es doch mal mit 09E.

MrSpock 17. Jun 2003 10:43

Hallo Gambit,

das habe ich befürchtet.
Das liegt daran, dass deine Einträge nicht alle gleich lang sind und die kürzeren Einträge nicht mit führenden Nullen oder Blanks aufgefüllt sind.

In diesem Fall, solltest du in der Query die MAX Funktion weglassen:

Delphi-Quellcode:
Select Regalnummer FROM DVDBank WHERE Regalnummer LIKE '%E'
Du erhälst dann eine Datenmenge aller auf E endenden Regalnummern. Diese durchläufst du in einer Schleife:

Delphi-Quellcode:
while Not Query2.Eof do
begin
  { Wert ermitteln }
  Query2.Next
end;
Beim "Wert ermitteln" schneidest du das E ab:

Delphi-Quellcode:
try
  regNr := Query2.FieldByName('RegalNummer').AsString;
  Delete(regNr, length(regNr-1, 1);
  wert := StrToInt(regNr);
except
   { Fehler: RegalNr ist keine Nummer! }
end;
Wenn der so entdeckte Wert größer ist, als der soweit gefundene, dann ist es das (temporäre) Maximum.

Gambit 17. Jun 2003 10:46

Jaja, das war mir schon klar, 09 würde ja auch funzen, nur bei 99 und 100 ginge das Spielchen wieder los. Ich müsste also im Voraus festlegen, wieviel Datensätze die DB maximal verwalten darf und entsprechend Nullen voranstellen, falls mir nichts anderes einfällt. Vielleicht hätte ich besser mit 2 getrennten Felden arbeiten sollen und eins davon als Integer oder sowas deklarieren sollen...

Gambit

Gambit 17. Jun 2003 10:48

Wow Spock, du machst deinem Namen aber alle Ehre!!! Lots of thanks!

Gambit

MrSpock 17. Jun 2003 10:52

:oops: Danke :mrgreen:

Gambit 17. Jun 2003 11:11

Wobei mir dumpf irgendwas in Erinnerung ist, allerdings in Bezug auf SQL Server, dass man ihm sagen kann, dass er Strings wie Integer sortieren soll. Bin mir aber nicht sicher und es fällt mir auch nix genaueres ein...aber so gehts ja auch ganz gut. Ab wieviel Datensätze fängt denn die Routine an langsamer zu werden als die jeweils höchste Regalnummer in einer Datei festzuhalten?

Gambit

Gambit 17. Jun 2003 11:38

btw, muss es nicht einfach nur

Delphi-Quellcode:
Delete(regNr, length(regNr), 1);
heißen?

MrSpock 17. Jun 2003 12:09

Hallo Gambit,

ja, dein Delete Statement stimmt!
Bzgl. Laufzeit ist die wesentliche Frage, ob sich die Datenbank im Netzt oder auf dem lokalen Rechner befindet. Bei lokalen Rechnern sollte die Laufzeit nicht ins Gewicht fallen. Das Merken in einer Datei ist aber immer schneller.


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:43 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz