Entwickler-Ecke

Datenbanken - Hilfsvariable bei SQL?


D. Annies - So 26.01.14 04:32
Titel: Hilfsvariable bei SQL?
Hi Delpher,

leider funktioniert die folgende Konstruktion mit einer Hilfsvariablen nicht:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure TBuchMain.qSchuelerSort(Sender: TObject);
begin                                      // IDENT_NR, NAME, VORNAME, KLASSE, GESCHLECHT,
                                           // GEBDAT, TELEFON, EMPFEHLUNG, FSPRACHE1, WPK1NAME
  sortkrit := ' KLASSE, IDENT_NR, NAME, VORNAME ';
  screen.cursor := crhourglass;
  if fileexists(label30.caption + extractfilename(TbSchueler.tablename)) then
  begin
    QSchueler.close;  QSchueler.sql.clear; 
      QSchueler.sql.text := format('select * from "%s" order by sortkrit', [TbSchueler.tablename]);
      QSchueler.prepare;
    QSchueler.open;
    datasource1.dataset := QSchueler;
  end;
  screen.Cursor := crdefault;
end;


Gibt es einen (anderen) Weg?

Gruß, Detlef


Sinspin - So 26.01.14 07:11

Was funktioniert denn nicht? Bzw. was für einen Fehler bekommst du denn? Auf den ersten blick würde ich sagen du ersetzt "sortkrit" im SQL nicht.
Kleiner Tipp, wenn du bei der Zuweisung mit ...SQL.Text arbeitest kannst du dir das SQL.Clear vorher schenken.


haentschman - So 26.01.14 11:13

Moin... 8)

ok, weil heute Sonntag ist:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
procedure TBuchMain.qSchuelerSort(Sender: TObject);
begin                                      // IDENT_NR, NAME, VORNAME, KLASSE, GESCHLECHT,
                                           // GEBDAT, TELEFON, EMPFEHLUNG, FSPRACHE1, WPK1NAME
  SortKrit := ' KLASSE, IDENT_NR, NAME, VORNAME ';
  Screen.Cursor := crHourGlass;
  if FileExists(Label30.Caption + ExtractFilename(TbSchueler.Tablename)) then
  begin
    QSchueler.Sql.Text := Format('select * from %s order by %s', [TbSchueler.Tablename, SortKrit]);
    QSchueler.Open;
    Datasource1.Dataset := QSchueler; //kann man auch im OI zuweisen
  end;
  Screen.Cursor := crDefault;
end;


Anmerkungen:
Kennt deine Codevervollständigung nur kleine Buchstaben?
Was passiert wenn der Tabellenname falsch geschrieben ist?
Warum die Sortierkriterien über Variable wenn die eh fix sind?


D. Annies - So 26.01.14 11:51

Moin Haentschman,

a) Groß- Kleinbuchstaben sind doch optional (?)

b) Kann nicht passieren

c) weil ich diese Kriterien weiterreiche, z.B. an die jeweilige Groupbox_x.caption.

Danke für deine Hilfe,
Gruß, Detlef


haentschman - So 26.01.14 12:00

Zitat:
a) Groß- Kleinbuchstaben sind doch optional (?)

... ja sicher. Ich denke, daß die Lesbarkeit sehr leidet wenn nur Kleinbuchstaben benutzt werden.


D. Annies - Mo 27.01.14 10:08

Hi Haentschman,

leider funzt der Code, den du gepostet hast, doch nicht - D6??

Schade,
Gruß, Detlef


baumina - Mo 27.01.14 10:12

Definiere "funzt nicht".


D. Annies - Mi 29.01.14 18:37

Die Fehlermeldung ist: Ungültiger Feldname ... Column '' is not found.

Gruß, Detlef


WasWeißDennIch - Mi 29.01.14 18:44

Wie sieht denn das resultierende SQL aus?

Delphi-Quelltext
1:
2:
QSchueler.Sql.Text := Format('select * from %s order by %s', [TbSchueler.Tablename, SortKrit]);
ShowMessage(QSchueler.Sql.Text);


D. Annies - Mi 29.01.14 20:45

showmessage liefert:

select * from Schueler.dbf order by " Name, Vorname "

also, die Hochkommata stören wohl ...

Gruß, Detlef


WasWeißDennIch - Mi 29.01.14 20:49

Ich frage mich, wo die herkommen. Mit haentschmans Code sind die jedenfalls nicht zu erklären.


D. Annies - Fr 31.01.14 13:23

Hat keiner noch eine andere Idee?

Der Tabellenname steht übrigens auch in Hochkommata, das ist aber ok.

Gruß, Detlef


WasWeißDennIch - Fr 31.01.14 14:34

Ohne aktuellen Code kann man nur mutmaßen.


D. Annies - Fr 31.01.14 18:25

Der aktuelle Code ist genau der von Haentschman.
Gruß, Detlef


WasWeißDennIch - Fr 31.01.14 18:36

Das kann ich beim besten Willen nicht nachvollziehen. Mein Testcode (einfach nur eine Query und einen Button aufs Formular geklatscht):

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure TfrmTest.ButtonTestClick(Sender: TObject);
var
  SortKrit, Tablename: string;
begin
  Tablename := 'Schueler.dbf';
  SortKrit := ' KLASSE, IDENT_NR, NAME, VORNAME ';
  Query1.Sql.Text := Format('select * from %s order by %s', [Tablename, SortKrit]);
  ShowMessage(Query1.SQL.Text);
end;

Und die Ausgabe:
Zitat:
select * from Schueler.dbf order by KLASSE, IDENT_NR, NAME, VORNAME


D. Annies - Fr 31.01.14 18:37

AHA!!
ich habe ja die %s in Hochkommata!
Jetzt mal sehen ...


D. Annies - Fr 31.01.14 18:43

Sooooo, jetzt geht's:

[Delphi]
Query1.Sql.Text := Format('select * from "%s" order by %s', [Tablename, SortKrit]);
[/Delphi]


WasWeißDennIch - Fr 31.01.14 19:33

Man sollte fremden Code auch so ausprobieren, wie er gepostet wurde ;)


D. Annies - Fr 31.01.14 20:53

Du hast recht, das hatte ich übersehen. - Also, in dieser Sache alles gelöst!
Gruß, Detlef


jackle32 - Fr 31.01.14 21:13

Ich frag mich grad warum so kompliziert. Ich baue meine SQL-Anfragen immer so zusammen:


Delphi-Quelltext
1:
Query1.SQL.Text := 'SELECT * FROM ' + TbSchueler.tablename + ' ORDER BY ' + sortkrit;                    


Oder kennt einer der anwesenden hier darin einen Nachteil?

Gruß,
Jack


haentschman - Sa 01.02.14 09:54

Guten Morgen... 8)
Zitat:
Ich frag mich grad warum so kompliziert. Ich baue meine SQL-Anfragen immer so zusammen:

Auch der von mir gepostete Code ist, sagen wir mal, nicht das gelbe vom Ei. :wink: Eine SQL Anweisung, ob jetzt in deinem Format oder mit der Formatanweisung, ist sicherheitstechnisch bedenklich wenn Daten integriert sind. Stichwort: SQL Injection.
Besser wäre es dann mit Parametern zu arbeiten. Beispiel anhand des obigen Codes: (Syntax kann von Zugriffskomponente zu Zugriffskomponente unterschiedlich sein)

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure TBuchMain.qSchuelerSort(Sender: TObject);
begin                                      // IDENT_NR, NAME, VORNAME, KLASSE, GESCHLECHT,
                                           // GEBDAT, TELEFON, EMPFEHLUNG, FSPRACHE1, WPK1NAME
  SortKrit := ' KLASSE, IDENT_NR, NAME, VORNAME ';
  WhereKrit := 'Ich';
  Screen.Cursor := crHourGlass;
  if FileExists(Label30.Caption + ExtractFilename(TbSchueler.Tablename)) then
  begin
    QSchueler.Sql.Text := Format('select * from %s where Name = :N order by %s', [TbSchueler.Tablename, SortKrit]);
    QSchueler.ParamByName('N').AsString := WhereKrit;
    QSchueler.Open;
    Datasource1.Dataset := QSchueler; //kann man auch im OI zuweisen
  end;
  Screen.Cursor := crDefault;
end;


vagtler - Sa 01.02.14 12:59

Und auch das wäre nur die halbe Miete, wenn der Benutzer irgendwie die Sortierkriterien manuell beeinflussen könnte.

http://xkcd.com/327/


haentschman - Sa 01.02.14 13:28

Zitat:
Und auch das wäre nur die halbe Miete

...wer seinen Benutzern den direkten Zugriff auf den SQL String, und wenn es nur über einen Sortierstring ist, gibt ist selbst schuld. :roll: