Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi SQL Abfrage - Datum zwischen X und Y (https://www.delphipraxis.net/140246-sql-abfrage-datum-zwischen-x-und-y.html)

Major1337 14. Sep 2009 12:52

Datenbank: Oracle • Zugriff über: ODAC

SQL Abfrage - Datum zwischen X und Y
 
Hi,

ich möchte über das eine Editfeld abfragen "Datum von" und mit dem anderen Editfeld "Datum bis" .
Mit welcher SQL Abfrage kann ich nun diese beiden Parmeter vergleichen und mir die Werte auslesen lassen?

Mfg
Major

Klaus01 14. Sep 2009 13:03

Re: SQL Abfrage - Datum zwischen X und Y
 
sollte das im Prinzip nicht in etwa so gehen:

SQL-Code:
select * from table where date > dateFrom and date < dateTo
Grüße
Klaus

mikhal 14. Sep 2009 13:04

Re: SQL Abfrage - Datum zwischen X und Y
 
Variante 1: datum between :wert1 and :wert2
Variante 2: datum >= :wert1 and datum <= :wert2

Denk bei den Vergleichen aber daran, dass der Datentyp DATE auch die Uhrzeit enthält. Zweckmäßigerweise solltest du den Nachkommateil mit TRUNC(datum) abschneiden.

Grüße
Mikhal

Major1337 14. Sep 2009 13:16

Re: SQL Abfrage - Datum zwischen X und Y
 
Delphi-Quellcode:
// DATE FROM
if DesEdit2.Text <> '' then

SmartQuery1.SQL.Add('');
end;


//DATE END;
if DesEdit3.Text <> '' then
begin

SmartQuery1.SQL.Add('');
end;


ICh habe ja zwei Felder in denen ich eine SQL-Abfrage machen muss und es kann auch vorkommen das man auch nur mal wissen will "Datum von" ohne die Angabe bis oder anderst herum.

DeddyH 14. Sep 2009 13:17

Re: SQL Abfrage - Datum zwischen X und Y
 
Dann baust Du Dir den SQL-String dynamisch zusammen und setzt die Parameter entsprechend.

mikhal 14. Sep 2009 13:24

Re: SQL Abfrage - Datum zwischen X und Y
 
ODAC stellt Macros zur Verfügung. Damit kannst du dir den Auswerteteil zusammensetzen:
SQL-Code:
  SELECT
    ...
  FROM
    TABELLE
  WHERE
    ...
    $DATUMVERGLEICH
in deinem Quelltext stellst du das Macro dann zusammen:

Delphi-Quellcode:
  ...
  if MySmartQuery.Active then
    MySmartQuery.Close;
  if DesEdit2.Text <> '' then
    MySmartQuery.MacroByName.Value = ' AND TRUNC(Datum) = ' + Trunc(StrToDate(DesEdit2.Text));
  ...
  MySmartQuery.Open;
Grüße
Mikhal

[edit=mkinzler]Code-Tags durch SQL und Delphi-Tag ersetzt Mfg, mkinzler[/edit]

Major1337 14. Sep 2009 13:35

Re: SQL Abfrage - Datum zwischen X und Y
 
gibt es da keine einfache Lösung ohne diese date (routine) ?
Wenn man z.B. jetzt alle IP Adressen herausfinden will die zwischen 232.18.147.53 und 288.92.141.55 liegen, wie würde man das denn machen?

fkerber 14. Sep 2009 14:48

Re: SQL Abfrage - Datum zwischen X und Y
 
Evtl. würde es sich anbieten, die IP-Adressen in einem anderen Format (z.B. als Integer) in der DB zu speichern.

mkinzler 14. Sep 2009 15:39

Re: SQL Abfrage - Datum zwischen X und Y
 
Als String sollten die Adressen auch zu vergleichen sein

DeddyH 14. Sep 2009 16:30

Re: SQL Abfrage - Datum zwischen X und Y
 
Aber ob man so alle "Zwischen-IPs" bekommt?

Medium 14. Sep 2009 17:01

Re: SQL Abfrage - Datum zwischen X und Y
 
Wenn jedes Byte mit führenden Nullen geschrieben ist ja, sonst wohl eher nein.

Major1337 15. Sep 2009 07:46

Re: SQL Abfrage - Datum zwischen X und Y
 
Die möglichen Beispiele die oben genannt worden sind wie beispielsweise mit Markos konnte ich nicht ganz nachvollziehen.
Ich zeige euch mal nochmal anhand meines Quellcodes wie es aussehen sollte.

Delphi-Quellcode:
if DateFromEdit.text <> '' then
    begin
     SmartQuery1.SQL.Add('{ DateFromEdit.Text bis ENDE} ');
     SmartQuery1.ParamByName('').AsString := DateFromEdit.Text;
    end;

  if DateUntilEdit.Text <> '' then
  begin
  SmartQuery1.SQL.Add('{DateFromEdit.Text bis DateUntilEdit.Text OR ANFANG bis DateUntilEdit.Text}');
  SmartQuery1.ParamByName('').asString := DateUntilEdit.Text;
jetzt bräuchte ich nur noch die richtige Syntax dafür, dass mein Compiler damit auch was anfangen kann.^^

Gruß
Major

mikhal 15. Sep 2009 12:14

Re: SQL Abfrage - Datum zwischen X und Y
 
Du mischst Delphi mit SQL: Kommentare werden in SQL mit '/*' und '*/' geklammert oder eine ganze Zeile mit '--' auskommentiert.

Grüße
Mikhal

Edit: Schreibfehler...

p80286 15. Sep 2009 14:30

Re: SQL Abfrage - Datum zwischen X und Y
 
Delphi-Quellcode:
if DateFromEdit.text <> '' then
begin
  if DateUntilEdit.Text <> '' then
  begin
    SmartQuery1.SQL.Add(' and fromdate>=:ANFANG and untildate<=:ENDE);
    SmartQuery1.ParamByName('ANFANG').asString := DateUntilEdit.Text;
    SmartQuery1.ParamByName('ENDE').asString := DateUntilEdit.Text;
  end
  else
  begin
    SmartQuery1.SQL.Add(' and fromdate>=:ANFANG ');
    SmartQuery1.ParamByName('ANFANG').asString := DateUntilEdit.Text;
  end;
je nachdem wie das abzufragende Feld heißt mußt Du fromdate und untildate durch die richtigen namen ersetzen.
und nach dieser Aktion darfst Du keine weiteren Veränderungen am SQL-Text vornehmen (soweit ich weiß!)
ggf. mußt Du die Generierung des SQL-Textes und die Parameterübergabe dann aufteilen.

ist das .asString erst gemeint??
das halte ich nicht für empfehlenswert da es ja viele unterschiedliche Möglichkeiten gibt ei Datum darzustellen. Einzig mit YYYYMMDD könnte man das halbwegs ordentlch machen.

Gruß
K-H

Mithrandir 15. Sep 2009 15:38

Re: SQL Abfrage - Datum zwischen X und Y
 
*hust*

Ich weiß nicht, aber wenn ich mit Kalenderdaten um mich schmeißen muss, dann bietet sich doch im GUI ein TDateTimePicker an und in der Datenbank ein (oder in diesem Falle zwei) Felder vom Typ "DATE". (So denn Oracle so einen Typen kennt...).

p80286 15. Sep 2009 16:07

Re: SQL Abfrage - Datum zwischen X und Y
 
@Daniel G

Naja der tDateTimepicker ist nicht jedermans Sache (ich bin da bei enem Anwender hochkant aus dem Büro geflogen) aber Du hast schon recht (oracle hat einen Datumstypen) so früh wie möglich auf Datumstypen gehen, damit's da keine Probleme gibt.

Gruß
K-H

mkinzler 15. Sep 2009 16:11

Re: SQL Abfrage - Datum zwischen X und Y
 
Das gilt grundsätzlich für alle Daten, wenn möglich die entsprechenden Typen verwenden. Mit dem Motto: "Ein String nimmt alles auf" fällt man schnell auf die Schnauze!

Mithrandir 15. Sep 2009 16:12

Re: SQL Abfrage - Datum zwischen X und Y
 
Zitat:

Zitat von p80286
(ich bin da bei enem Anwender hochkant aus dem Büro geflogen)

Ernsthaft? :shock: Naja, das aufpoppende Fensterchen kann man notfalls ja noch verstecken, oder man leitet sich da was eigenes ab, aber für Datumseingaben ist er eigentlich optimal und auch recht komfortabel. Aber User sind eh manchmal komisch...

p80286 15. Sep 2009 16:21

Re: SQL Abfrage - Datum zwischen X und Y
 
[OT]
na ja, nach alter Väter Sitte über die Tastatur.... (ist man halt so gewohnt)
und ich hatte die Eingabeüberprüfung an der Backe (Das wäre mal eine Aufgabenstellung für den Informatikunterricht!)
[/OT]

Gruß
K-H

Major1337 15. Sep 2009 17:12

Re: SQL Abfrage - Datum zwischen X und Y
 
@p80286

danke für deine Lösung aber ich muss nur ein Feld abfragen da gibts keine zwei unterschiedliche Namen, nur einen.
Kann von diesem PC aus nicht das Projekt pflegen, könntest du mir aber trotzdem schreiben ob man es so schreiben kann.


Delphi-Quellcode:
....
  SmartQuery1.SQL.Add(' and date >= :ANFANG and date <= :ENDE);
....
else
....
    SmartQuery1.SQL.Add(' and date >=:ANFANG ');
...

p80286 15. Sep 2009 17:25

Re: SQL Abfrage - Datum zwischen X und Y
 
Ich denke das ist korrekt, aber achte auf die Hochkommata!

Gruß
K-H

mkinzler 15. Sep 2009 17:59

Re: SQL Abfrage - Datum zwischen X und Y
 
date ist allerdings ein ungeschickter Feldbezeichner

Major1337 17. Sep 2009 07:59

Re: SQL Abfrage - Datum zwischen X und Y
 
Delphi-Quellcode:
 
if DateBeginSucheEdit.text <> '' then
begin
  if DateEndSucheEdit.Text <> '' then
  begin
    SmartQuery1.SQL.Add('and datum >= :ANFANG and datum <= :ENDE');
    SmartQuery1.ParamByName('ANFANG').asString := DateBeginSucheEdit.Text;
    SmartQuery1.ParamByName('ENDE').asString := DateEndSucheEdit.Text;
  end
  else
  begin
    SmartQuery1.SQL.Add('and datum >= :ANFANG');
    SmartQuery1.ParamByName('ANFANG').asString := DateBeginSucheEdit.Text;
  end;
end;


das ".asString" wurde ja eben schon angezweifelt, ich bekomme jetzt ein ORA Fehler das er das String nicht verträgt.
Gibt es eine andere Möglichkeit? und muss man in der OraSession auch das Datumformat angeben oder gilt das nur für den Timer?
Das Datum wird immer DD.MON.YYYY (17.09.2009) gespeichert.

mkinzler 17. Sep 2009 08:16

Re: SQL Abfrage - Datum zwischen X und Y
 
Versuch mal
Delphi-Quellcode:
SmartQuery1.ParamByName('ANFANG').Value := StrToDate(DateBeginSucheEdit.Text, Format);

Major1337 17. Sep 2009 08:24

Re: SQL Abfrage - Datum zwischen X und Y
 
[Pascal Fehler] Unit6.pas(101): E2250 Es gibt keine überladene Version von 'Format', die man mit diesen Argumenten aufrufen kann

DeddyH 17. Sep 2009 08:25

Re: SQL Abfrage - Datum zwischen X und Y
 
Du sollst da auch das Datumsformat eintragen.

Major1337 17. Sep 2009 08:28

Re: SQL Abfrage - Datum zwischen X und Y
 
mit var deklarieren ich hab in der OraSession bei Eigenschaften das Datenformat DD.MON.YYYY eingetragen.

EDIT Okay ich habs verstanden!

Major1337 17. Sep 2009 08:31

Re: SQL Abfrage - Datum zwischen X und Y
 
hab dieses Datenformat jetzt eingesetzt aber er unterstreicht es rot, wieso? => DD.MM.YYYY

EDIT: mit Hochkommata? :P

mkinzler 17. Sep 2009 08:33

Re: SQL Abfrage - Datum zwischen X und Y
 
Schau dir doch mal die Hilfe zu dieser Funktion an

Major1337 17. Sep 2009 08:47

Re: SQL Abfrage - Datum zwischen X und Y
 
Hey,

es funktioniert auch ohne das Datenformat anzugeben. ^^

mkinzler 17. Sep 2009 08:50

Re: SQL Abfrage - Datum zwischen X und Y
 
Ja aber nur, wenn das eingebene Format mit dem des Systems übereinstimmt.

Major1337 17. Sep 2009 09:06

Re: SQL Abfrage - Datum zwischen X und Y
 
ja, das Datumformat ist immer das selbe. Habe mich aber jetzt entschieden, wenn man nur ein Feld ausfüllt wird genau das Datum angezeigt was man eingegeben hat. Das klappt jetzt allerdings nur mit dem Feld DateBegin.. wie bekomme ich den jetzt da noch den Fall unter wenn er nur DateEnd eingibt ? o.O.



Delphi-Quellcode:
  if DateBeginSucheEdit.text <> '' then
begin
  if DateEndSucheEdit.Text <> '' then
  begin
    SmartQuery1.SQL.Add('and datum >= :ANFANG and datum <= :ENDE');
    SmartQuery1.ParamByName('ANFANG').Value := StrToDate(DateBeginSucheEdit.Text);
    SmartQuery1.ParamByName('ENDE').Value := StrToDate(DateEndSucheEdit.Text);
  end
  else
  begin
    SmartQuery1.SQL.Add('and datum = :ANFANG');
    DateEndSucheEdit.Text := DateBeginSucheEdit.Text;
    SmartQuery1.ParamByName('ANFANG').Value := StrToDate(DateBeginSucheEdit.Text);
  end
end;

p80286 17. Sep 2009 09:23

Re: SQL Abfrage - Datum zwischen X und Y
 
Ähm wie ist die Frage gemeint?
Delphi-Quellcode:
if DateBeginSucheEdit.text <> '' then
begin
  ....
end;
Wenn keine Eingabe in DateBeginSucheEdit dann keine Verarbeitung!
Pack vielleicht noch eine Messagebox in den else-Zweig "Bitte Anfangsdatum eingeben!"

Gruß
K-H

Major1337 17. Sep 2009 09:32

Re: SQL Abfrage - Datum zwischen X und Y
 
Wenn DateBeginEdit nicht ausgefüllt ist aber DateEndEdit soll er nur nach dem Datum suchen was in DateEndEdit eingeben ist und dann gleichzeitig in DateBeginEdit das Datum von DateEndEdit eintragen umgekehrt geht es ja schon.

Major1337 17. Sep 2009 09:43

Re: SQL Abfrage - Datum zwischen X und Y
 
Mein Vorschlag wäre:

Delphi-Quellcode:
if DateBeginSucheEdit.text <> '' then
SmartQuery1.SQL.Add('and datum = :ANFANG');
DateEndSucheEdit.Text := DateBeginSucheEdit.Text;
SmartQuery1.ParamByName('ANFANG').Value := StrToDate(DateBeginSucheEdit.Text);
begin
  if DateEndSucheEdit.Text <> '' then
  begin
    SmartQuery1.SQL.Add('and datum >= :ANFANG and datum <= :ENDE');
    SmartQuery1.ParamByName('ANFANG').Value := StrToDate(DateBeginSucheEdit.Text);
    SmartQuery1.ParamByName('ENDE').Value := StrToDate(DateEndSucheEdit.Text);
  end
  else
  begin
    SmartQuery1.SQL.Add('and datum = :ENDE');
    DateBeginSucheEdit.Text := DateEndSucheEdit.Text;
    SmartQuery1.ParamByName('ENDE').Value := StrToDate(DateEndSucheEdit.Text);

  end
end;
klappt aber nicht ^^

DeddyH 17. Sep 2009 09:58

Re: SQL Abfrage - Datum zwischen X und Y
 
Erstell Dir doch einmal ein Struktogramm oder einen PAP ;)

Major1337 17. Sep 2009 10:31

Re: SQL Abfrage - Datum zwischen X und Y
 
@DeddyH

ich weiß doch wie das Programm ablaufen soll da brauch ich keinen Programmablauf o.O.


Datum von: (DateBeginSucheEdit)

Datum bis: (DateEndSucheEdit)

1. Fall
Eingabe von DateBeginSucheEdit; DateEndSucheEdit keine Eingabe
=> Zeigt alle Datensätze mit Datum von Eingabe DatebeginSucheEdit an,
DateEndSucheEdit bekommt Caption von Eingabe DateBeginSucheEdit

2. Fall
2. Eingabe von DateEndSuchEdit; DateBeginSucheEdit keine Eingabe
=> Zeigt alle Datensätze mit Datum von Eingabe DatebeginSucheEdit an,
DateBeginSucheEdit bekommt Caption von Eingabe DateEndSucheEdit

3. Fall
3. Eingabe von DateBeginSucheEdit und DateEndSucheEdit
=> Zeigt alle Datensätze an die zwischen DateBeginSuchEdit und DateEndSucheEdit stehen



Delphi-Quellcode:
if DateBeginSucheEdit.text <> '' then
begin
  if DateEndSucheEdit.Text <> '' then
  begin
    SmartQuery1.SQL.Add('and datum >= :ANFANG and datum <= :ENDE');
    SmartQuery1.ParamByName('ANFANG').Value := StrToDate(DateBeginSucheEdit.Text);
    SmartQuery1.ParamByName('ENDE').Value := StrToDate(DateEndSucheEdit.Text);
  end
  else
  begin
    SmartQuery1.SQL.Add('and datum = :ANFANG');
    DateEndSucheEdit.Text := DateBeginSucheEdit.Text;
    SmartQuery1.ParamByName('ANFANG').Value := StrToDate(DateBeginSucheEdit.Text);
  end
end;

  SmartQuery1.open;
end;

Dieser Quellcode zeigt mir Fall 1. und 3. an.. ich weiß nur nicht wie ich den 2. Fall unterbekomme.

DeddyH 17. Sep 2009 10:36

Re: SQL Abfrage - Datum zwischen X und Y
 
Genau deshalb mein Vorschlag mit dem PAP.
Delphi-Quellcode:
if DateBeginSucheEdit.text <> '' then
  begin
    if DateEndSucheEdit.Text <> '' then
      begin
        //...
      end
    else
      begin
        //...
      end
  end
else
  begin
    if DateEndSucheEdit.Text <> '' then
      begin
        //...
      end
    else
      begin
        //...
      end
  end;

p80286 17. Sep 2009 13:14

Re: SQL Abfrage - Datum zwischen X und Y
 
Zitat:

Zitat von Major1337
@DeddyH

ich weiß doch wie das Programm ablaufen soll da brauch ich keinen Programmablauf o.O.


Datum von: (DateBeginSucheEdit)

Datum bis: (DateEndSucheEdit)

1. Fall
Eingabe von DateBeginSucheEdit; DateEndSucheEdit keine Eingabe
=> Zeigt alle Datensätze mit Datum von Eingabe DatebeginSucheEdit an,
DateEndSucheEdit bekommt Caption von Eingabe DateBeginSucheEdit

2. Fall
2. Eingabe von DateEndSuchEdit; DateBeginSucheEdit keine Eingabe
=> Zeigt alle Datensätze mit Datum von Eingabe DatebeginSucheEdit an,
DateBeginSucheEdit bekommt Caption von Eingabe DateEndSucheEdit

3. Fall
3. Eingabe von DateBeginSucheEdit und DateEndSucheEdit
=> Zeigt alle Datensätze an die zwischen DateBeginSuchEdit und DateEndSucheEdit stehen

Mir scheint das 1=2 , daher ist das Problem doch gelöst?

Aber im Ernst:
Du hast verschiedene Möglichkeiten daran zu gehen:
a) Du machst die Verarbeitung von einer Eingabe abhängig
b) Du machst die Verarbeitung von einem Inhalt abhängig

ich vermute es geht Dir um b). Dann solltest Du zunächst die Inhalte überprüfen und so "hinbiegen" wie Du sie benötigst. Dann erst startest Du die Abfrage mit den Inhalten der Edit-Felder, bzw. den Inhalten die Du daraus generiert hast.
Das könnte so aussehen:
Code:
wenn BeginSuche = leer dann BeginSuche=EndSuche // Suche nach einem Tag (EndSuche)

Wenn BeginSuche nicht leer
und
Wenn Endsuche nicht leer dann ...              // Suche mit Anfang und Ende

ansonsten

Wenn BeginSuche nicht leer dann ....          // Suche mit Anfang ohne Ende
ansonsten Fehlerausgabe                       // Anfang und Ende sind leer
Wenn Du die nicht gefülleten Felder mit Standard-Werten füllen willst, dann sieht das etwas anders aus, aber das Prinzip bleibt das gleiche.

Und der Vorschlag von Detlef ist in keinster Weise ehrenrührig. Es ist oft ungemein hilfreich wenn man den Überblick verloren hat sich einen PAP oder ähnliches zu erstellen, da sich dann oft die notwendige Distanz einstellt.

Gruß
K-H


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