Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Mehrere Suchbegriffe in einem Datensatz suchen (https://www.delphipraxis.net/4264-mehrere-suchbegriffe-einem-datensatz-suchen.html)

Flo 21. Apr 2003 20:50


Mehrere Suchbegriffe in einem Datensatz suchen
 
Ich möchte eine Suche durchführen. Das besondere daran(oder vielleicht auch nicht) ist, dass man drei Suchbegriffe eingeben kann. Also...er soll nachschauen, ob alle drei Suchbegriffe in einem Datensatz vorhanden ist. Ich habe folgenden Code von MrSpock erhalten:

Delphi-Quellcode:
SELECT * from personen
WHERE (abteilung = :abteilung) AND
(reihe = :reihe) AND
(nr = :nummer)

Ich muss irgendwie mit den erzeugten Parametern auf ParamByName('abteilung').Value zugreifen. Vor dem Open muss ich dann alle 3 Parameter besetzen und schon bekommst ich nur die Sätze, die alle 3 Werte enthalten.

Das ist das, welches ich nicht verstehe :freak:

Vielen Dank nochmal an MrSpock :mrgreen:

MrSpock 21. Apr 2003 21:22

Hallo Flo,

da bin ich schon wieder :mrgreen: .

Ziehe einmal eine TQuery Komponente auf das Formular und setze die Eigenschaft DatabaseName auf den Alias, den du auch für die Tabelle benutzt hast. Dann klicke die SQL Eigenschaft an und schreibe dort das oben gezeigte SQL Statement rein. Dabei musst du natürlich den Tabellennamen, der hinter from steht durch den echten Tabellennamen ersetzen (ohne die Endung .DB), außerdem musst du die drei Felder in der where Klausel durch die korrekten Namen der Felder der Tabelle ersetzen. Die 3 Bezeichner mit dem Doppelpunkt kannst du beliebig nennen, am besten natürlich so, dass die Bedeutung klar wird. Wenn dir das so weit nicht klar ist, dann poste einmal wie die Tabelle heißt und wie die 3 Felder, nach denen du suchen willst.

APP 22. Apr 2003 06:39

Hallo,

ich hätte noch einen anderen Ansatz zu anzubieten, ohne der Parameterfunktion:
Delphi-Quellcode:
  WITH Query1 DO
    BEGIN
        Close;
        WITH SQL DO
          BEGIN
            Clear;
            Add('SELECT * ');
            Add('FROM Tabelle.db');
            Add('WHERE Spalte1 = ' + CHR(39) + Edit1.Text + CHR(39));
            Add('AND Spalte2 = ' + CHR(39) + LCB_AuftraegeFuer.Text + CHR(39)); // Lookupcombobox
            Add('AND TARGSTARTDATE <= ' + CHR(39) + DateToStr(DateTimePicker1.Date) + CHR(39));
          END;
        Query1.Active := True;
        Open;
      END;
    END;
Damit kannst Du Variablen, Comboboxen, Edits usw. als "Parameter" für ein SQL-Statement Übergeben.

Flo 22. Apr 2003 09:33

Danke erst einmal für eure Antworten.

@MrSpock
Soweit habe ich das hinbekommen. Aber ich weiß jetzt nicht, wie ich den Code per Buttonclick aufrufe.

@APP
Hab deinen Code auch mal ausprobiert, aber der klappt irgendwie nicht :cry: Hab ihn natürlich auch angepasst ! Hier ist er:
Delphi-Quellcode:
procedure TForm7.BitBtn1Click(Sender: TObject);
begin
WITH Query1 DO
    BEGIN
        Close;
        WITH SQL DO
          BEGIN
            Clear;
            Add('SELECT * ');
            Add('FROM kosten.db');
            Add('WHERE abteilung = ' + CHR(39) + Edit1.Text + CHR(39));
            Add('AND reihe = ' + CHR(39) + edit2.Text + CHR(39)); // Lookupcombobox
            Add('AND Nr <= ' + CHR(39) + edit3.text + CHR(39));
          END;
        Query1.Active := True;
        Open;
      END;

end;

MrSpock 22. Apr 2003 09:54

Hallo Flo,

den abgebildeten Code fügst du in die Methode ein, die auf ein Doppelklick des OnClick Events des gewünschten Schalters erzeugt wird. Das "Open" der Query Komponente führt letztlich die Abfrage aus.

Zum Code vom APP:

Du solltest ihn wie folgt ändern:
Delphi-Quellcode:
WITH Query1 DO
    BEGIN
        Close;
        WITH SQL DO
          BEGIN
            Clear;
            Add('SELECT * ');
            { Tabellenname ohne Punkt, sonst muss er in
              Anführungszeichen gestzt werden }
            Add('FROM kosten');
            Add('WHERE abteilung = ' + CHR(39) + Edit1.Text + CHR(39));
            { falls reihe und Nr Zahlenfelder sind, muss das Chr(39)
              weggelassen werden }
            Add('AND reihe = ' +edit2.Text);
            Add('AND Nr <= ' +edit3.text);
          END;
        Query1.Active := True;
        Open;
      END;

Flo 22. Apr 2003 19:22

Danke, aber ich bekomme folgende Fehlermeldung:

Ungültiges Schlüsselwort
Symbol-String R1'
and Nummer <= 1
Zeilennummer4

R1 ist die Reihe.
Was sagt die Fehlermeldung aus und wie bekomme ich das Problem in den Griff? :roll:

MrSpock 22. Apr 2003 20:51

Hallo Flo,
wie gesagt, ob du Chr(39) um den Feldwert packen musst, hängt vom Datentyp ab. Ist "Reihe" ein Stringfeld, musst du Edit2.Text in "" übergeben, das gehtmit Chr(39)+Edit2.Text+Chr(39) oder einfacher über QuotedStr(Edit2.Text). Handelt es sich bei einem Feld um ein Numerisches Feld, muss der Wert von Editx.Text direkt benutzt werden.

Flo 23. Apr 2003 10:20

Jetzt kommt die Fehlermedlung:
'Keine Übereinstimmung der Typen im Ausdruck' :x

MrSpock 23. Apr 2003 16:15

Hallo Flo,

OK, dann poste doch bitte noch einmal die genaue Definition der Felder:
  • abteilung
  • reihe
  • nr
außerdem die Zuordnung, was steht in Edit1, Edit2 und Edit3.
Mit dieser Info sollte es möglich sein, die Query klar und korrekt zu definieren.

Flo 24. Apr 2003 13:43

Ok....*such*....

in edit2 steht die abteilung,
in edit2 steht die Reihe und
in edit3 steht die Nummer.

Abteilung = Abteilung,
Reihe = Reihe,
Nummer = Nummer.

Abteilung und Nummer enthalten Zahlen und Buchstaben. Reihe nur Zahlen.

Wenn noch was fehlt, bitte melden !

Cobra 24. Apr 2003 15:18

Hallo Flo,

also ich kenne mich nur mit Interbase und IBX aus und da geht folgendes immer.

Delphi-Quellcode:
      Add('SELECT * ');
      Add('FROM kosten');
      Add('WHERE abteilung = "' + Edit1.Text + '"');
      Add('AND reihe = "' +edit2.Text+'"');
      Add('AND Nr <= "' + edit3.text +'"');
Also einfach überall " und nich ' und bei Zahlen kann mann " schreiben oder auch nicht.

Nochwas bei Interbase ist ein Select * immer langsamer als ein Select Feld1,Feld2,Feld3 ...

Vieleicht hilft dir das ja weiter.
:coder:

MrSpock 24. Apr 2003 16:08

Hallo Cobra,

ich denke, dass es so nicht ganz funktioniert. Ich hatte ja extra nach den Feldtypen gefragt. Nr ist ein numerisches Feld, sodass die Abfrage mit einem Zahlenwert und nicht mit einem String stattfinden muss:

Delphi-Quellcode:
 Add('SELECT * ');
 Add('FROM kosten');
 Add('WHERE abteilung = "' + Edit1.Text + '"');
 Add('AND reihe = "' +edit2.Text+'"');
 Add('AND Nr <= ' + edit3.text);

Flo 24. Apr 2003 16:24

Also ich hab das jetzt nochmal probiert.

Jetzt sieht's so aus:
Delphi-Quellcode:
begin
WITH Query1 DO
    BEGIN
        Close;
        WITH SQL DO
          BEGIN
            Clear;
          Add('SELECT * ');
Add('FROM kosten');
Add('WHERE abteilung = "' + Edit1.Text + '"');
Add('AND reihe = "' +edit2.Text+'"');
Add('AND nr <= ' + edit3.text);
          END;
        Query1.Active := True;
        Open;
      END;;
      end;
Da kommt aber wieder:
Zitat:

'Keine Übereinstimmung der Typen im Ausdruck'

Cobra 24. Apr 2003 16:27

Hallo MrSpock,

Interbase macht das mit aber jetzt wo ich es lese hat sich der Fehler ja auf die Datentypen bezogen.

:thuimb: :hello:
Dann bin ich jetzt auch dafür das deine Lösung die richtige ist.

SQL ist eben nicht gleich SQL :wink:
:coder:

Cobra 24. Apr 2003 16:45

:wiejetzt: der Fehler kommt immernoch, dann gehen wir mal systematisch vor.

Mein erster Vorschlag wir fügen alles aufeinmal hinzu so können wir keine Leerzeichen vergessen.
so also:
Add('SELECT * FROM kosten.db WHERE abteilung = "' + Edit1.Text + '"'
+ ' AND reihe = "' +edit2.Text+'"'
+ ' AND nr <= ' + edit3.text);



Mein zweiter Vorschalg es muß doch eine Testconsole geben für die SQL wo wir diese prüfen können und den Fehlerpunkt bestimmen kann.

Machmal sind es kleine Fehler die eine große Wirkung haben.
:coder:

Flo 24. Apr 2003 17:49

Also jetzt kommt ungültiges Schlüsselwort in Zeile 2 (select)

Code:
Delphi-Quellcode:
WITH Query1 DO
    BEGIN
        Close;
        WITH SQL DO
          BEGIN
            Clear;
          Add('SELECT * ');
Add('SELECT * FROM kosten.db wHERE abteilung = "' + Edit1.Text + '"'
+ ' AND reihe = "' +edit2.Text+'"'
+ ' AND nummer <= ' + edit3.text);
          END;
        Query1.Active := True;
        Open;
      END;;
:roll: :roll: :roll:

MrSpock 24. Apr 2003 21:12

!
 
Hallo Flo,

na diese Fehlermeldung ist einfach. Du hast ja "SELECT * SELECT * FROM ..." erzeugt, da ist das 2-te SELECT fehl am Platz.

Also wenn die von dir angegebenen Feldtypen stimmen, dann versuch bitt mal folgendes:

Delphi-Quellcode:
Add('SELECT * ');
Add('FROM kosten');
Add('WHERE abteilung = ' +QuotedStr(Edit1.Text));
Add('AND reihe =' +QuotedStr(edit2.Text));
Add('AND Nr <= ' + edit3.text);
Falls es nicht funktioniert, muss einer der Feldtypen nicht korrekt sein.

[edit=MrSpock]PS: In Edit3 muss eine gültige Ziffernfolge stehen![/edit]

Flo 25. Apr 2003 14:39

Vorweg: Es funktioniert immer noch nicht :cry:

Hab nochmals alles durchgeguckt, aber alles ist korrekt.

Zitat:

'Keine Übereinstimmung der Typen im Ausdruck'
In Edit1 soll die Abteilung stehen......Beispiel: A1
In Edit2 soll die Reihe stehen..........Beispiel: R1
In Edit3 soll die Nummer stehen.........Beispiel: 1

Bin schon am Versweifeln :(

MrSpock 26. Apr 2003 20:41

Hallo Flo,

um ganz sicher zu gehen, habe ich den Originalcode wie folgt in ein kleines Programm gepackt:

Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
begin
   Query1.Close;
   with Query1.SQL do
  begin
     Clear;
     Add('SELECT * ');
      Add('FROM kosten');
      Add('WHERE abteilung = ' +QuotedStr(Edit1.Text));
      Add('AND reihe =' +QuotedStr(edit2.Text));
      Add('AND Nr <= ' + edit3.text);
   end;
  Query1.Open;
end;
Ich habe dazu eine Tabelle definiert, mit
Abteilung A 20
Reihe A 20
Nr I

... und es funktioniert, wenn man in Edit1 z.B. A1, in Edit2 R1 und schließlich in Edit3 5 schreibt, ohne Fehler.

Was für eine Datenbank nutzt du?
Heißt das 3. Feld Nr oder Nummer?

APP 27. Apr 2003 11:30

Hallo,
eine Anmerkung am Rande:

Wenn ich mit umfangreichen Queries arbeiten muß, öffne ich einen
(oder auch DEN) SQL-Explorer, mache einen Test-Alias oder benutze
auch schon mal die vorhendenen Demo-Aliase und schreibe meine
SQL-Statements in das SQL Fenster (natürlich angepasst und vereinfacht).

(Man kann den SQL-Explorer z.B. über das Menü Datenbank/Explorer oder
direkt beim TQuery1 auf dem Formular mit RechterMaus/Explorer im
Kontextmenü öffnen)

So habe ich immer den Überblick über die Feldnamen, Definitionen,
usw..., wenn das Statement dann funktioniert übertrage ich es einfach
in Delphi-Notation.

Flo 27. Apr 2003 17:15

Also...
@ MrSpock
Ich hab den Code nachmal in mein Programm kopiert und überprüft. Funktioniert aber immer noch nicht.
Zitat:

'Keine Übereinstimmung der Typen im Ausdruck'
Das dritte Felt heißt nr. Ich benutze eine Paradox7 Tabelle.

@ APP
Hab alles nochmal im DB-Explorer kontrolliert. Es stimmt alles.

MrSpock 27. Apr 2003 19:53

Hallo Flo,

wenn dein Programm nicht zu groß ist, kann ich dir nur noch anbieten, das Programm (und die Tabellen) einmal dem nächsten Posting anzuhängen oder mir zu schicken, dann kann ich dort noch einmal reinschauen.

Flo 28. Apr 2003 10:32

Nur die Unit, in der der Fehler ist ???

MrSpock 28. Apr 2003 10:47

Hallo Flo,

wenn diese Unit nicht auf andere Units zugreift (über die uses Klausel), dann genügt die Unit und die Tabellen. Benutzt du ein eigenes DataModule, dann solltest du das auch anhängen.

MrSpock 28. Apr 2003 19:22

Hallo Flo,

ich habe mir einmal deine Dateien angeschaut und den Fehler gefunden.

Das dritte Feld "Nr" ist kein Zahlenfeld! Es ist definiert als A 5 (alphanumerisch 5 Zeichen lang). Es gibt jetzt 2 Möglichkeiten:

Entweder du änderst den Typ des Feldes z.B. mit der Datenbankoberfläche in ein Integerfeld (I) oder zu änderst den Code in:

Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
begin
   Query1.Close;
   with Query1.SQL do
  begin
     Clear;
     Add('SELECT * ');
      Add('FROM kosten');
      Add('WHERE abteilung = ' +QuotedStr(Edit1.Text));
      Add('AND reihe =' +QuotedStr(edit2.Text));
      Add('AND Nr <= ' + QuotedStr(edit3.text));
   end;
  Query1.Open;
end;
Bei der 2. Lösung musst du jedoch beachten, dass bei Vergleichen mit >= oder <= die Reihenfolge der Zeichen im ASCII Code entscheidend ist.

Flo 29. Apr 2003 12:37

Hab die erste Lösung genommen und es hat geklappt :spin:

Aber wieso springt er denn nicht zum Datensatz ? Muss ich da noch was hinzufügen ???

MrSpock 29. Apr 2003 21:47

Hallo Flo,

in deinem Formular zeigst du ja den Inhalt der Tabelle an. Neben der Tabelle hast du jetzt eine Datenmenge mit einer Query (Abfrage) erstellt. Diese beiden Datenmengen haben aber nichts miteinander zu tun.

Wenn du willst, dass die Tabelle auf den gewünschten Satz zeigt, kannst du mit Locate arbeiten (siehe OH) und die Query komplett vergessen.

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  Table1.Locate('abteilung;reihe;grabstelle',
     VarArrayOf([Edit1.Text,
             Edit2.Text,
                  Edit3.Text]),[]);
end;

Flo 30. Apr 2003 15:37

Ohh....das tut mir jetzt leid :oops:
Hätte ich vielleicht vorher sagen bzw. schreiben sollen.
Klappt aber.

Vielen Dank nochmal an alle, die geholfen haben !!!


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