Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Auf einen Datensatz in einem Resultset positionieren (Locate) (https://www.delphipraxis.net/201564-auf-einen-datensatz-einem-resultset-positionieren-locate.html)

MPirnstill 1. Aug 2019 15:46

Delphi-Version: 7

Auf einen Datensatz in einem Resultset positionieren (Locate)
 
Hallo,

ich nutze Delphi, der Datenzugriff geht über SQLDircet auf eine MS SQLServer.

Ich nutze schon eine Weile TSDQuery.Locate, aber es ist mir jetzt klar geworden, dass die Suchkriterien im VarArray-Parameter nicht um den Typ scheren.

Ich suche in einer Adress-Tabelle z.B. über Name, dazu nutze ich eine Select-Anweisung. Aus der Treffermenge kann der Anwender einen Datensatz anklicken auf den ich dann mit Locate in meine Haupt-Resultset (eigentliche alle der Tabelle) um auf den gesuchten DS zu positionieren.
Hier verwende ich natürlich den PI eine ID vom Typ Integer.
Aber da die Datenmenge für die Anwender sinnvollerweise nach Name sortiert ist, steht z.B. die ID 749 vor der ID 74 und Locate scheint das Integer-Feld wie ein Char-Feld zu behandeln und gibt mir schon bei entspr. 749 als Treffer zurück.

Kann ich Locate irgendwie sagen, das ich da in einem Integer-Feld suche und 749 nicht gleich 74 ist?
Oder gibt es eine andere Methode innerhalb eines Resultset auf einen Datensatz zu positionieren?

Früher bei TTable habe ich FindKey benutzt, aber inzwischen ist alles TQuery bzw. TSDQuery.

Vielen Dank für eure Hilfe im Voraus.

Micha

mkinzler 1. Aug 2019 16:07

AW: Auf einen Datensatz in einem Resultset positionieren (Locate)
 
das hört sich eher nach der Option loPartialKey an.

peterbelow 1. Aug 2019 16:15

AW: Auf einen Datensatz in einem Resultset positionieren (Locate)
 
Zitat:

Zitat von MPirnstill (Beitrag 1438844)
Hallo,

ich nutze Delphi, der Datenzugriff geht über SQLDircet auf eine MS SQLServer.

Ich nutze schon eine Weile TSDQuery.Locate, aber es ist mir jetzt klar geworden, dass die Suchkriterien im VarArray-Parameter nicht um den Typ scheren.

Ich suche in einer Adress-Tabelle z.B. über Name, dazu nutze ich eine Select-Anweisung. Aus der Treffermenge kann der Anwender einen Datensatz anklicken auf den ich dann mit Locate in meine Haupt-Resultset (eigentliche alle der Tabelle) um auf den gesuchten DS zu positionieren.
Hier verwende ich natürlich den PI eine ID vom Typ Integer.
Aber da die Datenmenge für die Anwender sinnvollerweise nach Name sortiert ist, steht z.B. die ID 749 vor der ID 74 und Locate scheint das Integer-Feld wie ein Char-Feld zu behandeln und gibt mir schon bei entspr. 749 als Treffer zurück.

Kann ich Locate irgendwie sagen, das ich da in einem Integer-Feld suche und 749 nicht gleich 74 ist?
Oder gibt es eine andere Methode innerhalb eines Resultset auf einen Datensatz zu positionieren?

Früher bei TTable habe ich FindKey benutzt, aber inzwischen ist alles TQuery bzw. TSDQuery.

Vielen Dank für eure Hilfe im Voraus.

Micha

Was Du da treibst ist nicht die Art, wie man mit einer SQL-Datenbank arbeiten sollte. Anstatt den vom Benutzer markierten Datensatz in einen clientseitigen Dataset zu suchen solltest Du eine neue Query absetzen, die anhand der PI nur den gewählten Datensatz zurückgibt, und dieser Dataset kann dann eventuell editiert werden, oder was Du auch immer damit anstellen willst. Locate ist ein Fossil aus den Tagen von Paradox und dBase und TTable, das sollte man meiner Meinung nach nicht mehr verwenden.

Allerdings: wenn dein "voller" Dataset über eine Query mit einer order by Klausel über die PI erzeugt wurde könnte das Locate sogar funktionieren.

hoika 1. Aug 2019 17:12

AW: Auf einen Datensatz in einem Resultset positionieren (Locate)
 
Hallo,
also ich habe das mehrfach durchgelesen und trotzdem nicht verstanden ...

Zitat:

steht z.B. die ID 749 vor der ID 74 und Locate scheint das Integer-Feld wie ein Char-Feld zu behandeln und gibt mir schon bei entspr. 749 als Treffer zurück.
Auch bei einem Char-Feld wäre das Locate doch auch falsch!.

Char2="749"
Char1="74"

Where Char="74" darf doch auch hier nicht "749" zurückliefern ...

Ich würde mir mal ein paar Optionen des Locate ansehen und
1. "Filter" benutzen
2. direkte Queries nehmen, also wieder Abfragen zum SQL-Server schicken
3. Umsteigen auf TClientDataSet

Punkt 1 und 3 ergaben sich nach Goggle-Suche "TQuery Locate Error"

haentschman 1. Aug 2019 20:07

AW: Auf einen Datensatz in einem Resultset positionieren (Locate)
 
Moin...8-)
Zitat:

direkte Queries nehmen, also wieder Abfragen zum SQL-Server schicken
...ich persönlich bin vom Locate (auch MSSQL) weg. Ich hatte auch so Fälle wo z.B. der Datensatz nachweislich existiert hat, aber Locate False ausgewiesen hat. Seit der Umstellung auf Queries (SQL) habe ich die Probleme nicht mehr. :thumb:

hoika 1. Aug 2019 20:12

AW: Auf einen Datensatz in einem Resultset positionieren (Locate)
 
Hallo,
Zitat:

Ich hatte auch so Fälle wo z.B. der Datensatz nachweislich existiert hat, aber Locate False ausgewiesen
Hört sich wie ein Transaktionsproblem an.
IdR wird bei jeder neuen Query auch eine Transaktion gestartet und dein Ärger war weg ;)

haentschman 2. Aug 2019 06:35

AW: Auf einen Datensatz in einem Resultset positionieren (Locate)
 
Moin...8-)
Zitat:

Hört sich wie ein Transaktionsproblem an
...bei einem Select der Datenmenge? :zwinker: Ich habe dann aufgegeben... Der Locate "sucht" ja lokal in der geladenen Datenmenge. Wenn der Datensatz nachweislich geladen wurde, aber Locate False ausgibt, ist irgendwas falsch.:?

DasWolf 2. Aug 2019 09:29

AW: Auf einen Datensatz in einem Resultset positionieren (Locate)
 
Zitat:

Zitat von MPirnstill (Beitrag 1438844)
Ich nutze schon eine Weile TSDQuery.Locate, aber es ist mir jetzt klar geworden, dass die Suchkriterien im VarArray-Parameter nicht um den Typ scheren.

Wie sieht denn Dein Locate in voller Länge aus?

Zitat:

Zitat von peterbelow (Beitrag 1438846)
Was Du da treibst ist nicht die Art, wie man mit einer SQL-Datenbank arbeiten sollte. Anstatt den vom Benutzer markierten Datensatz in einen clientseitigen Dataset zu suchen solltest Du eine neue Query absetzen, die anhand der PI nur den gewählten Datensatz zurückgibt, und dieser Dataset kann dann eventuell editiert werden, oder was Du auch immer damit anstellen willst. Locate ist ein Fossil aus den Tagen von Paradox und dBase und TTable, das sollte man meiner Meinung nach nicht mehr verwenden.

Zitat:

Zitat von haentschman (Beitrag 1438878)
Moin...8-)
Zitat:

direkte Queries nehmen, also wieder Abfragen zum SQL-Server schicken
...ich persönlich bin vom Locate (auch MSSQL) weg. Ich hatte auch so Fälle wo z.B. der Datensatz nachweislich existiert hat, aber Locate False ausgewiesen hat. Seit der Umstellung auf Queries (SQL) habe ich die Probleme nicht mehr. :thumb:

Naja, um nicht ständig den Datenbankserver zu "nerven", sollte man folgende Instrumente niemals aus den Augen verlieren:
  • Delphi-Quellcode:
    Locate
  • Delphi-Quellcode:
    Filter
  • Delphi-Quellcode:
    CachedUpdates=True

haentschman 2. Aug 2019 09:44

AW: Auf einen Datensatz in einem Resultset positionieren (Locate)
 
Moin...8-)
Zitat:

Naja, um nicht ständig den Datenbankserver zu "nerven", sollte man folgende Instrumente niemals aus den Augen verlieren:
...dem widerspreche ich. :wink: Warum soll ich mir die komplette "Tabelle" laden um mir den passenden DS rauszusuchen? :roll: Mit einer einfachen Abfrage holt man sich das was man möchte zu dem Zeitpunkt wann man es braucht. 8-)

Zitat:

Locate ist ein Fossil aus den Tagen von Paradox und dBase und TTable, das sollte man meiner Meinung nach nicht mehr verwenden.
+ :thumb:

exilant 2. Aug 2019 09:57

AW: Auf einen Datensatz in einem Resultset positionieren (Locate)
 
Zitat:

Zitat von peterbelow (Beitrag 1438846)
Was Du da treibst ist nicht die Art, wie man mit einer SQL-Datenbank arbeiten sollte. Anstatt den vom Benutzer markierten Datensatz in einen clientseitigen Dataset zu suchen solltest Du eine neue Query absetzen, die anhand der PI nur den gewählten Datensatz zurückgibt, und dieser Dataset kann dann eventuell editiert werden, oder was Du auch immer damit anstellen willst. Locate ist ein Fossil aus den Tagen von Paradox und dBase und TTable, das sollte man meiner Meinung nach nicht mehr verwenden.


Auch das editieren von Datasets mit edit/append/insert/post halte ich für übel.
Ich verstehe auch nach wie vor nicht, warum es Firedac u.ä.aufwendige Data Access Frameworks gibt. Das, was man wirklich brauchen könnte (ORM) leistet es nicht. Und der Rest wie das editieren von Datasets, "Live"-Querys, cached updates u. ä. sind übel. Eine leichtgewichtige direkte Verbindung zur Datenbank ist alles was man braucht: insert, update, delete. Und ein unidirektionaler Cursor auf eine Datenmenge, geliefert von einem Query.
Aber das ist nur meine Meinung.

jobo 2. Aug 2019 10:23

AW: Auf einen Datensatz in einem Resultset positionieren (Locate)
 
Ich denke der Hinweis von mkinzler ist genau richtig, wenn auch knapp.

Und ich verstehe nicht, warum ein Locate verboten sein soll. Der Anwendungsfall, bei dem in einem Dateset auf einen bestimmten Datensatz gesprungen wird (werden soll) ist doch hier niemand bekannt.

Wieso wird sowas immer gleich so niedergemacht. Filter ist etwas anderes als Locate, Query mit Where Clause sowieso.

Wieso kann man nicht fragen, was gewollt und bekannt ist, statt zu behaupten, das sei alles falsch.

Und wenn ein Locate nicht funktionieren sollte, der Anwendungsfall aber diese Funktion benötigt, würde man wohl darüber schreiben müssen, wie man es nachbaut.

MPirnstill 2. Aug 2019 10:36

AW: Auf einen Datensatz in einem Resultset positionieren (Locate)
 
Also ursprünglich war das mal eine TTable und man konnte mit dem DBNavigator in der Datenmenge vor- und zurückblättern, editieren, usw.
Dafür brauche ich doch die kompletten Datensätze, oder nicht?

Aber da es natürlich durch einfach blättern von Datensatz zu Datensatz zu mühselig/langwierig für die Anwender ist zu einem bestimmten Datensatz zu gelangen, mache ich auf Knopfdruck ein Suchfenster auf, wo der Anwender seine Suchparameter eingeben kann, wobei ich schon bei der Eingabe eine Ergebnismenge im Suchfenster anzeige. Klickt der Anwender dann auf eine Datensatz in der Ergebnismenge nehme ich mir den PI und will damit auf den DS im Adressdialog zu positionieren. Früher als noch TTable war per FindKey, später als es auf TQuery umgestellt war mit Locate.

Und das ging auch recht gut bis jetzt aufgefallen ist, das ...

- bei der Datenmenge, die für die Anwender nach Namenfeld sortiert ist, der PI 749 in der Datenmenge vor 74 liegt.
z.B.
PI Name
749 Hugo
..
..
74 Klaus

der Locate sieht so aus ...
Code:
      Locate('Adress_ID', StrToInt(aID), [loPartialKey]);
Da das Eingabefeld für den Suchbegriff ein alphanumerisches Feld ist, wandele ich es hier mit StrToInt um, aber das scheint locate nicht zu interessieren und positioniert deshalb auf "749 Hugo".

Ich hoffe, ich konnte hiermit verständlicher machen, in welcher Weise ich hier vorgehe. Mir wurde immer gesagt, viele Wege führen nach Rom. :wink:
Wenn der Ansatz falsch ist, wäre dankbar für eine kurze Beschreibung der richtigen Herangehensweise.

p80286 2. Aug 2019 10:38

AW: Auf einen Datensatz in einem Resultset positionieren (Locate)
 
"Verboten" hab ich nirgendwo gesehen. Aber es ist schon die Frage was eigentlich erreicht werden soll.
Wenn z.B. alle Kunden in Mannheim zur Auswahl stehen sollen, würde ich es so lösen, daß ich zuerst die Kundennamen+ID hole und dann, nach der Auswahl, an hand der ID die vollständigen DatenSätze für das Edit.
Wenn es sich aber um eine Hand voll Datensätze handelt die man vollständig mit sich schleppen kann, dürfte der Weg über Locate oder ähnliches wohl effizienter sein.

Gruß
K-H

MPirnstill 2. Aug 2019 10:38

AW: Auf einen Datensatz in einem Resultset positionieren (Locate)
 
Zitat:

Zitat von mkinzler (Beitrag 1438845)
das hört sich eher nach der Option loPartialKey an.

Meinst du damit, das ich loPartialKey hier weglassen soll?

Ich werde das mal ausprobieren. Muss ich aber aufpassen, da ich den Suchdialog auch für andere Dialoge verwende.

mkinzler 2. Aug 2019 11:00

AW: Auf einen Datensatz in einem Resultset positionieren (Locate)
 
Zitat:

Meinst du damit, das ich loPartialKey hier weglassen soll?
Ja. Bewirkt, dass teilweise Übereinstimmungen erkannt werden.

MPirnstill 2. Aug 2019 11:16

AW: Auf einen Datensatz in einem Resultset positionieren (Locate)
 
Zitat:

Zitat von mkinzler (Beitrag 1438983)
Zitat:

Meinst du damit, das ich loPartialKey hier weglassen soll?
Ja. Bewirkt, dass teilweise Übereinstimmungen erkannt werden.

Hab's ausprobiert. Ohne den Parameter findet und positioniert "locate" auf den richtigen Datensatz.
Vielen Dank an alle.


P.S.:
Noch kurz zur Herangehensweise.
Als ich da Programm 1994 geschrieben hab, wo Delphi noch BDE hat und so, hat man doch mit TTable und DBNavigator gearbeitet.
Ist ja auch nur ein kleiner Dialog innerhalb einer größeren Anwendung.
Als ich dann auf TQuery umgestellt hab, hatte ich die im Prinzip nur ausgetauscht und anstelle FindKey dafür Locate verwendet.
Ich das, in dieser Weise wirklich so falsch?
Ich mein unter der Oberfläche könnte ich Anpassungen vornehmen, aber ich weiß nicht, ob ihr das kennt, der Anwender ist ein Gewohnheitstier
und wenn ich die Oberfläche verändere, kommen bestimmt wieder Proteste.

haentschman 2. Aug 2019 11:28

AW: Auf einen Datensatz in einem Resultset positionieren (Locate)
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Und ich verstehe nicht, warum ein Locate verboten sein soll...
Wieso wird sowas immer gleich so niedergemacht.
...weil es eben nicht immer funktioniert. :?

ca. 700.000 Einträge. Die ersten sagen schon alles. ADO hat damit sowieso seine Probleme. :?
https://www.google.de/search?source=...4dUDCAc&uact=5

jobo 2. Aug 2019 12:39

AW: Auf einen Datensatz in einem Resultset positionieren (Locate)
 
Können mehr als 700T google Treffer irren?

meine Suchbegriffe zur Gegenprobe: c# dataset locate probleme

Gemäß der Ergebnisanzahl von 5,4 Mio empfehle ich dann konsequent am besten gleich gar kein C#
einzusetzen.
Es scheint ungefähr 8 Mal so problematisch zu sein.

jobo 2. Aug 2019 12:46

AW: Auf einen Datensatz in einem Resultset positionieren (Locate)
 
Zitat:

Zitat von MPirnstill (Beitrag 1438988)
Noch kurz zur Herangehensweise.
Als ich da Programm 1994 geschrieben hab, wo Delphi noch BDE hat und so, hat man doch mit TTable und DBNavigator gearbeitet.
..
Als ich dann auf TQuery umgestellt hab, hatte ich die im Prinzip nur ausgetauscht und anstelle FindKey dafür Locate verwendet.
Ich das, in dieser Weise wirklich so falsch?
..

Falsch ist m.E. nicht der richtige Ansatz.
Es gibt Probleme, die idR priorisiert werden und es gibt Aufwände, diese Probleme zu beheben.
Wenn die Lösung von mkinzler für Dein Problem funktioniert, scheint es mir einfach sehr effizient zu sein.

Und ich möchte nicht wissen, wie viele alte BDE Programme so umgestellt wurden wie Du es grob beschrieben hast. Es ist nicht unbedingt ideal, aber wer würde sich beschweren, wenn es funktioniert.

Und klar, wenn man etwas nicht ganz besonders richtig macht, fällt es einem irgendwann auf die Füße und tut weh. Mit dem Risiko muss man eben leben.

Jenachdem wen Du fragst, wirst Du eine andere Antwort erhalten.


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:50 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