Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Umstellung auf SQL-Filterung (https://www.delphipraxis.net/181165-umstellung-auf-sql-filterung.html)

Crowbar 21. Jul 2014 14:06

Datenbank: dbf • Version: x • Zugriff über: TTable, TQuery, TDatasource

Umstellung auf SQL-Filterung
 
Hallo,

ich bin gerade dabei mein kleines Rechnungsprogramm von TTable nach TQuery (inkl. SQL-Befehle) umzuschreiben.

In meinem Rechnungsprogramm sollen die Rechnungen angezeigt werden, dessen Buchnungsdatum (Tabellenfeld "RESTELLUNG") gegenüber dem aktuellen Datum größer-gleich der Mahntage (z.B. 14 Tage) sind.
Im Prinzip sollen alle erstellten Rechnungen, die vor 14 Tagen erstellt wurden und kein Rechnungseingangsdatum besitzen, angezeigt werden (= für Mahnungen).

Diesen "OnFilterRecord"-Event (TTable) habe ich bisher wie folgt programmiert und läuft auch so wie gewollt:

Delphi-Quellcode:
...
MahnTage:=14;
...
{ Differenz der Tage ermitteln }
Function TMainForm.DaysBetween(const d1,d2: TDateTime) : Integer;
begin
  Result:=Trunc(d1)-Trunc(d2);
end;
...

Procedure TMainForm.DBBuchungTableFilterRecord(DataSet: TDataSet; var Accept: Boolean);
Var
 Tage : Integer;

begin
  if (FilterFeld = 'MAHNUNG') then
   begin
     if ((DBBuchungTable.FieldByName('REEINGANG').AsString = '') and (DBBuchungTable.FieldByName('KATEGORIE').AsWideString = 'Einnahmen') and not (DBBuchungTable.FieldByName('RESTELLUNG').AsString = '') then
      begin
        Tage:=DaysBetween(Now,StrToDate(DBBuchungSQLQuery.FieldByName('RESTELLUNG').AsString));
        Accept:=(Tage >= MahnTage);
       end;
   end;
end;
...
Nun möchte ich diese Abfrage/Filterung per SQL lösen.

Filterbedingungen:
Nur die Rechnungen der KATEGORIE "Einnahmen" anzeigen, dessen Datum im Feld "RESTELLUNG" größer-gleich der Mahntage (z.B. 14 Tage) sind und das Datum für Rechnungseingang (Feld "REEINGANG") leer ist.
Zusätzlich ... das Feld "RESTELLUNG" darf auch nicht leer sein.

Zusammengefaßt:

- im Feld "KATEGORIE" => muss "Einnahmen" stehen
und
- das Feld "RESTELLUNG" darf nicht leer sein
und
- das Feld "REEINGANG" muss leer sein
und
- das Datum im Feld "RESTELLUNG" muss größer-gleich 14 Tage vor dem aktuellen Datum sein

Irgendwie stehe ich jetzt hier, durch die vielen "Bedingungsabfragen", auf dem Schlauch. :roll:

Delphi-Quellcode:
SQLText:='SELECT * FROM Buchung WHERE KATEGORIE ="Einnahmen" AND REEINGANG = '+QuotedStr('')+' AND RESTELLUNG >=... ???

DeddyH 21. Jul 2014 14:16

AW: Umstellung auf SQL-Filterung
 
Ist RESTELLUNG ein Stringfeld?

Crowbar 21. Jul 2014 14:20

AW: Umstellung auf SQL-Filterung
 
Zitat:

Zitat von DeddyH (Beitrag 1266199)
Ist RESTELLUNG ein Stringfeld?

Nein, ein DATE Feld.

KATEGORIE Feld string
RESTELLUNG Feld date
REEINGANG Feld date

baumina 21. Jul 2014 14:30

AW: Umstellung auf SQL-Filterung
 
SQL-Code:
WHERE KATEGORIE = 'Einnahmen'
AND RESTELLUNG is not null
AND REEINGANG is null
AND DATEDIFF(day, NOW(), RESTELLUNG) >= 14

jobo 21. Jul 2014 14:31

AW: Umstellung auf SQL-Filterung
 
Eine Prüfung auf "leer" machst Du am besten mit
Code:
 where ..
   [myDateField] is null
   ..

himitsu 21. Jul 2014 14:35

AW: Umstellung auf SQL-Filterung
 
Zitat:

Zitat von Crowbar (Beitrag 1266200)
Zitat:

Zitat von DeddyH (Beitrag 1266199)
Ist RESTELLUNG ein Stringfeld?

Nein, ein DATE Feld.

Aber warum behandelst du es dann wie Eines? :zwinker:

Delphi-Quellcode:
Tage := DaysBetween(Now, DBBuchungSQLQuery.FieldByName('RESTELLUNG').AsDataTime);


Jetzt nur noch in der entsprechenden DBMS-Doku nachsehen, wie sich die Funktion nennt, mit welcher man Datumsdifferenzen ausrechnen kann.


Und das
Delphi-Quellcode:
DBBuchungTable.FieldByName('RESTELLUNG').AsString = ''
sollte wohl auch ein
Delphi-Quellcode:
DBBuchungTable.FieldByName('RESTELLUNG').IsNull
darstellen.

Crowbar 21. Jul 2014 14:58

AW: Umstellung auf SQL-Filterung
 
Zitat:

Zitat von himitsu (Beitrag 1266210)
Zitat:

Zitat von Crowbar (Beitrag 1266200)
Zitat:

Zitat von DeddyH (Beitrag 1266199)
Ist RESTELLUNG ein Stringfeld?

Nein, ein DATE Feld.

Aber warum behandelst du es dann wie Eines? :zwinker:

Delphi-Quellcode:
Tage := DaysBetween(Now, DBBuchungSQLQuery.FieldByName('RESTELLUNG').AsDataTime);


Jetzt nur noch in der entsprechenden DBMS-Doku nachsehen, wie sich die Funktion nennt, mit welcher man Datumsdifferenzen ausrechnen kann.


Und das
Delphi-Quellcode:
DBBuchungTable.FieldByName('RESTELLUNG').AsString = ''
sollte wohl auch ein
Delphi-Quellcode:
DBBuchungTable.FieldByName('RESTELLUNG').IsNull
darstellen.

... das ist alles einwenig unsauber programmiert ... deswegen auch meine Überarbeitung und gleichzeitiges Umsetzen auf SQL.

Zitat:

Zitat von baumina (Beitrag 1266205)
SQL-Code:
WHERE KATEGORIE = 'Einnahmen'
AND RESTELLUNG is not null
AND REEINGANG is null
AND DATEDIFF(day, NOW(), RESTELLUNG) >= 14

... Danke, das war schon fast die Lösung.
SQL-Code:
WHERE KATEGORIE = "Einnahmen" AND RESTELLUNG is not null AND REEINGANG is null
Dieser SQL-Befehl klappt wunderbar, natürlich ohne diese 14 Tage-Berücksichtigung.

Sobald ich aber den gesamten Befehl benutze:

SQL-Code:
WHERE KATEGORIE = "Einnahmen" AND RESTELLUNG is not null AND REEINGANG is null AND DATEDIFF(day, NOW(), RESTELLUNG) >= 14
... erhalte ich eine Fehlermeldung, die heißt:

...Boolean expression expectedt, but 'DATEDIFF' found..."

DeddyH 21. Jul 2014 15:00

AW: Umstellung auf SQL-Filterung
 
Deswegen sollst Du ja in die Doku zu Deiner DB schauen, welche Datumsfunktionen es da gibt. Was ist das denn: dBase, FoxPro?

Crowbar 21. Jul 2014 15:06

AW: Umstellung auf SQL-Filterung
 
Zitat:

Zitat von DeddyH (Beitrag 1266213)
Deswegen sollst Du ja in die Doku zu Deiner DB schauen, welche Datumsfunktionen es da gibt. Was ist das denn: dBase, FoxPro?

Zum Austesten, ob alles so funktioniert wie ich es mir vorstelle, benutze ich derzeitig die Trialversion von "Absolute Database".
Hier scheint es den Befehl "DATEDIFF" nicht zu geben.

DeddyH 21. Jul 2014 15:24

AW: Umstellung auf SQL-Filterung
 
Scheint so. Ich konnte auf die Schnelle keine Übersicht der enthaltenen Funktionen finden, vielleicht ist es das Beste, das Datum am Client zu errechnen und als SQL-Parameter zu übergeben.

mkinzler 21. Jul 2014 15:43

AW: Umstellung auf SQL-Filterung
 
Recht übersichtlich
Zitat:

Zitat von Datumsfunktionen
Function
Description

CURRENT_DATE
Returns the current date

CURRENT_TIME
Returns the current time

CURRENT_TIMESTAMP
Returns the current local date and local time as a timestamp value

NOW
Returns current date and time as a timestamp value

SYSDATE
Returns current date and time as a timestamp value

TOSTRING
Converts date and time to string

TODATE
Converts string to date and time

EXTRACT
Extracts datepart component from datetime value as INTEGER


p80286 21. Jul 2014 16:06

AW: Umstellung auf SQL-Filterung
 
Unter Umständen geht es ja auch so
Zitat:

AND NOW()-RESTELLUNG >= 14
wobei 14 naürlich durch den Timestamp-wert für 14 Tage ersetzt werden muß

Gruß
K-H

Crowbar 21. Jul 2014 16:19

AW: Umstellung auf SQL-Filterung
 
Zitat:

Zitat von p80286 (Beitrag 1266223)
Unter Umständen geht es ja auch so
Zitat:

AND NOW()-RESTELLUNG >= 14
wobei 14 naürlich durch den Timestamp-wert für 14 Tage ersetzt werden muß

Gruß
K-H

Aus irgendeinen Grund benötige ich garkeinen Timestamp-Wert für die "14".
Mit dem SQL-Befehl:
SQL-Code:
SELECT * FROM Buchung WHERE KATEGORIE = "Einnahmen" AND RESTELLUNG is not null AND REEINGANG is null AND (NOW-RESTELLUNG > 14)
klappt nun alles wie gewollt. :)
Vielen Dank an alle ... nun konnte ich wieder mein kleines SQL-Wissen erweitern.


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