Entwickler-Ecke

Datenbanken - Sql halbrichtig?


D. Annies - So 29.01.12 09:47
Titel: Sql halbrichtig?
Hi, Delpher,

ich habe den folgenden Code, der "halbrichtig" funktioniert:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
  Tg := strtoint(copy(maskedit1.editText,1,2));                                   // + '%%'; ?
  Mo := strtoint(copy(maskedit1.editText,4,2));
  if (tg >= 10and (mo >= 10then TAG_MON := inttostr(Tg) +'.' + inttostr(Mo) +'.' + '%'
  else
  if (tg >= 10and (mo <  10then  TAG_MON := inttostr(Tg) +'.' + '0' + inttostr(Mo) + '.' + '%'
  else
  if (tg <  10and (mo >= 10then  TAG_MON := '0' + inttostr(Tg) +'.' + inttostr(Mo) + '.' + '%'
  else
  if (tg <  10and (mo <  10then  TAG_MON := '0' + inttostr(Tg) +'.' + '0' + inttostr(Mo) + '.' + '%';

  tbname := TbSchueler.TableName;
  qx := TQuery.Create(Application);
  qx.datasource := TbSchueler.DataSource;
  Qx.DatabaseName := listbox11.items[listbox11.itemindex];
  qx.SQL.Text := format('select * from "%s" ' , [tbname]);

  if TbSchueler.Fieldbyname('gebdat').DataType = ftString then
  begin
    showmessage('GebDat ist als TString gespeichert  ' + Tag_Mon);
    qx.Close;
      qx.SQL.Text := format('select Name, Vorname, Klasse, Gebdat, Telefon from "%s" ' +
                            'where gebdat like "%s" ' +
                            'order by Name, Vorname, Klasse', [TbName, Tag_Mon]);
    qx.Open;
  end;


"Halbrichtig" deshalb, weil (an einem bestimmten Tad) drei Personen angezeigt werden müssen, aber nur einer angezwigt wird.

Was ist denn mein Fehler?

Gruß, Detlef


jaenicke - So 29.01.12 10:55

// EDIT: Ok, hatte das MaskEdit nicht korrekt im Kopf...

Dann zu der SQL-Formel:
Wird die korrekt zusammengesetzt? Funktioniert die dann in der Form, wenn du sie unabhängig von deinem Programm ausführst? Das ist ja schließlich der erste Schritt bevor man es in ein Programm einbaut.


D. Annies - So 29.01.12 20:35

Ja, funktioniert, sonst würde IMO ja nicht der eine (richtige) Datensatz ausgegeben werden.
Aber warum nicht alle drei?
Weiß noch jemand Rat?


jaenicke - So 29.01.12 20:46

Lösche am besten einmal alle anderen Datensätze. Wenn es dann reproduzierbar ist, kannst du die Datenbank (ggf. anonymisiert, wenn es echte Daten sind) ja einfach hier anhängen. Denn ohne wird kaum jemand etwas dazu sagen können.

Und da du deinen SQL-Befehl ja offenbar (das schließe ich mal aus deiner Antwort) nicht außerhalb des Programms einfach nur auf der Datenbank ausprobiert hast, weißt du ja nicht einmal woran es denn nun liegt...


Tranx - Mo 30.01.12 04:52

Vielleicht gibst Du Ja den SQLText mal als Text aus, um zu sehen, was da letztendlich steht:



Delphi-Quelltext
1:
2:
  SQLText := qx.SQL.Text;
  showmessage(SQLText);


Dann siehst Du, was wirklich in der SQL-Abfrage steht. Und wie steht es mit der Datenbank? Sind da alle Daten im Feld "GebDat" auch sauber als Datumsstring gespeichert? Da kann es leicht passieren, dass ein Datum in einem Stringfeld falsch gespeichert wird. Besser ist eine Speicherung von Datumsangaben in einem Datetime-Feld.


D. Annies - Mo 30.01.12 05:59

Danke, Gunther,
ja, es ist alles so, wie es sein soll. Es muss wohl an dem Like-Befehl liegen.
Ich probier da mal, etwas zu verändern.
Gruß, Detlef


Xion - Mo 30.01.12 08:16

bzgl LIKE probiers mal mit


Delphi-Quelltext
1:
' where gebdat like''%%s%'' '                    


Es sollte dann im SQL so aussehen: LIKE '%24.12.%'

Vor allem das % (beliebiges Jahr) am Ende ist wichtig, da LIKE sonst keinen Vorteil gegenüber = bringt.


D. Annies - Mo 30.01.12 20:57

Hi, Xion, habe ich so gemacht -
leider keine Änderung.
:(


Tranx - Mo 30.01.12 22:08

Frage: Sind die Daten aller Datensätze im Feld "GebDat" wirklich Datumsangaben? Oder hat sich da ein Fehler eingeschlichen?

Wie ich schon schrieb: Am Besten ist, solche Felder auch mit dem Feldtyp zu belegen, der den Daten entspricht: Datumsfelder : DateTime, Zahlen: Ganzzahl : Integer oder Longint oder Byte, Realzahlen : float, Boolsche Felder : boolean ....

Dann sind Fehleingaben sofort ersichtlich bzw. werden gar nicht erst akzeptiert.

Versuche doch mal folgende SQL-Syntax:


Delphi-Quelltext
1:
2:
3:
  SELECT *
  FROM xxx
  WHERE (((Day([GebDat]))=Tag) AND ((Month([GebDat]))=Monat))


xxx : Deine Tabellenbezeichnung
Tag : Tag des Datums (1..31)
Monat: Monat des Datums (1..12)
GebDat : Feldbezeichnung Des Geburtstagsfeldes.

Der Vorteil liegt auf der Hand: 1. brauchst Du den Format-Konstrukt nicht mehr, weil Du über Tag und Monat direkt auf die SQL-Daten zugreifst. Das Erstellen der SQL-Syntax erfolgt dann wie folgt:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
  
  Tg := strtoint(copy(maskedit1.editText,1,2));                                   // + '%%'; ?
  Mo := strtoint(copy(maskedit1.editText,4,2));

  tbname := TbSchueler.TableName;
  qx := TQuery.Create(Application);
  qx.datasource := TbSchueler.DataSource;
  Qx.DatabaseName := listbox11.items[listbox11.itemindex];
  qx.Close;
  qx.SQL.Text := Format('select * from %s where (Day([gebdat])=%d) and (Month([gebdat])=%d) order by Name, Vorname, Klasse', [TbName, Tg, Mo]);
  qx.Open;


Die Typ-Abfrage des Feldes "GebDat" entfällt. Ich hoffe dass es so funktioniert. Ich habe es an einer Testdatenbank ausprobiert. Und hier sowohl an einen Datetime, als auch an einem String-Feld GebDat. Die Doppelten Anführungszeichen bei %s und %d benötigst Du nicht.


D. Annies - Di 31.01.12 07:28

Hallo, Gunther,

Leider Fehlermeldung: Typ für Feld <...Dateiname...> ist unbekannt.

Detlef


Tranx - Di 31.01.12 09:07

Versuche dann statt des * bei select Deine Felder wieder einzutragen


Delphi-Quelltext
1:
2:
3:
4:
5:
Select Name, Vorname, Klasse, Gebdat, Telefon From ...

statt: 

Select * From ...


Das mag an dem Formatbefehl liegen


D. Annies - Di 31.01.12 09:55

Leider nööö, mit der gleichen Fehlermeldung
arrgh, Detlef


Tranx - Di 31.01.12 10:29

Was steht dann letztendlich in dem SQL.Text? Und was für eine Art Datenbank ist die zugrundeliegende Datenbank? Ich habe es mit einer ACCESS-Datenbank probiert. Da gab es keine Probleme.


jaenicke - Di 31.01.12 10:37

Es wird sich vermutlich weiter um die BDE handeln.

Mit einer geposteten Testdatenbank wäre das ganze ziemlich sicher schon lange erledigt. Und bevor der SQL Befehl nicht unabhängig von dem Projekt auf der Datenbank getestet ist, bringt es auch nichts immer neue Quelltexte auszuprobieren...


D. Annies - Di 31.01.12 18:00

Nun, da werde ich wohl mit den Schwächen der BDE leben müssen, die Daten kann ich leider nicht posten,
da es sich um echte Daten handelt.
LG, Detlef


Tranx - Di 31.01.12 18:02

Die Daten interessieren nicht die Bohne. Es geht nur um die Struktur der Datenbank/Tabelle. Wie ist die aufgebaut? Als Access-Datenbank, MySQL, dBase, Paradox oder was? Welche Felder hast Du und wie definiert. Wie greifst Du auf die Datenbank zu?


D. Annies - Di 31.01.12 18:38

Danke, Gunther, ich habe jetzt aus Frust die Prozedur gelöscht!

Es ist im übrigen so, dass ich die richtigen Daten bekomme, wenn ich nur eine Personen-Tabelle abfrage
und danach die zweite Personentabelle. Nur, wenn (als) ich beide in einer Proc hintereinander abfragte,
passierte dieses "halbrichtige" Ergebnis - und, halt dich fest, auch nicht immer.

Also, noch einmal danke für deine Ideen und Hilfe, aber ich bin mit dieser (eigentlich guten) Idee
durch :))

LG, Detlef


Tranx - Di 31.01.12 19:23

Warum aber hast Du denn zwei Tabellen mit der gleichen Struktur? Ich würde die Daten in einer Tabelle verwalten. Und wenn es z.B. Schul/Büro/private Daten sind - na und? Dann legst Du ein Feld an (Datentyp: Text mit Länge 1) und schreibst da hinein "p" für privat, "b" für Büro, "s" für Schule .... Dann kannst Du die Abfrage in einer Tabelle machen und hast nicht diese Probleme.


D. Annies - Di 31.01.12 19:42

Es ist schon so, dass die beiden Tabellen einen verschiedenen Aufbau haben, und auch verschiedene
Treiber usw.

Lassen wir sie ruhen.

Einen schönen Abend noch,
sagt dir Detlef aus HL