Entwickler-Ecke

Datenbanken - SQL-Fehler?


D. Annies - Sa 19.01.13 10:28
Titel: SQL-Fehler?
Hi, Delpher,

Der folgende Befehl ist falsch:


Delphi-Quelltext
1:
2:
3:
4:
SQL.Text := format('select distinct WPK1NAME as WPU from "%s" ', [TbSchueler.tablename]) +
                         'union ' +
                  format('select WPK2NAME as WPU from "%s" ', [TbSchueler.tablename]) +
                  format('where WPK1NAME[1] = '' '' or WPK2NAME[1] = '' '' ');              // hier Fehler


Wo liegt der Fehler?
Danke, Detlef


Tilo - Sa 19.01.13 11:39

Hallo Detlef

Tippe mal darauf, das in der mit "hier Fehler" markierten Zeile die Aphostrophe (') zuviel sind und die Zeichenkette vorzeitig geschlossen wird.
Mögliche Lösungen: Stringbegrenzer escapen oder den zu übergebenen String vorher zusammenbauen und in einer Variablen speichern.

Bitte schreib doch mal was für ein Fehler auftritt. Meckert zu Beispiel schon der Compiler oder bekommst Du falsche Ergebnisse?
(Funktionierende Glaskugel sind leider Mangelware)

Schönes Wochenende,
Tilo


D. Annies - Sa 19.01.13 11:43

Danke, Tilo,

nun, der Compiler meckert:
[Fehler] buch.pas(3706): Nicht genügend wirkliche Parameter

Gruß, Detlef


Mathematiker - Sa 19.01.13 11:46

Hallo,
der format-Befehl benötigt ein Array der einzufügenden Variablen/Argumente:

Delphi-Quelltext
1:
function Format(const Format: stringconst Args: array of const): string;                    
Dein letzter format-Befehl besteht nur aus dem Formatierungssstring, d.h. entweder "format(" weglassen oder das Array ergänzen, z.B.

Delphi-Quelltext
1:
2:
3:
4:
SQL.Text := format('select distinct WPK1NAME as WPU from "%s" ', [TbSchueler.tablename]) +
                         'union ' +
                  format('select WPK2NAME as WPU from "%s" ', [TbSchueler.tablename]) +
                  format('where WPK1NAME[1] = '' '' or WPK2NAME[1] = '' '' ',[]);

Beste Grüße
Mathematiker


D. Annies - Sa 19.01.13 11:59

ich habe jetzt:


Delphi-Quelltext
1:
2:
3:
4:
SQL.Text := format('select distinct WPK1NAME as WPU from "%s" ', [TbSchueler.tablename]) +
                         'union ' +
                  format('select WPK2NAME as WPU from "%s" ', [TbSchueler.tablename]) +
                         'where WPK1NAME[1] = ' ' or WPK2NAME[1] = ' ' ');


mit der Fehlermeldung:

[Fehler] buch.pas(3706): Operator oder Semikolon fehlt


Mathematiker - Sa 19.01.13 12:26

Hallo,
die doppelten ' waren schon richtig. Außerdem ist jetzt eine Klammer zuviel, d.h.

Delphi-Quelltext
1:
2:
3:
4:
SQL.Text := format('select distinct WPK1NAME as WPU from "%s" ', [TbSchueler.tablename]) +
                         'union ' +
                  format('select WPK2NAME as WPU from "%s" ', [TbSchueler.tablename]) +
                         'where WPK1NAME[1] = '' '' or WPK2NAME[1] = '' '' ';


Beste Grüße
Mathematiker


D. Annies - Sa 19.01.13 12:34

Danke, aber leider ist die (gleiche) Fehlermeldung noch da :(
LG, Detlef


Mathematiker - Sa 19.01.13 12:48

Hallo,
user profile iconD. Annies hat folgendes geschrieben Zum zitierten Posting springen:
... aber leider ist die (gleiche) Fehlermeldung noch da :(

Gib bitte einmal die ganze Prozedur mit der fehlerhaften Zeile an. Irgendwo muss ja der Fehler stecken.

Beste Grüße
Mathematiker


D. Annies - Sa 19.01.13 13:45

Look at that:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
procedure TBuchMain.WPUListeerzeugen1Click(Sender: TObject);
begin
  with QSchueler2 do
  begin                                                        
    Close; SQL.Clear;
      SQL.Text := format('select distinct WPK1NAME as WPU from "%s" ', [TbSchueler.tablename]) +
                         'union ' +
                  format('select WPK2NAME as WPU from "%s" ', [TbSchueler.tablename]) +
                         'where WPK1NAME[1] = ' ' or WPK2NAME[1] = ' ' ';
    Open;
  end;
  fname := concat(label30.caption, 'OUTXLS\' + 'WPU_Liste.xls');
  TeilMengenausgabeSG(QSchueler2);
end;


LG, Detlef


Mathematiker - Sa 19.01.13 15:37

Hallo,
bei mir wird Folgendes, wie oben schon erwähnt, korrekt übersetzt:

Delphi-Quelltext
1:
2:
3:
4:
      SQL.Text := format('select distinct WPK1NAME as WPU from "%s" ', [TbSchueler.tablename]) +
                         'union ' +
                  format('select WPK2NAME as WPU from "%s" ', [TbSchueler.tablename]) +
                         'where WPK1NAME[1] = '' '' or WPK2NAME[1] = '' '' ';

Mehr kann ich Dir nicht sagen.

Beste Grüße
Mathematiker


D. Annies - Sa 19.01.13 16:59

Jo, jetzt geht es mir auch!!

War wohl iwi unaufmerksam

Danke


WasWeißDennIch - Sa 19.01.13 17:51

Mit SQL-Parametern wäre das nicht passiert ;)

Delphi-Quelltext
1:
2:
3:
Query.SQL.Add('where WPK1NAME[1] = :param1 or WPK2NAME[1] = :param2');
Query.ParamByName('param1').Value := ' ';
Query.ParamByName('param2').Value := ' ';


Tranx - Sa 19.01.13 18:02

um z.B. Strings in SQL-Abfragen einzubinden, bietet sich die Funktion

QuotedStr oder in Multibyte-Zeichensätzen AnsiQoutedStr an. Dann wird das mit den '' nicht mehr so unübersichtlich.

Diese beiden Funktionen fügen am Anfang und Ende das Zeichen ' automatisch ein.

Nur zur Info.

Du kannst auch leere Strings damit übergeben:

Delphi-Quelltext
1:
..  + Quotedstr('') + ....                    


WasWeißDennIch - Sa 19.01.13 18:08

Das ist aber nur die 2. Wahl, falls aus irgendwelchen Gründen parametrisierte Queries nicht in Frage kommen. Aber immer noch besser, als Strings ungeprüft zu übernehmen (Stichwort SQL-Injection).


Gerd Kayser - Sa 19.01.13 20:29

user profile iconWasWeißDennIch hat folgendes geschrieben Zum zitierten Posting springen:


Delphi-Quelltext
1:
2:
3:
Query.SQL.Add('where WPK1NAME[1] = :param1 or WPK2NAME[1] = :param2');
Query.ParamByName('param1').Value := ' ';
Query.ParamByName('param2').Value := ' ';


Ich würde es so schreiben:

Delphi-Quelltext
1:
2:
3:
Query.SQL.Add('where WPK1NAME like :param1 or WPK2NAME like :param2');
Query.ParamByName('param1').Value := ' %';
Query.ParamByName('param2').Value := ' %';


WasWeißDennIch - Sa 19.01.13 21:24

Es ging mir weniger um die Abfrage an sich, sondern um die Verwendung von Parametern.