Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Filtern in einer Datenbank (https://www.delphipraxis.net/62715-filtern-einer-datenbank.html)

Surrounder 8. Feb 2006 15:19

Datenbank: FlashFiler • Version: 2.13 • Zugriff über: Datasource / Query

Filtern in einer Datenbank
 
Hallo Forum,

ich denke ich hab da ein Anfängerproblem, hab schon viel gelesen weiss aber nicht recht nach was ich suchen soll um eine Lösung zu finden, vielleicht gibt es ja auch keine...

Ich habe zwei Tabellen, eine mit Welleninformationen und eine mit den zugehörigen Lagerstellen zu den Wellen. Bei den Welleninformationen stehen so Dinge wie Datum und Uhrzeit usw. der Primärschlüssel ist ein AutoInc Wert den ich in eine Spalte der Lagerstellen schreibe damit ich die Beziehung herstellen kann.

So weit klappt das auch, wenn ich ein Grid habe in dem ich die Welleninformationen anzeige dann kann ich ein zweites Grid setzen indem ich dann automatisch die zugehörigen Lagerstellen der selektierten Welle angezeigt bekomme. So weit so gut.

Jetzt würde ich gerne Filtern. Was ich dabei tun möchte ist z.B. mit alle Wellen von einem bestimmten Datum an zu zeigen, oder die eben ein bestimmtes anderes Kriterium erfüllen das ich bei den Welleninformationen gespeichert habe. Nur wie bekomme ich jetzt die zugehörigen Lagerstellen heraus?

Ich hatte das bisher so gelöst, ich habe mir eine MemTabel erzeugt und der die gleichen Spalten wie der Wellentabelle gegeben. Dann habe ich Programmtechnisch alle Einträge im Grid mit den Welleninformationen durchsteppt und jeweils die Lager dann in diese MemTabel kopiert. Ziel ist es eben alle Lagerstellen dann zu haben, und dort dann wieder Filtern zu können, z.B. nach Lagerstelle 2 oder nach dem Durchmesser etc. Das funktioniert auch, ist aber langsam, sehr langsam.

Deshalb dachte ich, ich versuche das mal mit SQL, und hab mir eine Query gesetzt, was auch wesentlich schneller ist wenn ich viele Datensätzte habe ( zumindest ohne Filterung ), nur weiss ich nicht wie ich das machen soll wenn ich jetzt den Filter will

Also z.B. Ich möchte alle Wellen haben die vom 07.02.2006 sind, dann setze ich in der Tabelle mit den Welleninformationen den Filter auf das Datum, nur wie bekomme ich jetzt die zugehörigen Lagerstellen? Ich müsste ja jetzt hergehen und von allen Welleninformationen den AutoIndex Wert ermitteln, und nach allen die ich ermittelt habe wieder die Lagerstellen durchsuchen!?

Kann mir jemand auf die Sprünge helfen, mach ich da einen Denkfehler oder geht das wirklich nicht oder nichtt anderst? :wiejetzt:

Wie gesagt bin eigentlich DB Anfänger, also seid gnädig, bin dankbar über jeden Tip.

Phistev 8. Feb 2006 15:47

Re: Filtern in einer Datenbank
 
Informier dich mal über die WHERE-Klausel, JOIN könnte auch nicht schaden

Surrounder 8. Feb 2006 16:16

Re: Filtern in einer Datenbank
 
Ok, danke das hab ich versucht, aber villeicht hab ich nicht weit genug gedacht. Wenn ich jetzt z.B. auf alle Wellen vom 07.02.2006 gefiltert habe ( im cxGrid von devExpress ) dann habe ich von 10000 Wellen noch 300 im Gird. Jede dieser Wellen hat jetzt z.B. 15 Lagerstellen. Diese Lagerstellen würde ich jetzt gerne alle in einem weitere Grid anzeigen, um darin wieder zu Filtern, z.B nach Lagerstelle 2

Nur das ist mir mit WHERE und JOIN auch nicht ganz klar. Ich könnte jetzt sagen

Delphi-Quellcode:
      with DM1.ffQuery2 do begin
         Close();
         with SQL do begin
            Clear;
            Add( 'SELECT * FROM WellenInformation ' );
            s := 'WHERE ' + cxGrid1DBTableView1.DataController.Filter.FilterText;
            Add( s );
         end;
         Open();
      end;

      with DM1.ffQuery1 do begin
         Close();
         with SQL do begin
            Clear;
            Add( 'SELECT * FROM LagerStellen, ffQuery2 ');
            s := 'WHERE MessDatLager.WLfdNr = ffQuery2.LfdNr';
            Add( s );
         end;
         Open();
      end;
nur das klappt so nicht weil ich wohl keine Query in eine FROM Zeile nehmen kann / darf. Ich bin mir aber auch nicht sicher ob da überhaupt das rauskommen würde was ich möchte, denn wenn ich wie hier jetzte 300 Wellen habe, dann habe ich ja 300 verschiedene LfdNr. LfdNr ist bei mir der AutoInx Wert der in der WellenInformation steht und den ich in die Lagerinformationen schreibe, anhand dem ich dann die Bezeiehung herstelle

marabu 8. Feb 2006 17:02

Re: Filtern in einer Datenbank
 
Hallo.

Deine erste Query hast du ja schon hinbekommen:

SQL-Code:
select * 
from WellenInformationen
where :filterexpr
order by :wsort
Wenn die zweite Query alle Lagerstellen der Wellen aus der ersten Query enthalten soll, dann müsste sie etwa so aussehen:

SQL-Code:
select * 
from LagerStellen
where WLfdNr in (
  select lfdnr
  from WellenInformationen
  where :filterexpr )
order by :lsort
Der Parameter :filterexpr muss dann mindestens den Filter-Ausdruck enthalten, der auch für die erste Query verwendet wurde.

Grüße vom marabu

Hansa 8. Feb 2006 17:48

Re: Filtern in einer Datenbank
 
Du hast irgendwelche Wellen und willst wissen wo die sind ?

SQL-Code:
select * from welle where welle.id_lager= :ID_lager
Das listet dir auf, welche Wellen in einem bestimmten Lager sind. Wenn Du wissen willst, wo überall ein bestimmter Wellentyp im Lager ist :

SQL-Code:
select w.*, l.* from welle w, lager l where w.id_lager = l.id order by lager.nr
Aber ohne Gewähr ! Probiere mal aus. :mrgreen:

Jelly 8. Feb 2006 18:10

Re: Filtern in einer Datenbank
 
Da eine Welle wohl in einem Lager liegt, würde ich den Fremdschlüssel in die Wellen-Tabelle legen, und nicht umgekehrt.

Hansa 8. Feb 2006 23:20

Re: Filtern in einer Datenbank
 
Davon ging ich auch aus :

SQL-Code:
w.id_lager = l.id
Jede Welle liegt irgendwo im Lager rum, aber wo ist sie nur ? :mrgreen:

Bin hierbei von folgenden Datenstrukturen ausgegangen :

SQL-Code:
CREATE TABLE LAGER (
  ID integer,
  NR integer,
....

CREATE TABLE WELLE (
  ID integer,
  ID_LAGER integer, /* FK auf die ID des Lagerortes */
  NR integer,
...
Wie sehen denn die Tabellen bisher überhaupt aus ? :shock:

Surrounder 9. Feb 2006 06:56

Re: Filtern in einer Datenbank
 
Zitat:

Zitat von Jelly
Da eine Welle wohl in einem Lager liegt, würde ich den Fremdschlüssel in die Wellen-Tabelle legen, und nicht umgekehrt.

Nein es ist genau umgekehrt, eine Welle ( z.B. Kurbelwelle ) besitzt mehrere Lagerstellen.

Zitat:

Zitat von Hansa
Davon ging ich auch aus :

SQL-Code:
w.id_lager = l.id
Jede Welle liegt irgendwo im Lager rum, aber wo ist sie nur ? :mrgreen:

Bin hierbei von folgenden Datenstrukturen ausgegangen :

SQL-Code:
CREATE TABLE LAGER (
  ID integer,
  NR integer,
....

CREATE TABLE WELLE (
  ID integer,
  ID_LAGER integer, /* FK auf die ID des Lagerortes */
  NR integer,
...
Wie sehen denn die Tabellen bisher überhaupt aus ? :shock:

Ich hatte doch den Aufbau in meinem ersten Post beschrieben, ich wollte nicht alle Felder eintragen. Es ist genau anderst herum wie in deiner Datenstruktur

TABLE WellenInformation
ID AUTOINC
...

TABLE Lagerstellen
ID AUTOINC
WTypIdx Integer /* hier steht die ID der Welle zu der die Lagerstelle gehört
...

Surrounder 9. Feb 2006 07:30

Re: Filtern in einer Datenbank
 
Zitat:

Zitat von marabu
Hallo.

Deine erste Query hast du ja schon hinbekommen:

SQL-Code:
select * 
from WellenInformationen
where :filterexpr
order by :wsort
Wenn die zweite Query alle Lagerstellen der Wellen aus der ersten Query enthalten soll, dann müsste sie etwa so aussehen:

SQL-Code:
select * 
from LagerStellen
where WLfdNr in (
  select lfdnr
  from WellenInformationen
  where :filterexpr )
order by :lsort
Der Parameter :filterexpr muss dann mindestens den Filter-Ausdruck enthalten, der auch für die erste Query verwendet wurde.

Grüße vom marabu

Danke für den Tip, das hat mir geholfen. Ich hab es jetzt in einem Query gemacht und ich denke das sollte klappen. Vielleicht könnt ihr mit einen Tip geben falls jemand daran etwas auffällt.

SQL-Code:

      with DM1.ffQuery2 do begin
         Close();
         with SQL do begin
            Clear;
            Add( 'SELECT * FROM WellenInformationen, Lagerdaten ' );
            s := 'WHERE WellenInformationen.Idx = Lagerdaten.WiIdx';
            if cxGrid1DBTableView1.DataController.Filter.FilterText <> '' then begin
               s := s + ' AND ' + cxGrid1DBTableView1.DataController.Filter.FilterText;
            end;
            Add( s );
         end;
         Open();
      end;
Die erste Query brauche ich glaub gar nicht weil das cxgrid mir das ja direkt anzeigt, die müsste ich wohl nur selber machen wenn ich das Grid in den GridMode schalten würde.

Ein Problem habe ich noch. Ich lass mir ja den FilterText von meinem cxGrid direkt zurück geben, den ich dann direkt als SQL Statement einfüge. Das geht bei allen Feldern außer bei meinem Datumsfeld. Das Feld ist vom Typ "SysTools Date", muss ich da was beachten? Ich bekomme als Meldung immer einen Type mismatch.

Beim Feld "SysTools Time" funktionierts ohen Probleme

Surrounder 9. Feb 2006 08:28

Re: Filtern in einer Datenbank
 
kann es sein dass das an meinem Datumsformat liegt? Ich gebe im SQL Statement als Datumsformat '09.02.2006' an, so sehe ich das Datum eigentlich auch in der Tabelle aber trotzdem kommt es zur Exception

marabu 9. Feb 2006 08:42

Re: Filtern in einer Datenbank
 
Du solltest Parameter verwenden, wie ich es in meinem SQL-Code angedeutet habe, dann umgehst du die Probleme.

Wenn die direkte Verwendung von DateTime-Werten als Parameter-Wert nicht funktionieren sollte, dann verwende String-Literale:

SQL-Code:
'... WHERE datum = DATE ' + QuotedStr(DateToStr(DeinDatum));
marabu

Surrounder 9. Feb 2006 09:08

Re: Filtern in einer Datenbank
 
Zitat:

Zitat von marabu
Du solltest Parameter verwenden, wie ich es in meinem SQL-Code angedeutet habe, dann umgehst du die Probleme.

Wenn die direkte Verwendung von DateTime-Werten als Parameter-Wert nicht funktionieren sollte, dann verwende String-Literale:

SQL-Code:
'... WHERE datum = DATE ' + QuotedStr(DateToStr(DeinDatum));
marabu

das hatte ich auch versucht, aber das ändert nichts.

SQL-Code:

Add( 'SELECT * FROM WellenInformation WHERE gamdate = ' + QuotedStr(DateToStr( date ));
führt ebenfalls zu einer Exception mit "type mismatch", ich glaub ich hab schon alle Datumsformate durch getestet, nur keines funktioniert. Wenn ich in der Tabelle einen Filter setzte auf "gamdate=08.02.2006" das geht :wall:

marabu 9. Feb 2006 10:02

Re: Filtern in einer Datenbank
 
Ich habe keine Erfahrung im Umgang mit FlashFiler, aber der Dokumentation glaubte ich zu entnehmen, dass ein Datums-Literal im SQL-Statement aus der Literal-Konstante DATE und einem String-Literal zu bilden ist - wie in meinem Beispiel. Du lässt das Schlüsselwort DATE einfach weg ...

marabu

Surrounder 9. Feb 2006 10:32

Re: Filtern in einer Datenbank
 
Zitat:

Zitat von marabu
Ich habe keine Erfahrung im Umgang mit FlashFiler, aber der Dokumentation glaubte ich zu entnehmen, dass ein Datums-Literal im SQL-Statement aus der Literal-Konstante DATE und einem String-Literal zu bilden ist - wie in meinem Beispiel. Du lässt das Schlüsselwort DATE einfach weg ...

marabu

Das verstehe ich jetzt nicht ganz wie Du das gemeint hast. Meinst Du ich muss noch irgend einen Formatstring angeben in dem SQL Statment?

Wenn ich das von hand versucht hatte dann habe ich bisher das eingegeben:

SQL-Code:
Add( 'SELECT * FROM WellenInformation WHERE gamdate = ''08.02.2006''' )
oder hab ich dich falsch verstanden?

marabu 9. Feb 2006 11:11

Re: Filtern in einer Datenbank
 
Wenn es so funktioniert ist es gut so. Ich hatte in der Dokumentation gelesen:

Zitat:

<date literal> = DATE <string literal>
Daraus habe ich geschlossen, dass dein SQL-Statement so aussehen muss:

SQL-Code:
Add( 'SELECT * FROM WellenInformation WHERE gamdate = DATE ''08.02.2006''' )
marabu

Surrounder 9. Feb 2006 11:43

Re: Filtern in einer Datenbank
 
:duck: du hast recht, in meinem Handbuch ist das nicht beschrieben, aber ich hab mir gerade die aktuellste Doku im Internet gesucht und da steht das mit dem Literal Date drinnen.

Jetzt bekomme ich nur noch eine "Syntax Error in Date Literal" :gruebel:

Aber ich komme meinem Ziel näher ;-)

Edit:

SQL-Code:

Add( 'SELECT * FROM WellenInformation, Lagerstellen WHERE WellenInformation.Idx= Lagerstellen.WiIdx AND gamdate = DATE ' + QuotedStr(DateToStr( date ));;
Noch wer eine Idee?

So soll es laut Doku aussehen

<string literal< = ' [/ <noQuote> | '' } ... ]' :?:

Surrounder 9. Feb 2006 12:05

Re: Filtern in einer Datenbank
 
:bounce2: ich habs, die verwenden folgendes Datumsformat '2006-02-08'

Danke für deine Hilfe Marabu


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