Entwickler-Ecke

Datenbanken - Query Abfrage


Arne Danikowski - Fr 29.08.08 17:09
Titel: Query Abfrage
Hallo, ich versuche mich grade an Queryabfragen.
Kann mir einer sagen warum forgende Abfrage zu einer Fehlermeldung führt:


Delphi-Quelltext
1:
2:
Lagerdata.ADOEingangQuery.SQL.Text:=('Select * From Eingang Where Eingangsnummer=' +dbedit45.text);
Lagerdata.ADOEingangQuery.Open;


mkinzler - Fr 29.08.08 17:27

Was für ein Fehler?

Delphi-Quelltext
1:
Lagerdata.ADOEingangQuery.SQL.Text:='Select * From Eingang Where Eingangsnummer=' +dbedit45.text;                    


Delete - Fr 29.08.08 17:33

kann man so, ohne kristallkugel nicht sagen...

da braucht man (a) mehr code und (b) die tabellendeklaration und (c) die fehlermeldung...


alzaimar - Fr 29.08.08 20:04

Lustig, ein Quiz. Au Fein. :dunce: Hier die möglichen Antworten
A - Es gibt gar keine Datenbank
B - Delphi ist nicht installiert
C - dbedit45.text enthält nichtnumerische Zeichen
D - Die Welt ist eine Scheibe

So, den Telefonjoker hast du noch, 50:50 auch. Und?


mkinzler - Fr 29.08.08 20:06

Das Publikum hat er ja hiermit schon gefragt :mrgreen:


BenBE - Fr 29.08.08 20:18

Lösungsmöglichkeiten:
A) Use Infinite Inprobability Drive
B) Use Prepared Statements
C) Use Proper Escaping
D) Use Brain 1.0


Arne Danikowski - Mo 01.09.08 10:13

Hatte nicht gedacht dass das Quizz so schwer ist.

- Ich habe eine Access Datenbank (jep die Datenbank ist vorhanden) mit einer Tabelle (eigentlich sogar mehrere) huchu
- Ich arbeite mit Delphi 2007 (ist sogar installiert)
- enthält keine nichtnummerischen Zeichen (geht nicht das Feld ist ein AutoFeld Nummersich per Zufall)
- definitiv keine Scheibe nur bei Terry Pratchett

ich habe aber immer wieder ähnliche Probleme hier noch ein Beispiel. Ich möchte eine Tabelle nach dem Inhalt in einem edit Text Feld durchsuchen.
Die Ergebnisse sollen in enem Grid angezeigt werden.



Delphi-Quelltext
1:
2:
lagerdata.ADOArtikelQuery.SQL.Text:=('select * from artikel where Seriennummer=  '+seriensuchedit.text);
lagerdata.ADOArtikelQuery.open;


Die Tabelle in der Datenbank heißt = artikel
die zu filternde Spalte = Seriennummer

ich möchte nur Dtaensätze anzeigen, die mit dem Inhalt in seriensuchedit.text übereinstimmen.

und hier die Fehlermeldung : Fehlender Operator in Abfrageausdruck 'Seriennummer=" aufgetreten.


baka0815 - Mo 01.09.08 10:32

Klingt als sei "seriensuchedit.text" ein Leerstring, also ''
Damit sieht das SQL wie folgt aus: select * from artikel where Seriennummer= und da fehlt dann halt einfach was.

Ich würde aber Punkt B von user profile iconBenBE beherzigen und Prepared Statements [http://de.wikipedia.org/wiki/Prepared_Statement] verwenden.

Dann sieht das SQL z.B. so aus: select * from artikel where Seriennummer=:SerienNr.
Über lagerdata.ADOArtikelQuery.SQL.ParamByName('SerienNr').AsInteger := 4711 kannst du dem ganzen dann den Wert zuweisen.


alzaimar - Mo 01.09.08 10:33

Hui, dann wirds lustig.

Gib die Query mal in eine Textdatei aus


Delphi-Quelltext
1:
2:
3:
4:
// Die Klammern braucht's nicht
lagerdata.ADOArtikelQuery.SQL.Text:='select * from artikel where Seriennummer=  '+seriensuchedit.text;
lagerdata.ADOArtikelQuery.SQL.SaveToFile('c:\Foobar.txt');
lagerdata.ADOArtikelQuery.open;

Öffne die Textdatei, per Copy & Paste in Access reinschnipseln und dann schauen.

Wenn das nicht hilft:
DB leeren, packen und hier reinstellen. Kriegen wir schon hin. Auch wenn es nix mit Multiple-Choice und der Millionenfrage wird.

Ach, und die Sache mit den 'prepared Statements' ist auf jeden Fall besser, als eine per Hand zusammengebastelte Query.


Arne Danikowski - Mo 01.09.08 10:45

Ich hab das nochmal ausprobiert in der Textdatei steht dann zum Beispiel:

select * from artikel where Seriennummer= 1

In Access und auch in Delphi bekomme ich folgende Fehlermeldung:

"Datentypen in Kreterienausdruck unverträglich"


Robert.Wachtel - Mo 01.09.08 10:57

Nun, ich würde sagen, es scheint so als wären die Datentypen im Kriterienausdruck unverträglich. :mrgreen: Wie lautet das DDL-Statement der Spalte "Seriennummer"?


alzaimar - Mo 01.09.08 10:58

Gut, und nun noch die gepackte Access-DB (kann auch leer sein) als ZIP. Alternativ Access öffnen, in der Tabellenbeareitung das Feld 'Seriennummer' auswählen und das als Screenshot hier einhängen.

Das Feld 'Seriennummer' ist vermutlich nicht numerisch.


Arne Danikowski - Mo 01.09.08 11:04

Das mit den prepared Statements gestaltet sich schwierig, da mein ADOQuery kein Opjekt von ParamByName kennt.


alzaimar - Mo 01.09.08 11:08

user profile iconArne Danikowski hat folgendes geschrieben:
Das mit den prepared Statements gestaltet sich schwierig, da mein ADOQuery kein Opjekt von ParamByName kennt.

Stimmt, die Eigenschaft heißt auch:

Delphi-Quelltext
1:
MyQuery.Parameters.ParamByName['SerienNr']                    


Arne Danikowski - Mo 01.09.08 11:40

hier die beiden Dateien:

Screenshot: http://www.rsystems.de/download/screenshot.jpg

Screenshot: http://www.rsystems.de/download/datenbank.mdb


alzaimar - Mo 01.09.08 11:49

Das Feld 'Seriennummer' ist ein Text und daher musst Du auch mit einem Text vergleichen. Nimm die parametrierten Queries, dann passieren solche Geschichten nicht. ADO wird die Query dann automatisch korrekt formatieren.


Arne Danikowski - Mo 01.09.08 12:35

Erst einmal vielen Dank für Deine Gedult mit mir.

Ich bastle grade so an den paramentierten SQL Abfragen rum da geschieht es plötzlich: Fehler !! :D

Komm mir schon blöd vor aber ich hab noch den

Publikumsjoker.



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
Var suche:String;
suche:seriensuchedit.text
..
..
 lagerdata.ADOEingangQuery.SQL.Text:=
      'SELECT Seriennummer FROM Eingang WHERE Seriennummer = :seriennr';



so weit so gut aber bei.


Delphi-Quelltext
1:
lagerdata.ADOEingangQuery.Parameters.ParamByName('seriennr').AsString:=suche;                    


gibt es in meinem Query kein Objekt für AsString erkennt der nicht.
Soweit ich das verstanden habe muss man doch dem ParamByName einen Datatype zuweisen oder nicht?

Wenn ich statt ASString Value einsetzte (das Kennt er zumindestens) dann bekomme ich kein Fehlermeldung:
Aber es funktioniert auch nicht ich bekomme keine Daten.


alzaimar - Mo 01.09.08 12:38


Delphi-Quelltext
1:
lagerdata.ADOWareneingangQuery.Parameters.ParamByName('seriennr').DataType := ftString;                    


Arne Danikowski - Mo 01.09.08 12:40

ftString = undefinierter Bezeichner


alzaimar - Mo 01.09.08 12:46

F1 = Delphi Hilfe. Und dann die Unit einbinden, in der dieser Wert definiert wurde (DB.PAS, denke ich).


Arne Danikowski - Mo 01.09.08 13:21

ich befüchte mal, damit komm ich nicht zurecht aber trotztem vielen dank für deine Bemühungen.
jetzt geht zwar das ftString aber ein ASString hab ich immer noch ich


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
uses lager_data, lager_eingang, db;

lagerdata.ADOEingangQuery.SQL.Clear;
    lagerdata.ADOEingangQuery.SQL.Text:= 'SELECT Seriennummer FROM Eingang WHERE Seriennummer = :seriennr';
    lagerdata.ADOWareneingangQuery.Parameters.ParamByName('seriennr').DataType := ftString;
    lagerdata.ADOEingangQuery.Parameters.ParamByName('seriennr').??? (geht nicht)ASString
    lagerdata.ADOEingangQuery.open;


Robert.Wachtel - Mo 01.09.08 13:41

Du könntest ja auch mal in die Hilfe schauen und nachsehen, welche Methoden/Eigenschaften ParamByName hat. Vielleicht gibt es ja eine Eigenschaft namens Value?


Arne Danikowski - Mo 01.09.08 15:01

Das hat irgenwie nicht hingehauen aber ich konnte das Proplem so lösen:


Delphi-Quelltext
1:
2:
3:
4:
5:
Lagerdata.ADOEingangQuery.close;
  Lagerdata.ADOEingangQuery.SQL.clear;
  Lagerdata.ADOEingangTable.IndexFieldNames:='Seriennummer';
  lagerdata.ADOEingangQuery.SQL.Text := 'Select * From Eingang WHERE (Seriennummer LIKE ' + QuotedStr(sucheseriennr + '%') + ')';
  Lagerdata.ADOEingangQuery.Open;


alzaimar - Mo 01.09.08 15:09


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
lagerdata.ADOEingangQuery.SQL.Text:= 'SELECT Seriennummer FROM Eingang WHERE Seriennummer = :seriennr';
//lagerdata.ADOWareneingangQuery.Parameters.ParamByName('seriennr').DataType := ftString;
//          xxxxxxxxxxxxxxxxxxxx  BLÖDSINN wir arbeiten ja mit "ADOEingangQuery"
lagerdata.ADOEingangQuery.Parameters.ParamByName('seriennr').DataType := ftString;
lagerdata.ADOEingangQuery.Parameters.ParamByName('seriennr').Value := MyEdit.Text;
lagerdata.ADOEingangQuery.open;

Sollte funktionieren.


Arne Danikowski - Mo 01.09.08 15:52

tut es auch
vielen Dank !! :)


saxe66 - Do 11.09.08 13:02
Titel: QuotedStr ist die schnellste Lösung
Sofern du in Textfeldern sucht, ist, so denke ich jedenfalls, die QuotedStr-Anweisung am effektivsten.

Also etwa so ...

var suche: string;

suche:=Edit1.Text;

Query.SQL.Add('select * from datenbank where seriennummer='+QuotedStr(suche));

Mehr ist hier nicht notwendig.


alzaimar - Do 11.09.08 13:10

saxe66, das ist keine gute Idee, denn es kann sein, das das DBMS diese einfachen Hochkommata nicht akzeptiert.

Es ist wirklich besser, mit parametrisierten Queries zu arbeiten, weil nur hier sicher ist, das die Formatierung des SQL-Befehls korrekt ist.